背景
很多人在初学java时可能都听过一句话:编译看左边,运行看右边。那么,这句话到底什么意思呢?
甭着急,我们来一起瞅瞅。
代码
先来看父类:
/**
* 本文原创作者:谷哥的小弟
* 作者博客地址:http://blog.csdn.net/lfdfhl
*/
public class Father {
public int age = 45;
public String getMessage() {
String string = "I like you";
return string;
}
}
再来看子类:
/**
* 本文原创作者:谷哥的小弟
* 作者博客地址:http://blog.csdn.net/lfdfhl
*/
public class Son extends Father {
public int age = 23;
@Override
public String getMessage() {
String string = "Just do it";
return string;
}
public void play() {
System.out.println("happy day");
}
}
要点概述:
1、Son继承自Father
2、Son重写了父类的getMessage( )方法
3、Son类中拥有自身特有的play( )方法
OK,至此我们完成了父类和子类的代码编写。最后,我们来进行测试。
/**
* 本文原创作者:谷哥的小弟
* 作者博客地址:http://blog.csdn.net/lfdfhl
*/
public class Test {
public static void main(String[] args) {
Father father = new Son();
int age = father.age;
System.out.println(age);
String message = father.getMessage();
System.out.println(message);
//error code
//father.play();
}
}
分析
看完示例后,我们再来看看"编译看左边,运行看右边"是什么含义?
当存在继承时,我们通常会使用父类引用指向子类对象,例如:
Father father = new Son();
在这句代码中等号的左边是父类引用,等号的右边是子类的对象。
接下来,我们可以使用father对象调用方法。
在编译阶段会去检查父类引用(在等号的左边)是否拥有该方法。
例如:father.getMessage( );可以通过编译,因为Father类中有方法getMessage( )
例如:father.play( );不可以通过编译,因为Father类中没有方法play( )
以上,就是常说的"编译看左边"。
在通过编译后执行代码时实际调用的是子类对象(在等号的右边)的方法。
例如:father.getMessage( );打印的是Just do it 而不是 I like you
以上,就是常说的"运行看右边"。
问题
为什么 int age = father.age; 的值是45而不是23呢?
因为:成员变量不具备多态性。成员变量的值取决于引用所属的类