📅  最后修改于: 2020-03-23 00:51:54             🧑  作者: Mango
让我们首先考虑以下Java程序作为重写或运行时多态的简单示例。
class Base {
public void fun() {
System.out.println("父类 fun");
}
}
class Derived extends Base {
public void fun() { // 重写父类的fun()
System.out.println("派生类 fun");
}
public static void main(String[] args) {
Base obj = new Derived();
obj.fun();
}
}
程序输出“派生类 fun”。
基类引用’obj’引用派生类对象(请参见表达式“ Base obj = new Derived()”)。在obj上调用fun()时,将根据引用对象的类型而不是引用进行调用。
使私有方法可以重写吗?
预测以下程序的输出。
class Base {
private void fun() {
System.out.println("父类 fun");
}
}
class Derived extends Base {
private void fun() {
System.out.println("派生类 fun");
}
public static void main(String[] args) {
Base obj = new Derived();
obj.fun();
}
}
我们收到编译器错误“ fun()在Base中具有私有访问权限”。因此,编译器尝试调用基类函数,而不是派生类,这意味着fun()不会被重写。
内部类可以访问其外部类的私有成员。如果我们扩展内部类并在内部类中创建fun()怎么办?
一个内部类可以访问其外部类的私有成员,例如,在下面的程序中,内部类展示访问私有数据成员。
/* Java展示通过内部类重写外部private方法 */
class Outer {
private String msg = "芒果文档";
private void fun() {
System.out.println("外部 fun()");
}
class Inner extends Outer {
private void fun() {
System.out.println("外部私有成员: " + msg);
}
}
public static void main(String args[]) {
// 分别创建外部对象和内部对象
Outer o = new Outer();
Inner i = o.new Inner();
// 这将调用内部的fun
i.fun();
// o.fun() 调用外部的fun(无运行时多态)
o = i;
o.fun();
}
}
输出:
外部私有成员: 芒果文档
外部 fun()
在上面的程序中,我们创建了一个外部类和一个内部类。我们从Outer扩展了Inner,并在Outer和Inner中都创建了一个fun()方法。如果我们观察到输出,则很明显,方法fun()未被重写。之所以如此,是因为私有方法是在编译时绑定的,并且引用变量的类型(而不是它所引用的对象的类型)决定了要调用的方法。附带说明一下,由于静态绑定,私有方法在性能上可能会更好(与非私有和非最终方法相比)。
与C++的比较
1)在Java中,允许内部类访问外部类的私有数据成员。此行为和C++相同。
2)在Java中,永远不能重写声明为private的方法,它们在编译期间实际上是有界的。此行为与C++不同。在C++中,我们可以有虚拟私有方法。