多态
Java引用变量有两个类型:一个是编译时类型,一个是运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就可能出现多态
相同类型的变量、调用同一个方法时呈现出多种不同的行为特征,这就是多态
class BaseClass{
public int book = 6;
public void base(){
System.out.println("父类的普通方法");
}
public void test(){
System.out.println("父类的被覆盖的方法");
}
}
public class SubClass extends BaseClass{
//重新定义一个book实例变量隐藏父类的book实例变量
public String book = "123";
public void test(){
System.out.println("子类的覆盖父类的方法");
}
public void sub(){
System.out.println("子类的普通方法");
}
public static void main(String[] args){
//下面编译时类型和运行时类型完全一样,因此不存在多态
BaseClass bc = new BaseClass();
//输出6
System.out.println(bc.book);
bc.base();
bc.test();
//下面编译时类型和运行时类型完全一样,因此不存在多态
SubClass sc = new SubClass();
//输出123
System.out.println(sc.book);
//下面执行从父类继承到的base()方法
sc.base();
//下面执行子类的test()方法
sc.test();
//下面编译时类型和运行时类型不一样,多态发生
BaseClass ploymophicBc = new SubClass(); //父类编译 子类运行
//输出6,表明访问的是父类对象的实例变量
System.out.println(ploymophicBc.book);
//调用继承父类的base()方法
ploymophicBc.base();
//调用自身的test方法;
ploymophicBc.test();
//因为ploymophicBc的编译时类型是BaseClass
//BaseClass类没有提供sub()方法,所以下面代码编译时会出现错误;
//ploymophicBc.sub();
SubClass a= new BaseClass();//这个报错 不能子类编译父类运行
}
}
当把一个子类对象直接赋给父类引用变量时,其方法行为总是表现出子类方法的行为特征,而不是父类方法的行为特征。
通过引用变量来访问其所包含的实例变量时,系统总是试图访问编译时类型所定义的成员变量,而不是运行时的。 编译类中有同名先用编译类中的 没有在用运行类中的