mirror of
https://github.com/LingCoder/OnJava8.git
synced 2026-08-23 22:43:28 +08:00
更新小节 内部类可以被覆盖么?
This commit is contained in:
@@ -1193,7 +1193,96 @@ enclosingClassReference.super();
|
||||
|
||||
<!-- Can Inner Classes Be Overridden? -->
|
||||
|
||||
## 内部类可以被重写么?
|
||||
## 内部类可以被覆盖么?
|
||||
|
||||
如果创建了一个内部类,然后继承其外围类并重新定义此内部类时,会发生什么呢?也就是说,内部类可以被覆盖吗?这看起来似乎是个很有用的思想,但是“覆盖”内部类就好像它是外围类的一个方法,其实并不起什么作用:
|
||||
|
||||
```java
|
||||
// innerclasses/BigEgg.java
|
||||
// An inner class cannot be overridden like a method
|
||||
class Egg {
|
||||
private Yolk y;
|
||||
protected class Yolk {
|
||||
public Yolk() {
|
||||
System.out.println("Egg.Yolk()");
|
||||
}
|
||||
}
|
||||
Egg() {
|
||||
System.out.println("New Egg()");
|
||||
y = new Yolk();
|
||||
}
|
||||
}
|
||||
public class BigEgg extends Egg {
|
||||
public class Yolk {
|
||||
public Yolk() {
|
||||
System.out.println("BigEgg.Yolk()");
|
||||
}
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
new BigEgg();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
输出为:
|
||||
|
||||
```
|
||||
New Egg()
|
||||
Egg.Yolk()
|
||||
```
|
||||
|
||||
默认的无参构造器是编译器自动生成的,这里是调用基类的默认构造器。你可能认为既然创建了BigEgg的对象,那么所使用的应该是“覆盖后”的Yolk版本,但从输出中可以看到实际情况并不是这样的。
|
||||
|
||||
这个例子说明,当继承了某个外围类的时候,内部类并没有发生什么特别神奇的变化。这两个内部类是完全独立的两个实体,各自在自己的命名空间内。当然,明确地继承某个内部类也是可以的:
|
||||
|
||||
```java
|
||||
// innerclasses/BigEgg2.java
|
||||
// Proper inheritance of an inner class
|
||||
class Egg2 {
|
||||
protected class Yolk {
|
||||
public Yolk() {
|
||||
System.out.println("Egg2.Yolk()");
|
||||
}
|
||||
public void f() {
|
||||
System.out.println("Egg2.Yolk.f()");
|
||||
}
|
||||
}
|
||||
private Yolk y = new Yolk();
|
||||
Egg2() { System.out.println("New Egg2()"); }
|
||||
public void insertYolk(Yolk yy) { y = yy; }
|
||||
public void g() { y.f(); }
|
||||
}
|
||||
public class BigEgg2 extends Egg2 {
|
||||
public class Yolk extends Egg2.Yolk {
|
||||
public Yolk() {
|
||||
System.out.println("BigEgg2.Yolk()");
|
||||
}
|
||||
@Override
|
||||
public void f() {
|
||||
System.out.println("BigEgg2.Yolk.f()");
|
||||
}
|
||||
}
|
||||
public BigEgg2() { insertYolk(new Yolk()); }
|
||||
public static void main(String[] args) {
|
||||
Egg2 e2 = new BigEgg2();
|
||||
e2.g();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
输出为:
|
||||
|
||||
```
|
||||
Egg2.Yolk()
|
||||
New Egg2()
|
||||
Egg2.Yolk()
|
||||
BigEgg2.Yolk()
|
||||
BigEgg2.Yolk.f()
|
||||
```
|
||||
|
||||
现在BigEgg2.Yolk通过extends Egg2.Yolk明确地继承了此内部类,并且覆盖了其中的方法。
|
||||
|
||||
insertYolk()方法允许BigEgg2将它自己的Yolk对象向上转型为Egg2中的引用y。所以当g()调用y.f()时,覆盖后的新版的f()被执行。第二次调用Egg2.Yolk(),结果是BigEgg2.Yolk的构造器调用。
|
||||
|
||||
<!-- Local Inner Classes -->
|
||||
|
||||
|
||||
Reference in New Issue
Block a user