1.编译时类型:声明该变量时使用的类型。
2.运行时类型:该变量指向的对象类型。
记住:对象调用编译时类型的属性和运行时类型的方法
class Birds { public String name; public Birds() { name = "birds"; } public void yell() { System.out.println("birds yell"); } } class Sparrows extends Birds { public String name; public Sparrows() { name = "sparrows"; } public void yell() { System.out.println("Sparrows yell"); } } public class TestDemo { public static void main(String[] args) { Birds bird = new Birds(); System.out.println(bird.name); bird.show(); System.out.println(); Birds birdOne = new Sparrows(); System.out.println(birdOne.name); birdOne.show(); System.out.println(); Sparrows sparrow = new Sparrows(); System.out.println(sparrow.name); sparrow.show(); } }
结果:
birds
birds yellbirds
Sparrows yellsparrows
Sparrows yell
分析:我们来看这段代码:Birds bird=new Sparrows(),由上面代码可以知道Sparrows类继承自Birds类,那么,假如bird的属性修饰符为public 那么访问属性时得到的是Birds类的属性还是Sparrows类的属性?方法调用又是哪个类?答案是:会得到Birds类的属性,调用Sparrows类的方法。为什么会这样呢?这里就需要知道什么是编译时类型和运行时类型,Java程序状态会分为编译和运行这两种状态,编译时,JVM会在栈中静态创建基本数据变量,和引用数据变量的引用,回到刚刚那句代码,显然,bird这个引用就是在编译时创建的,那么,bird的编译时类型就是Birds,当运行这段java代码时,JVM在堆中为bird新建一块内存,对应new Sparrows()这段代码,所以bird的运行时类型就是Sparrows。