一、内部类的继承
内部类的构造器必须连接到指向其外围类对象的引用,因此继承内部类变得些许复杂,关键是指向外围类对象的引用必须被初始化而在导出类中不再存在可连接的默认对象,若要解决该问题,需要使用特殊的语法来明确说明它们之间的关系。
代码说明
package com.lh.innerclass.class6;
class WithInner{
class Inner{}
}
/****
*
* 内部类的继承
*
* @author Liu
*
*/
public class InheritInner extends WithInner.Inner{
public InheritInner(WithInner wi){
//获取外围类的引用
wi.super();
}
public static void main(String[] args) {
WithInner wi = new WithInner();
InheritInner ii = new InheritInner(wi);
}
}
小结:
1、内部类一般继承自某个类或实现了某个接口,内部类可以操作外围类的对象,因此可以认为内部类提供了某种进入外围类的接口
2、内部类可以独立继承某个接口的实现,无论外围类是否继承某个接口的实现,均对内部类无影响
二、内部类的覆盖
1、一般情况是否能被覆盖?
package com.lh.innerclass.class6.first;
class Egg{
private Yolk y;
protected class Yolk{
public Yolk(){
System.out.println("Egg.Yolk()");
}
}
public 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) {
BigEgg bigEgg = new BigEgg();
}
}
输出结果:
New Egg()
Egg.Yolk()
小结:
1、表明子类的内部类不能覆盖父类的内部类!
2、 继承时内部类是不能被覆盖的,虽然外围类存在继承的关系,内部类并未发生继承关系,这两个类分别为两个独立的实体,各自在自己的命名空间里
2、若想覆盖怎么办?
若要在两个内部类之间实现子类覆盖父类的内部类,那么只能使子类的内部类继承父类,并加些许变通。
package com.lh.innerclass.class6.first;
/****
*
* 如果子类想覆盖父类的内部类,子类的内部类需要继承父类的内部类
*
* @author Liu
*
*/
class Egg2{
private Yolk y = new Yolk();
protected class Yolk{
public Yolk(){
System.out.println("Egg2.Yolk()");
}
public void f(){
System.out.println("Egg2.Yolk.f()");
}
}
public Egg2(){
System.out.println("New Egg2()");
}
public void insertYork(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()");
}
public void f(){
System.out.println("BigEgg2.Yolk.f()");
}
}
public BigEgg2(){
insertYork(new Yolk());
}
public static void main(String[] args) {
Egg2 egg2 = new BigEgg2();
egg2.g();
}
}
输出结果:
Egg2.Yolk()
New Egg2()
Egg2.Yolk()
BigEgg2.Yolk()
BigEgg2.Yolk.f()
小结:
如果子类想覆盖父类的内部类,子类的内部类需要继承父类的内部类
三、局部内部类
局部内部类可以访问代码块作用域的常量以及外围类的所有成员
package com.lh.innerclass.class6.second;
interface Counter{
int next();
}
public class LocalInnerClass {
private int count = 0;
/***通过局部内部类构建:
*1、需要自定义带参或较复杂的构造器
*2、需要创建多个实例对象
*
*/
Counter getCounter(final String name){
class LocalCounter implements Counter{
public LocalCounter() {
System.out.println("LocalCounter()");
}
@Override
public int next() {
System.out.print(name);
return count++;
}
}
return new LocalCounter();
}
//通过匿名内部类构建
Counter getCounter2(final String name){
return new Counter() {
{
System.out.println("Counter()");
}
@Override
public int next() {
System.out.print(name);
return count++;
}
};
}
public static void main(String[] args) {
LocalInnerClass localInnerClass = new LocalInnerClass();
Counter c1 = localInnerClass.getCounter("Local Inner"),
c2 = localInnerClass.getCounter2("Anonymous Inner");
for (int i = 0; i < 5; i++) {
System.out.println(" " + c1.next());
}
for (int i = 0; i < 5; i++) {
System.out.println(" " + c2.next());
}
}
}
小结:
选择局部内部类可参考:
1、需要自定义带参或较复杂的构造器
2、需要创建多个实例对象