第十章 内部类
可以讲一个类的定义放在另一个类的定义内部,这就是内部类。
1.创建内部类
public class InnerTest {
public static void main ( String[ ] args) {
Outer o = new Outer ( ) ;
Inner inner = o. getInner ( ) ;
inner. say ( ) ;
}
}
class Outer {
class Inner {
public void say ( ) {
System. out. println ( "Hello World!" ) ;
}
}
public Inner getInner ( ) {
Inner inner = new Inner ( ) ;
return inner;
}
}
2.链接外部类
3.使用.this与.new
如果内部类需要生成对外部类的引用,则可以在外部类的名字后紧跟.this,这样产生的引用自动的具有正确的类型,且这点在编译时期就被知晓并受到检查,因此不会受到额外的运行开销。
piblic class Outer {
void say ( ) {
System. out. print ( "Outer.say()" ) ;
}
class Inner {
public Outer getOuter ( ) {
return Outer. this ;
}
}
public Inner getInner ( ) {
return new Inner ( ) ;
}
public static void main ( String[ ] args) {
Outer o = new Outer ( ) ;
Outer. Inner i = o. getInner ( ) ;
i. getOuter ( ) . say ( ) ;
}
}
如果要创建某个类的内部类,不能直接使用“外部类.内部类”,而是需要使用.new语法。例如:“外部类.new 内部类()”
4.在方法和作用域内的内部类
public class Outer {
void say ( ) {
System. out. print ( "Outer.say()" ) ;
}
class Inner {
public String say ( ) {
return "Inner" ;
}
}
public Inner getInner ( ) {
return new Inner ( ) {
@Override
public String say ( ) {
return "Method Inner" ;
}
} ;
}
public static void main ( String[ ] args) {
Outer o = new Outer ( ) ;
Outer. Inner i = o. getInner ( ) ;
System. out. println ( i. say ( ) ) ;
System. out. println ( o. new Inner ( ) . say ( ) ) ;
}
}
匿名类是不能有名字的类,它们不能被引用,只能在创建时用new语句来声明它们。
5.嵌套类
如果不需要内部类对象与其外部类对象之间有联系,那么可以将内部类声明为static。这通常称为嵌套类。
嵌套类意味着:1).创建嵌套类对象,不需要使用外部类对象,可以直接创建。2).不能在嵌套内部类中访问非静态的外部类成员。
嵌套内部类与普通内部类的区别:普通内部类的字段与方法只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段,也不能包含嵌套类。但是嵌套类可以包含这些东西。
5.1 接口内部的类
正常情况下,接口内部是不能放置任何代码的,但是嵌套类可以作为接口的一部分。接口中的任何类都自动是被public和static修饰。嵌套类是static的,所以并不违反接口的规则,甚至可以在嵌套类上实现外部接口。 如果想要创建某些公共代码,使他们可以被某个接口的所有不同实现所公用,那么使用接口内部的嵌套类会很方便。
public interface OuterInteface {
void say ( ) ;
class Inner implements Outerface {
public void say ( ) {
System. out. print ( "Hello!" ) ;
}
public static void main ( String[ ] args) {
new Inner ( ) . say ( )
}
}
}
5.2 多层嵌套类
一个内部类被嵌套多少层并不重要,它能透明地访问所有它所嵌入的外部类的所有成员。
6. 为什么需要内部类
内部类有效的实现了“多重继承”。
每个内部类都能独立地继承自一个(接口)的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类没有任何影响。 如果不需要解决“多重继承”的问题,那么可以用别的编码方式。但如果要使用内部类,还可以获得一些其他特性:1). 内部类可以有多个实例,每个实例都有自己的状态信息,并且与其外部类对象的信息相互独立。 2). 在单个外部类中,可以让多个内部类以不同的方式实现同一个接口,或继承同一个类。 3). 创建内部类对象的时刻并不依赖外部类对象的创建。 4). 内部类并没有令人迷惑的“is-a”关系,它就是一个独立的实体
7. 内部类的继承
class Outer {
class Inner { }
}
public class InnerSon extends Outer. Inner {
InnerSon ( Outer out) {
out. super ( ) ;
}
public static void main ( String[ ] args) {
Outer o = new Outer ( ) ;
InnerSon i = new InnerSon ( o) ;
}
}
8. 内部类的覆盖
9. 局部内部类
在方法中创建一个有名字的内部类,但这个内部类不能有访问说明符。(public,protected,private)
10. 内部类标识符