1,成员变量:
在多态中,子父类成员变量同名。
- 在编译时期:参考的是引用型变量所属的类中是否有调用的成员。(编译时不产生对象,只检查语法错误)
- 运行时期:也是参考引用型变量所属的类中是否有调用的成员。
- 简单一句话:无论编译和运行,成员变量参考的都是引用变量所属的类中的成员变量。
- 再说的更容易记忆一些:成员变量 --- 编译运行都看 = 左边。
2,成员函数。
- 编译时期:参考引用型变量所属的类中是否有调用的方法。
- 运行时期:参考的是对象所属的类中是否有调用的方法。
为什么是这样的呢?因为在子父类中,对于一模一样的成员函数,有一个特性:覆盖。 - 简单一句:成员函数,编译看引用型变量所属的类,运行看对象所属的类。
- 更简单:成员函数 --- 编译看 = 左边,运行看 = 右边。
3,静态函数。
- 编译时期:参考的是引用型变量所属的类中是否有调用的成员。
- 运行时期:也是参考引用型变量所属的类中是否有调用的成员。
为什么是这样的呢?因为静态方法,其实不所属于对象,而是所属于该方法所在的类。
调用静态的方法引用是哪个类的引用调用的就是哪个类中的静态方法。 - 简单说:静态函数 --- 编译运行都看 = 左边.
看下面代码:
public class PrivateOverride {
public int i = 10;//成员变量
private void f() {//私有成员函数
System.out.println("private f()");
}
public void g() {//成员函数
System.out.println("PrivateOverride g()");
}
public static void s() {//静态函数
System.out.println("PrivateOverride s()");
}
public static void main(String[] args) {
PrivateOverride po = new Derived();
po.f();
po.g();
po.s();
System.out.println("i="+po.i);
((Derived)po).e();
}
}
class Derived extends PrivateOverride{
public int i = 20;
public void f() {
System.out.println("Derived f()");
}
public void g() {
System.out.println("Derived g()");
}
public void e() {
System.out.println("Derived e()");
}
public static void s() {
System.out.println("Derived s()");
}
}
运行结果:
private f()
Derived g()
PrivateOverride s()
i=10
Derived e()
上面有个f()方法基类是私有方法,子类也有个公有的f()方法,执行po.f();后,结果是基类的f()方法调用,这是由于private方法被自动认为是final方法,而对于子类是屏蔽的,因此,在这种情况下,Derived类中的f()方法就是一个全新的方法,既然基类中的f()方法在子类Derived中不可见,因此甚至也不能被重载。
结论就是:只有非private方法才可以被覆盖,但是还需要密切注意覆盖private方法的现象,这时虽然编译器不会报错,但是也不会按照我们所期望的来执行。确切地说,在基类中,对于基类中private方法,最好采用不同的名字。
网友评论