Think in Java
- 第十章 内部类
-
- 1.创建内部类
- 2.链接外部类
- 3.使用.this与.new
- 4.在方法和作用域内的内部类
- 5.嵌套类
-
- 5.1 接口内部的类
- 5.2 多层嵌套类
- `6. 为什么需要内部类`
- 7. 内部类的继承
- 8. 内部类的覆盖
- 9. 局部内部类
- 10. 内部类标识符
第十章 内部类
可以讲一个类的定义放在另一个类的定义内部,这就是内部类。
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()); } } /*output: Method Inner Inner */
匿名类是不能有名字的类,它们不能被引用,只能在创建时用new语句来声明它们。
5.嵌套类
如果不需要内部类对象与其外部类对象之间有联系,那么可以将内部类声明为static。这通常称为嵌套类。
嵌套内部类与普通内部类的区别:普通内部类的字段与方法只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段,也不能包含嵌套类。但是嵌套类可以包含这些东西。
嵌套类意味着:1).创建嵌套类对象,不需要使用外部类对象,可以直接创建。2).不能在嵌套内部类中访问非静态的外部类成员。
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() } } } /*output Hello! */
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. 内部类标识符
- 外部类名字$内部类名字.class