1、关于构造函数:子类需要继承父类的构造函数。
1)如果父类无构造函数或有无参构造函数,则调用子类构造函数前会自动调用父类的无参构造函数。
2)如果父类只有有参数的构造函数,则子类必须显式调用父类的构造函数,否则编译出错。
3)如果父类同时具有有参和无参的构造函数,则调用子类构造函数前会自动调用父类的无参构造函数。
2、成员变量覆盖:子类不能覆盖父类的成员变量,但可以隐藏父类的成员变量。
1)子类“覆盖”父类的成员变量时,父类的方法使用的永远是父类的成员变量,子类的方法使用的永远是子类的成员变量(除非显示使用super关键字来引用父类的成员变量)。
3、方法覆盖:实例方法被覆盖,静态方法被隐藏。
1)子类能覆盖父类的实例方法,不能覆盖静态或终态方法。
2)试图用子类的静态方法隐藏父类中同样标识的实例方法是不合法的,编译器将会报错。
3)试图用子类的实例方法覆盖父类中同样标识的静态方法也是不合法的,编译器会报错。
4)抽象方法必须在具体类中被覆盖。
4、实例
class SuperClass {
private int number;
public SuperClass() {
this.number = 0;
}
public SuperClass(int number) {
this.number = number;
}
public int getNumber() {
number++;
return number;
}
}
class SubClass1 extends SuperClass {
public SubClass1(int number) {
super(number);
}
}
class SubClass2 extends SuperClass {
private int number;
public SubClass2(int number) {
super(number);
}
}
public class SubClass extends SuperClass {
private int number;
public SubClass(int number) {
super(number);
}
public int getNumber() {
number++;
return number;
}
public static void main(String[] args) {
SuperClass s = new SubClass(20);
SuperClass s1 = new SubClass1(20);
SuperClass s2 = new SubClass2(20);
System.out.println(s.getNumber());
System.out.println(s1.getNumber());
System.out.println(s2.getNumber());
//结论一:多态时,当子类覆盖了父类的方法,使用子类覆盖的方法
//结论二:当子类覆盖父类的成员变量时,父类方法使用的是父类的成员变量,子类方法使用的是子类的成员变量
}
}
执行输出:
1
21
21