Java内部类可以被覆盖吗?内部类的继承

package Day05_innerclass;

//: innerclasses/BigEgg2.java
// Proper inheritance of an inner class.
import static myutil.Print.print;
//import static net.mindview.util.Print.*;

class Egg2 {
    protected class Yolk {
        public Yolk() { print("Egg2.Yolk()"); }
        public void f() { print("Egg2.Yolk.f()");}
    }
    private Yolk y = new Yolk();
    public Egg2() { print("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() { print("BigEgg2.Yolk()"); }
        public void f() { print("BigEgg2.Yolk.f()"); }
    }
    public BigEgg2() { insertYolk(new Yolk()); }   // 如果注释这行, 发现 bigegg2 的内部类都没被构造,因为bigegg2 的new Yolk() 是优先在bigegg2下面找有没有,
    public static void main(String[] args) {
        Egg2 e2 = new BigEgg2();//  此处在实例化e2 之前,会先看bigegg2, 先看 他的构造函数,发现构造函数之外,big先继承egg2, 所以向上寻找
                                //  找到egg2 的构造函数,然后发现有个 字段,其中有个new 内部类,于是先 对egg2 的内部类进行初始化,找到内部类的构造函数,构造函数之外没有字段
                                //  所以 egg2 的内部类的构造函数 执行, 回到egg2 类 的字段那里,private y=new yolk() 此时 y 有了初始值
                                //  所以执行 egg2 的构造函数
                                //  回到 bigegg2 的构造函数那里,基类egg2 以及 egg2 的内部类都已经准备好了,
                                //                            但是,bigegg2构造函数之前,发现还有一个内部类,
        e2.g();
    }
} /* Output:
Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()
BigEgg2.Yolk.f()
*///:~

如果把 BigEgg2 中的内部类注释掉:

发现BigEgg2没有因为自己没有内部类而报错,而是去内部的基类(父类)当中寻找Yolk类,并且进行相应的初始化

如果把 BigEgg2 中 InsertYolk()这行注释掉

可以看出BigEgg2 的内部类没有被使用到,因为注释掉

public BigEgg2() { insertYolk(new Yolk()); } 

后,BigEgg2 的构造器使用的是默认的 BigEgg2()在BigEgg2 的作用域内没有明显调用 new Yolk()。因此, BigEgg2 的内部类也就没有被使用到,从而也就不必对其初始化。

总结: 

1、在使用函数时的优先顺序:先是从导出类(子类)中寻找,如果子类中没有该函数,则会向父类寻求帮助(父类) (与多态类似)

2、内部类在使用到才会被初始化

3、在初始化时,一般都是会先看构造器,然后检查构造器之前有没有存在着  字段(域), (这些字段 相当于是 一些前置准备工作,准备好后,才会去执行构造函数)。如果字段又存在着调用,则又会看调用的是哪里的函数,在进行相应初始化,

例如:

class Egg2 {
    protected class Yolk {
        public Yolk() { print("Egg2.Yolk()"); }
        public void f() { print("Egg2.Yolk.f()");}
    }
    private Yolk y = new Yolk();
    public Egg2() { print("New Egg2()"); }
    public void insertYolk(Yolk yy) { y = yy; }
    public void g() { y.f(); }
}

在执行Egg2 的构造器之前,会先检查Egg2 下方的字段,发现了此处的private Yolk y = new Yolk(),从而 在Egg2 类的作用域当中寻找 Yolk类,也就是此处的内部类,在进行相应初始化。 

4、内部类中的方法看似被重载,但是实际上确不是,因为Egg2的内部类Yolk和BigEgg2 下的Yolk实际上是两个相互独立的实体,他们各自有着自己的命名空间。

//: innerclasses/BigEgg.java
// An inner class cannot be overriden like a method.
import static net.mindview.util.Print.*;

class Egg {
  private Yolk y;
  protected class Yolk {
    public Yolk() { print("Egg.Yolk()"); }
  }
  public Egg() {
    print("New Egg()");
    y = new Yolk();
  }
}	

public class BigEgg extends Egg {
  public class Yolk {
    public Yolk() { print("BigEgg.Yolk()"); }
  }
  public static void main(String[] args) {
    new BigEgg();
  }
} /* Output:
New Egg()
Egg.Yolk()
*///:~

此处 按理来说 new BigEgg()时 内部使用的 Yolk应该是 重载后的Yolk,但是实际上确不是。因为,BigEgg的yolk没有像 之前例子中 明确继承  Egg的Yolk。因此两个Yolk 是相互独立的,不会相互干扰。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值