您的位置:首页 > 编程语言 > Java开发

《java编程思想系列之7》 内部类

2014-02-22 13:13 120 查看
一、创建内部类

内部类:可以将一个类的定义放在另一个类的定义内部
内部类和组合是完全不同的概念



如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么必须像在main()方法中那样,具体的指明这个对象的类型:OuterClassName.InnerClassName.

二、链接到外部类

内部类自动拥有对其外围类的所有成员的访问权限:
当某个外围类的对象创建了一个内部类对象的时候,此内部类对象必定会咪咪的捕获一个指向那个外围类对象的引用。然后,当你访问此外围类的成员的时候,就是用那个引用来选择外围类的成员。幸运的时候,编译器会帮助你处理所有的细节,但是你现在可以看到:内部类的对象只能在与其外围类的对象相连的时候才能被创建(在内部类是非static类时候)。构件内部类对象的时候,需要一个指向外围类的引用,如果编译器访问不到这个引用就会出错。

三、使用.this和.new



想要直接创建内部类的对象,你不能按照你想象的方式,去引用外部类的名字DotNew,而是必须使用外部类的对象来创建该内部类对象。

在拥有外部类对象之前是不可能创建内部类对象的,这是因为内部类对象会暗暗的连接到创建它的外部类的对象上。但是,如果你创建是嵌套类(静态内部类),那么它就不需要对外部类对象的引用。

四、内部类与向上转型

当将内部类向上转型为其基类,尤其是转型为一个接口的时候,内部类就有了用武之地。(从实现了某个接口的对象,得到此接口的引用,与向上转型为这个对象的基类,实质上是一样的)。这是因为内部类---某个接口的实现---能够完全不可见,并且不可用。所得到的只是指向基类或者接口的引用,所以能够很方便的隐藏实现细节。

五、在方法和作用域内的内部类



TrackingSlip类被嵌入if 语句的作用域内,这并不是说该类的创建是有条件的,它其实与别的类一起编译过了。然而,在定义TrackingSlip的作用域之外,它是不可用的,除此之外,它与普通的类一样。

六、匿名内部类



这种奇怪的语法指的是:创建一个继承自Contents的匿名类的对象。

如果定义一个匿名内部类,并且希望它使用一个在其外部定义的对象,那么编译器就会要求其参数引用是final的,就像你在destination()的参数中看到的那样。如果你忘记了,将会得到一个编译时错误信息:



匿名内部类与正规的继承相比有些限制,因为匿名内部类既可以扩展类,也可以实现接口,但是不能两者兼备。而且如果是实现接口,也只能实现一个接口。

内部类实现工厂模式

七、嵌套类

嵌套类:如果不需要内部类对象与其外围类对象之间有联系,那么可将内部类声明为static。

1)要创建嵌套类的对象,并不需要其外围类的对象
2)不能从嵌套类的对象中访问非静态的外围类对象
3)普通的内部类不能有static数据和static字段,也不能包含嵌套类。但是嵌套类可以包含所有这些东西

1、接口内部的类

正常情况下,不能在接口内部放置任何代码,但是嵌套类可以作为接口的一部分。你放到接口中的任何类都自动的是public和static的。因为类是static的,只是将嵌套类置于接口的命名空间内,这并不违反接口的规则。你甚至可以在内部类中实现其外围接口:





使用嵌套类类测试代码

2、从多层嵌套类中访问外部类的成员

一个内部类被潜逃多少层并不重要-----它能够透明的访问所有它所嵌入的外围类的所有成员。



八、为什么需要内部类

每个内部类都能独立的继承自一个(接口的)实现,所以无论外围类是否已经继承类某个(接口的)实现,对于内部类都没有影响。

内部类有效的实现了“多重继承”

1)内部类可以有多个实例,每个实例都有自己得状态信息,并且与其外围类对象的信息相互独立
2)在单个外围类中,可以让多个内部类以不同的方式实现同一接口,或继承同一个类
3)创建内部类对象的时刻并不依赖于外围类对象的创建
4)内部类并没有令人迷惑的“is-a”关系,它就是一个独立的实体。

九、内部类的继承

因为内部类的构造器必须连接到指向其外围类对象的引用,所以在继承内部类的时候,事情会变得有点复杂。问题在于,那个指向外围类的对象的“秘密的”引用必须被初始化,二在导出类中不再存在可连接的默认对象。要解决这个问题,必须使用特殊的语法来明确的说清它们之间的关联:



10、内部类可以被覆盖吗

默认的构造器是编译器自动生成的,这里是调用基类的默认构造器。这个例子说明,当继承了某个外围类的时候,内部类并没有发生什么特别神奇的变化。这两个内部类是完全独立的两个实体,各自在自己得命名空间内:





当然,明确的继承某个内部类也是可以的:



11、局部内部类

使用局部内部类而不是使用匿名 内部类的理由就是:
1)我们需要一个已命名的构造器,或者需要重载构造器,而匿名内部类只能用于实例初始化
2)需要不止一个该内部类的对象

12、内部类标识符

如果内部类是匿名的,编译器会简单的产生一个数字作为其标识符。如果内部类是嵌套在别的内部类之中,只需要直接将他们的名字加上其外围类标识符与“$”的后面:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息