1、内部类的继承:
由于创建内部类对象的时候需要外部类的对象,所以在继承内部类的时候情况会比较复杂,需要确保内部类对象与外部类对象之间的引用正确建立,为了解决这个问题,Java提供了一种特殊的语法,来说明它们之间的关系。
package com.test;class Outer {public class Inner{public void hello() {System.out.println("Hello,World.");}}
}public class InheritInner extends Outer.Inner {//类InheritInner继承在Outer类中定义的内部类Inner//定义类类InheritInner的构造函数,传入参数类型为外部类对象public InheritInner(Outer ou) {ou.super();}
}class Test3 {public static void main(String[] args) {Outer ou = new Outer();InheritInner ii = new InheritInner(ou);ii.hello(); //输出:"Hello,World."}
}
上面代码的理解:
(1)类InheritInner继承Outer类中定义的内部类Inner,为了建立内部类Inner的对象到外部类Outer的对象之间的关系,需要在子类InheritInner中定义一个特殊的构造方法,其参数是外部类Outer对象的引用,然后在子类的构造方法中使用“ou.super();”这种特殊语法的语句,来建立内部类对象到外部类对象的引用关系。
(2)在main方法中,依然是先建立外部类的对象,然后将该对象的引用传递给InheritInner类的构造方法。程序运行输出:"Hello,World.",说明成功运行,调用了InheritInner类继承自内部类Inner中定义的hello()方法。
2、内部类的覆盖:
编写一个类,从一个外部类继承,然后在类中重新定义外部类中的内部类,会发生什么情况呢?内部类是否会被重写呢?通过如下的代码可以更好理解。
package com.test;class OneOuterClass {class OneInnerClass {public void foo() {System.out.println("1、这是一条定义在OneOuterClass类中的内部类OneInnerClass中的定义的foo()方法执行输出的信息。");}}// 定义外部类的构造函数,在构造函数内创建内部类OneInnerClass的对象,执行其foo()方法public OneOuterClass() {new OneInnerClass().foo();}
}/*** OverrideInner类:继承Outer类*/
public class OverrideInner extends OneOuterClass{class OneInnerClass {public void foo() {System.out.println("2、这是来自OverrideInner类中重新定义的OneInnerClass中的foo()方法输出的信息。");}}public static void main(String[] args) {new OverrideInner();}
}
运行上面的代码,输出信息:“1、这是一条定义在OneOuterClass类中的内部类OneInnerClass中的定义的foo()方法执行输出的信息。”
上面代码分析:
(1)类OverrideInner继承外部类OneOuterClass,并重新定义了OneOuterClass类中的内部类OneInnerClass。
(2)在类OneOuterClass的构造函数中调用了内部类OneInnerClass中定义的方法foo()。
(3)从输出信息看,在类OverrideInner中重新定义的OneInnerClass并没有覆盖继承的类OneOuterClass中定义的类OneInnerClass的方法。也就是没有覆盖。这是因为它们在完全不同的名称空间下,属于两个不同的内部类。
3、内部类规则总结
比起普通的顶层类来说,内部类有着更为复杂的规则。首先,内部类如同类中的成员一样,有访问权限,可以声明为public\protected\default(不加说明符时)\private,这与普通类是不一样的,普通类只能声明为public或者default(不加说明符)。
除了访问权限之外,我们还可以声明内部类为abstact、final或者static。当一个内部类被声明为抽象类时,就不能直接实例化这个内部类了;当一个内部类被声明为final时,说明这个类不能被继承;当一个内部类被声明为静态类static时,将可以直接创建这个内部类的对象。
当声明一个静态static的内部类(嵌套类)时,可以在这个内部类中加入静态方法,但是不能访问外部的非静态成员。在非静态的内部类中不能包含静态成员,静态成员属于类本身,可以直接通过类名来访问,而非静态的内部类对象依赖于外部类对象,也就是说,必须有外部类对象存在,而这与静态成员属于类本身,通过类名来调用冲突了。
内部类不仅可以让我们将逻辑上相关的一组类组织起来,并由外部类来控制内部类的可见性,而且与接口的结合能实现更为灵活与强大的功能。
Java并不支持类的多继承,当需要从多个类继承的时候,可以让外部类继承一个类,同时编写一个内部类来继承另外一个类。这样既能得到多继承的好处,又避免了C++多继承存在的问题。