19.10.13

//1.构造方法
在想直接通过在创建实例的时候赋予字段属性,
那么就必须使用构造方法了,有无参构造方法和有参构造方法
平时,如果我们没有写构造方法,编译器系统会默认为我们添加无参构造方法
也可以同时,写无参构造方法和有参构造方法
方法名与类名相同并且是大写开头的(注意)
没有返回值(即没有void)

Java中先创建实例时:
<1>首先初始化实例
<2>然后执行构造方法的代码进行初始化

多个构造方法在:
可以在类里面编写多个构造方法
会自己帮我们匹配使用哪个构造方法
一个构造方法可以调用其他构造方法,这样做的目的是便于代码复用。
调用其他构造方法的语法是this(…):
class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person(String name) {
        this(name, 18); // 调用另一个构造方法Person(String, int)
    }

    public Person() {
        this("Unnamed"); // 调用另一个构造方法Person(String)
    }
}

//2.关于class类????
是不是一个.java文件里面只有一个public类,并且文件名要与这个类名相同
但是,可以有多其他的类,只要类名不是带有public即可,这点似乎可以证实的

//3.方法重载(overload)
是指同一个类里面的可以有多个名字相同的方法
方法重载的返回值类型通常都是相同的
应该具有类似的功能

//4.继承extends
通过继承只需要编写额外的代码
在OOP的术语中,我们把Person称为
超类(super class),父类(parent class),基类(base class),
把Student称为子类(subclass),扩展类(extended class)。

Java中只允许一个class类继承一个父类(即有且只有一个父类)
只有Object特殊,它没有父类。

继承有个特点就是子类无法访问父类的私有属性和私有方法
如果子类想法访问父类的私有属性,可以将private改成protected
即只可以在继承树类进行访问

**super关键字:**重点记忆理解
用来访问父类的字段
特别是在构造方法的时候
这是因为在Java中,任何class的构造方法,
第一行语句必须是调用父类的构造方法。
如果没有明确地调用父类的构造方法,编译器会帮我们自动加一句super();
如果父类没有默认的构造方法,子类就必须显式调用super()
并给出参数以便让编译器定位到父类的一个合适的构造方法。
这里还顺带引出了另一个问题:
即子类不会继承任何父类的构造方法。
子类默认的构造方法是编译器自动生成的,不是继承的。

向上转型
这种把一个子类类型安全地变为父类类型的赋值,被称为向上转型(upcasting)。
Person p = new Student()
一个疑问??就是Student的新属性,p还可以使用吗??
可以,这些方法都是新添加上去的

向下转型
和向上转型相反,如果把一个父类类型强制转型为子类类型,就是向下转型(downcasting)。
如果转化类型不同,也就是所谓的不兼容,就会报错ClassCastException
但是Java提供instanceof 用于判断类型
instanceof实际上判断一个变量所指向的实例是否是指定类型,
或者这个类型的子类。如果一个引用变量为null,
那么对任何instanceof的判断都为false。
利用instanceof,在向下转型前可以先判断:
Person p = new Student();
if (p instanceof Student) {
    // 只有判断成功才会向下转型:
    Student s = (Student) p; // 一定会成功
}

区分继承和组合的关系
具有has关系不应该使用继承,而是使用组合,即Student可以持有一个Book实例:
class Student extends Person {
    protected Book book;
    protected int score;
}
继承是is关系,has是组合关系

//5.多态
在继承关系中,如果子类定义一个与父类**完全相同**的方法名的方法,
那么就叫覆写override
方法名相同,方法参数相同,但方法返回值不同,也是不同的方法。
在Java程序中,出现这种情况,编译器会报错。

Java的实例方法调用是基于运行时的实际类型的动态调用,而非变量的声明类型。
这个非常重要的特性在面向对象编程中称之为多态。
它的英文拼写非常复杂:Polymorphic。

多态的特性就是,运行期才能动态决定调用的子类方法。
多态具有一个非常强大的功能,就是允许添加更多类型的子类实现功能扩展,
却不需要修改基于父类的代码。

覆写Object方法
因为所有的class最终都继承自Object,而Object定义了几个重要的方法:
toString():把instance输出为String;
equals():判断两个instance是否逻辑相等;
hashCode():计算一个instance的哈希值。

调用super
在子类的覆写方法中,如果要调用父类的被覆写的方法,可以通过super来调用。

final
继承可以允许子类覆写父类的方法。如果一个父类不允许子类对它的某个方法进行覆写,
可以把该方法标记为final。用final修饰的方法不能被Override
class Person {
    protected String name;
    public final String hello() {
        return "Hello, " + name;
    }
}

class Student extends Person {
    // compile error: 不允许覆写
    @Override
    public String hello() {
    }
}
同样,类也是可以使用这个关键词修饰,修饰之后不可以被继承
字段被修饰并初始化后,不可以被修改。

//6.抽象方法、类
通过abstract定义的方法是抽象方法,它只有定义,没有实现。
抽象方法定义了子类必须实现的接口规范;
定义了抽象方法的class必须被定义为抽象类,从抽象类继承的子类必须实现抽象方法;
如果不实现抽象方法,则该子类仍是一个抽象类;
面向抽象编程使得调用者只关心抽象方法的定义,不关心子类的具体实现。

//7.接口
如果一个抽象类里面全是抽象方法,没有字段即属性
那么就可以把抽象类改为接口即abstract改为interface
abstract class Person {
    public abstract void run();
    public abstract String getName();
}
改为
interface Person {
    void run();
    String getName();
}
一个类可以继承多个interface接口,使用implements关键词继承
因为接口定义的所有方法默认都是public abstract的,
所以这两个修饰符不需要写出来(写不写效果都一样)


接口继承
一个interface可以继承自另一个interface。
interface继承自interface使用extends,它相当于扩展了接口的方法。
这个里面就不需要覆写父接口的方法,因为是平级关系,就和普通的继承一样

default方法(JDK>=1.8)
就是在接口的方法前面加上default关键字
实现类可以不必覆写default方法,就是方便接口添加新方法的时候,子类不用修改覆写
default方法和抽象类的普通方法是有所不同的。因为interface没有字段,
default方法无法访问字段,而抽象类的普通方法可以访问实例字段。

//8.静态字段和静态方法
一般通过类名直接访问
静态字段属于所有实例“共享”的字段,实际上是属于class的字段;
调用静态方法不需要实例,无法访问this,但可以访问静态字段和其他静态方法;
静态方法常用于工具类和辅助方法。

接口的静态字段
因为interface是一个纯抽象类,所以它不能定义实例字段。
但是,interface是可以有静态字段的,并且静态字段必须为final类型:
实际上,因为interface的字段只能是public static final类型,
所以我们可以把这些修饰符都去掉,
编译器会自动把该字段变为public static final类型。
posted @ 2019-10-30 20:55  睿晞  阅读(102)  评论(0编辑  收藏  举报