java中的许多对象(一般都是具有父子类关系的父类对象)在运行时都会出现两种类型:编译时类型和运行时类型。
例如:Person p = new Student();该变量的编译时类型时Person,运行时类型时Student。
说明一下编译时类型和运行时类型:
Java的引用变量有两个类型,一个是编译时类型,一个是运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,会出现所谓的多态。
因为子类其实是一个特殊的父类。因此java允许把一个子类对象直接赋值给一个父类引用变量,无须任何类型转换,或者称为向上转型,由系统自动完成。
引用变量在编译阶段只能调用其编译时类型所具有的方法,但运行时则执行它运行时类型所具有的方法,因此,编写java代码时,引用变量只能调用声明该变量所用类里包含的方法。与方法不同的是,对象的属性则不具备多态性。通过引用变量来访问其包含的实例属性时,系统总是试图访问它编译时类所定义的属性,而不是它运行时所定义的属性。
关键还是要理解这句:
Base who = new Sub(); //也就是向上转型
将一个父类对象的引用 指向了子类对象
通俗来讲,对象名(例如who)好比一个瓶子,其中的饮料就是属性和方法
这里向上转型做的是就是将一个父类瓶里装进子类饮料
这时,java有趣精妙的设计,使我们只能从这个”假父类瓶“中喝到父类的饮料,以及被子类重写的方法(此处用的是动态绑定)
我的个人理解分享一下
成员变量没有多态,而方法有多态。记住这句话就比较好理解了。
Base who = new Sub();//who被声明为Base类型,引用Sub实例
所以,who的成员变量是Base的,who的方法用的是子类重写的。
对于静态变量和静态方法都是属于类的,who是属于Base类的,所以who.staticVar和who.staticMethod()相当于Base.staticVar和Base.staticMethod(),一般不建议对象去调静态的东西,不信你看你的代码who.staticVar和who.staticMethod()在IDE里标了黄线。静态的东西建议类名去调用。
Base who= new Sub()是父类引用指向子类对象,说白了就是多态,你可以把who的类型当成Base类,但他比普通的Base who=new Base()方法多一个功能,就是当调用父类在子类中被重写的方法是,会展现子类的特性,也就是会调用子类的方法,但这只对被重写的方法有效,还有就是静态成员和方法是不能被继承的