多态为 java 的三大特征之一 (封装、继承、多态),一直以来不太理解,只是知道父类引用指向子类对象就是多态,但具体细节不清楚,今天在压测空闲前夕,特重学之。
public class SubClass extends BaseClass {
//重新定义一个book实例属性覆盖父类的book实例属性
public String book = "轻量级J2EE企业应用实战";
@Override
public void test() {
System.out.println("子类的覆盖父类的方法");
}
public void sub() {
System.out.println("子类的普通方法");
}
public static void main(String[] args) {
BaseClass bc = new SubClass();
System.out.println(bc.book); //输出:6 (访问的是父类属性)
bc.base(); //输出:父类的普通方法 (访问的是父类方法)
bc.test(); //输出:子类的覆盖父类的方法 (访问的是子类方法)
//编译出错,bc的编译类型是BaseClass类,BaseClass类没有提供sub()方法
bc.sub();
}
}
class BaseClass {
public int book = 6;
public void base() {
System.out.println("父类的普通方法");
}
public void test() {
System.out.println("父类的被覆盖的方法");
}
}
说明:因为 java 是解释性语言,所以运行有两个过程,编译和运行。
变量 bc 比较特殊,编译时类型是 BaseClass,运行时类型是 SubClass,当调用该引用变量的 test 方法 (BaseClass 类中定义了该方法,子类 SubClass 覆盖了父类的该方法),实际执行时,运行的是 SubClass 类中覆盖后的 test 方法,这就是多态。
注意⚠️:与方法不同的是,对象的属性则不具备多态性:如上面的 bc 引用变量, 程序中输出它的 book 属性,并不是输出 SubClass 类里定义的实例属性,而是输出 BaseClass 属性里的实例属性。