- 在调用子类的构造方法之前,若无super语句,java会自动调用父类的无参构造方法。
- final关键字修饰基本类型时,该基本类型只能被赋值一次;修饰对象引用时,一旦该引用初始化指向某个对象,就不能再指向第二个对象,即引用中保存的内存地址不能再变化,但是该引用所指向对象的内容是可以变化的。
public class Test09 {
final int[] array = {1, 2, 3};
public void doSome() {
// array = new int[20]; // Cannot assign a value to final variable 'array'
array[0] = 10; // 可以修改数组内容。
}
}
- 常量的定义:
public static final int VALUE = 10;
public表示可以用于包之外,static表示只有一份,final表示它为一个常量。
- 若使用了final修饰成员变量,则必须在成员变量的定义处或者每个构造方法中对其进行赋值。
class Father {
// 空白final(定义处未初始化)
private final int i;
// 则每一个构造器都要对空白final进行初始化。
// 无参
public Father() {
i = 1;
}
// 有参
public Father(int i) {
this.i = i;
}
}
- 使用final修饰的方法不会被覆盖。
- 若使用private修饰方法,则不存在被覆盖问题,该方法不会被子类继承。
- 子类加载时,所以父类都会被加载,所有类的static都会被初始化,初始化顺序为:父类→子类。
- new子类对象,java会自动初始化所有父类的所有成员数据,并且调用它们的无参构造方法。初始化与执行构造方法之间的先后顺序为:无论是在子类还是父类中,都是首先调用父类构造方法,然后初始化成员数据,最后再执行自己的构造方法。
public class Test09 {
public static void main(String[] args) {
// CC cc = new CC();
/* 输出结果:
AA构造方法执行!
BB构造方法执行!
CC构造方法执行!
*/
DD dd = new DD();
/* 输出结果:
AA构造方法执行!
BB构造方法执行!
CC构造方法执行!
BB构造方法执行!
DD构造方法执行!
*/
}
}
class AA {
public AA() {
System.out.println("AA构造方法执行!");
}
}
class BB {
public BB() {
System.out.println("BB构造方法执行!");
}
}
class CC extends AA {
private BB bb = new BB();
public CC() {
System.out.println("CC构造方法执行!");
}
}
class DD extends CC {
private BB bb = new BB();
public DD() {
System.out.println("DD构造方法执行!");
}
public static void main(String[] args) {
}
}
- 关于方法覆盖:
class SuperClass {
public SuperClass() {
}
// 方法若用final修饰,则不会被子类覆盖。
public String method1(String s1) {
return s1;
}
public SuperClass method2(String s1, String s2) {
return new SuperClass();
}
}
class SubClass extends SuperClass {
public SubClass() {
}
// 不会覆盖父类的method1
public float method1(float f1) {
return f1;
}
// 与父类方法的方法名和参数列表相同但返回值类型不同,
// 以下代码会报错:use incompatible return type
// 此时没有发生方法覆盖,只是创建了一个新方法,但是编译器不能根据返回值来区分该方法与父类method1方法,所以编译错误。
/*public float method1(String s1) {
return 1.0f;
}*/
// 不会覆盖父类的method1
public String method1(String s1, String s2) {
return s1 + s2;
}
// 只有方法名、返回值类型(允许返回值类型为父类方法返回值类型的子类)和参数列表和父类方法完全相同,父类方法才会被覆盖,否则就只是创建了一个新方法。
// 因此,需要覆盖父类方法时,将其整个方法复制过来再修改方法体内部的内容,同时使用@Override注解,可以保证覆盖的正确性。
@Override
public String method1(String s1) {
return "覆盖";
}
// 子类方法不能比被覆盖的父类方法的权限等级低。比如父类方法时public,子类方法就不能是private、protected和默认。
/*private String method1(String s1) {
return "覆盖";
}*/
// 子类方法的返回值类型是父类方法返回值类型的子类也是允许的,因为SubClass也是SuperClass。
@Override
public SubClass method2(String s1, String s2) {
return new SubClass();
}
}