JAVA多态: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 {
//重新定义一个book实例属性覆盖父类的book实例属性 public String book = "世界您好!";
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);
//下面两次调用将执行BaseClass(父类)的方法 bc.base(); bc.test();
//下面编译时类型和运行时类型完全一样,因此不存在多态 SubClass sc = new SubClass(); //创建子类对象
//输出"世界您好!"
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 类没有提供资金SUBYYIF
//所以下面代码编译时会出现错误 //ploymophicBc.sub(); } }
上面程序的main方法中显式创建了3个引用变量,对于前两个引用变量bc和sc,它们编译时类型和运行时类型完全相同,因此调用它们的属性和方法非常正常,完全没有任何问题。但第三个引用变量ploymophicBc则比较特殊,它的编译时类型是BaseClass,而运行时类型是SubClass,当调用该引用变量 的test(BaseClass类定义了该方法,子类SubClass覆盖了父类的该方法)实际执行的SubClass类中覆盖后的test方法,这就是多态。
因为子类其实是一种特殊的父类,因此JAVA允许把一个子类对象直接赋给一个父类引用变量,无须任何类型转换,或者被称为向上转型(upcasting),向上转型由系统自动完成。
当把一个子类对象直接赋给父类引用变量,例如上面的BaseClass ploymophicBc = new SubClass();,这个ploymophicBc引用变量 的编译时类型是BaseClass,而运行时类型是SubClass,当运行时调用该引用 变量的方法时,其方法行为总是像子类方法的行为,而不是像父类方法行为,这将出现相同类型的变量、执行同一个方法时呈现出不同的行为特征,这就是多态。 |
|