Java引用变量有两个类型:编译时类型,运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致时,就可能出现所谓的多态(Polymorphism)。
class BaseClass{
public int book=6;
public void base(){
System.out.println("父类的普通方法");
}
public void test(){
System.out.println("父类的被覆盖 的 方法");
}
}
public class SubClass extends BaseClass{
private String book="轻量级 Java EE 企业应用实战";
public void test(){
System.out.println("子类的覆盖父类的方法");
}
public void sub(){
System.out.println("子类的普通方法");
}
当编译时和运行时类型完全相同,调用他们的成员变量和方法非常正常。
//编译时类型和运行时类型 完全一致 一样 因此不会出现多态
BaseClass bc=new BaseClass();
//编译时类型与运行时类型完全一致 不会出现多态
SubClass sc =new SubClass();
当编译时与运行时类型不一致时就可能出现多态,
//编译时类型 与 运行时类型 不一致 将会可能出现 多态
BaseClass ploymophicBc=new SubClass();
子类其实是一种特殊的父类,java允许把一个子类对象直接赋给一个父类引用变量,无需任何类型转换,系统会自动向上转型。
ploymophicBc引用变量的编译时类型为BaseClass,而运行时类型为SubClass,当运行时调用该引用变量的方法时,其方法总是表现为子类方法的行为特征。
相同类型的变量,调用同一个方法时呈现出多种不同的行为特征,这就是多态。
对象的实例变量不会出现多态 引用变量访问其包含的实例变量时,系统总是试图访问编译时类型所定义的成员变量
引用变量在编译阶段只能调用其编译时类型所具备的方法
public static void main(String[] args){
//编译时类型和运行时类型 完全一致 一样 因此不会出现多态
BaseClass bc=new BaseClass();
System.out.println(bc.book);
bc.base();
bc.test();
System.out.println("---------------------------------------");
//编译时类型与运行时类型完全一致 不会出现多态
SubClass sc =new SubClass();
System.out.println(sc.book);
sc.base();//继承父类的方法
sc.test();//覆盖父类的方法
sc.sub();//自己的方法
System.out.println("---------------------------------------");
//编译时类型 与 运行时类型 不一致 将会可能出现 多态
BaseClass ploymophicBc=new SubClass();
System.out.println(ploymophicBc.book); //对象的实例变量不会出现多态 引用变量访问其包含的实例变量时,系统总是试图访问编译时类型所定义的成员变量
ploymophicBc.test();//运行时 是SubClass 调用子类的test方法
ploymophicBc.base();//父类方法
//ploymophicBc.sub()// 引用变量在编译阶段只能调用其编译时类型所具备的方法,BaseClass 没有sub方法所以不能调用
}
参考疯狂java