java内部类

来源:互联网 发布:python 乘方 编辑:程序博客网 时间:2024/05/29 18:14

内部类就是将一个类的定义放在另一个类的定义的内部。
特性:将逻辑相关的类组织在一起,并控制内部类的可视性。(注意:和组合是不同)外部类对内部类是透明的,内部类能与外部类通信。
1.创建内部类
在外部类类中使用内部类跟普通类一样,区别在于内部类的名字是嵌套在外部类里面的。(如:外部类.内部类)。
2.链接到外部类
内部类对象与外部类对象的联系。内部类对象能够访问其外部类对象的所有成员。(当外部类的对象创建内部类对象时,内部类对象会自动秘密的捕获一个指向外部类的对象的引用。在内部类对象访问外部类对象成员时,就会用这个引用来选择外部类的对象的成员。编译器处理这些细节,所以内部类的对象只能与外部类的对象相关联的情况下才能被创建(静态内部类例外)。构建内部类对象时,需要一个指向其外部类对象的引用。)
3.使用.this和.new
当内部类对象需要生成外部类对象的引用时,可以使用:外部类的名字.this.
当外部类对象需要创建内部类对象时,必须使用:外部类对象的引用.new 内部类();
4.内部类与向上转型
外部类提供基类(接口)的实现实现方法,内部类继承(实现)基类(接口)(内部类对外完全不可见).
应用:当客服端程序员需要一个基类(或接口),现在客户端程序员只能通过外部类的方法获得基类(接口)的实现,而内部来具体的实现对客户端程序员来说的不可见的。
5.在方法和作用域内的内部类
1)定义在方法中的内部类(局部内部类)。
应用:当某个方法需要返回一个基类(接口)时,可以在方法中使用内部类继承(实现)基类(接口),然后返回内部类的向上转型。
2)定义在作用域的内部类,此作用域在方法的内部。
应用:当某个作用域需要某个基类(接口)的功能时,可以在作用域中使用内部类来实现。
3)实现接口的匿名内部类。
匿名内部类其实就是继承(实现)了某基类(接口)后在向上转型为基类(接口)。
形式:基类(接口) = new 基类(接口)(){ 具体实现内容 };
4)匿名内部类扩展了有非默认构造器。
形式:基类(接口) = new 基类(接口)(参数。。。){ 具体实现内容 };
5)匿名内部类执行字段的初始化。
当在匿名内部类需要使用一个在其外部定义的对象时,那么参数的引用必须时final的。如:基类(接口) = new 基类(接口)(final String srt){ 具体实现内容 };
如果参数是传递给匿名构造器的基类那么它不是直接被内部类使用的,所以不需要添加final.如果参数是匿名内部类内部直接使用的那么必须为final.
6)匿名内部类通过实例初始化实现构造(匿名内部类不可能有构造器).
6.匿名内部类
由于匿名内部类没有名字,那么在匿名内部类中不可能有命名的构造器。但可以通过实例初始化来达到匿名内部类创建一个构造器的效果。
但也仅有这样一个构造器。
匿名内部类的限制:匿名内部类只能继承基类或实现一个接口,但不能兼有。
匿名内部类与工厂方法
这里写图片描述
实现类中有个静态抽象类类型的变量,它是用匿名内部类实现抽象工厂类,它的工厂方法时创建自己这种类型(实现类)并向上转型为基类类型。当要实现实现类时,可以使用静态抽象类类型变量来调用它的工厂方法来获得实现类。
7.嵌套类(静态内部类)
定义:当内部类声明为staitc时为嵌套类,嵌套类与外部类对象之间没有联系。创建嵌套类就表明不需要外部类的对象,也就不能从嵌套类的对象中访问非静态(static)的外部类对象。
注:普通内部类不能有static数据和static字段,也不能包含嵌套类。因为static的数据等只能在静态和顶级类型(外部类)中声明。嵌套类则可以。
原因:因为静态变量和静态方法都可以通过类名就能访问,而不必实例化对象;而普通内部类的初始化要利用外部类的实例化对象。
7.1接口与静态内部类
静态内部类可以放在接口中,因为接口中的任何类对自动地是pubilc和static的。所以内部类类是static的,也就是将静态内部类置于接口的命名空间中,这也没违反接口的规则。从而可以使用静态内部类实现的外围接口。
7.2从多层内部类中访问外部类的成员
当一个内部类被嵌套了很多层,它也能透明的访问所有它所嵌入的外部类的所有成员。
8.内部类的使用
内部类继承自某个类或实现某个接口,内部类的代码操作创建它的外部类的对象,可以认为内部类提供了某种进入其外部类的窗口。
每个内部类都能独立的继承或实现某个类或接口,无论外部类是否已经继承或实现,对内部类没有影响。
使用内部类可以实现继承多个类的能力,也就是多重继承。
内部类的特性:
1)内部类可以有多个实例,且每个实例都有自己的状态信息,并且与外部类对象的信息相互独立。
2)2)在单个外部类中,可以让多个内部类以不同的方式实现同一个接口(类)。
3)创建内部类对象的时刻并不依赖于外部类的对象的创建。
4)内部类并没有令人迷惑的“is-a”关系,它就是个独立的实体。
1.闭包与回调
闭包的定义:是一个可以调用的对象,这个对象记录了来自与创建这个对象的作用域的信息。内部类就是面向对象的闭包,因为它包含了外部类对象的信息,它还自动的拥有了一个指向外部类对象的引用,在外部类对象的作用域内,内部类有权操作所有的成员。
回调:通过回调,对象能够携带一些信息,这些信息允许它在稍后的某个时刻调用初始的对象。
调用方式分三种:
同步调用:是一种阻塞式的调用,调用方要等待对方执行完毕后才返回,是一种单向调用;
回调:是一种双向调用模式。被调用方在接口被调用时也会调用对方的接口;
异步调用:是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客服方(即调用客服方的接口);一般是通过回调来实现的,回调是异步调用的基础。
2.内部类与控制框架
应用控制框架:就是用来被设计用以解决某类特定问题的一个类或一组类。当要运用某个应用程序框架,通常是继承一个类或者多个类,并覆盖某些方法。在覆盖后的方法中,编写代码制定应用程序框架提供的通用解决方案,以解决特定问题。(是设计模式中模板方法的一个例子)
设计模式:总是将变化的事物与保持不变的事物分离开。
模板方法:包含算法的基本结构,并且会调用一个或多个可覆盖的方法,以完成算法的动作。模板方法是保持不变的的事物,而可覆盖的方法就是变化的事物。
控制框架:是一类特殊的应用程序框架,它用来解决响应事件的需求。主要用来响应事件的系统被称为事件驱动系统。(图像用户接口GUI,几乎全是事件驱动系统)
Java Swing库就是一个控制框架,用来解决GUI问题,并使用了大量的内部类。
9.内部类的继承
当要继承一个内部类时,需要在构造器中传入内部类的外部类对象,并使用外部类对象.super()。
因为内部类的构造器必须连接到一个指向外部类对象的引用,而这个引用又是外部类对象在创建内部类对象时动态的进行指向的。所以当要继承一个内部类时,使用这种特殊的语法需要显式的传入一个外部类对象,来说明内部类与外部类对象的联系。
10.内部类不能被覆盖
当继承了有内部类的外部类时,并重写内部类。这两个内部类是不同的,且没有任何关系,因为它们是不同的命名空间中内部类。所以重写的内部类没能覆盖原来的内部类。
11.局部内部类
局部内部类典型的方式时在方法体的内部类。
注意:局部内部类不能有访问修饰符,因为它不是外部类的一部分,但是它可以访问当前代码块的常量,以及外部类的所有成员。
如何使用局部类内部类和匿名内部类:当方法可以返回由不同构造器创建的内部类时,使用局部内部类。
12.内部类的标识符
由于每个类都会产生一个.class的文件,这个文件中包含如何创建该类型的对象的全部信息。这些信息又叫Class对象。
内部类也必须生成一个.class的文件以包含它们的Class对象的信息。其内部类的class文件命名规则:外部类名字$内部类的名字
当内部类是匿名内部类时,由于匿名内部类没有名字,编译器会自动生产一个数字来代替内部类的名字。
总结:内部类和接口实现了多重继承。

阅读全文
0 0