内部类的定义:一个定义在另一个类中的类,叫做内部类。内部类是一种非常有用的特性,因为它允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可见性。然而必须要了解,内部类与组合是完全不同的概念,这一点很重要。在最初,内部类看起来就像是一种代码隐藏机制:将类置于其他类的内部。但是,你将会了解到,内部类远不止如此,它了解外部类,并能与之通信,而且你用内部类写出的代码更加更加优雅而清晰,尽管并不总是这样(而且Java8的Lambda表达式和方法引用减少了编写内部类的需求)。
成员内部类
成员内部类是最普通的内部类,它的定义是位于另外一个类的内部,如下所示:
1 | class Outer{ |
这里,类Outer被称为外部类,Inner就是我们通常称呼的成员内部类。成员内部类可以无条件访问外部类中的所有成员属性和成员方法(包括private成员和静态成员)。不过要注意的是当成员内部类出现和外部类相同名称的成员变量或方法时,默认使用的内部类中定义的成员变量或方法。如果要使用外部类中的属性和方法,可以通过以下方式访问:
1 | 外部类.this.成员变量 |
在外部类中如果想要访问内部类中的成员变量或方法,必须创建一个成员内部类对象,再通过指向这个对象的引用来访问。
成员内部类是依靠外部类而存在的,所以说要想生成成员内部类的对象,必须先创建外部类对象。
1 | public class Main { |
内部类可以拥有private访问权限、protext访问权限、public访问权限以及包访问权限。而外部类只能被public和包访问两种权限修饰。
局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它与成员内部类的区别在于局部内部类的访问仅限于该方法内或该作用域内。
1 | class People { |
匿名内部类
匿名内部类的使用一般是用来编写事件监听代码。同样匿名内部类不能有访问修饰符和static修饰符。匿名内部类主要用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或重写。
静态内部类
静态内部类也是定义在另一个类里面的类,只不过在类名前面添加了static关键字,静态内部类是不需要依赖外部类的。并且它不能使用外部类的非static成员变量或方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员变量必须依赖于具体的对象。
1 | public class Main { |
闭包(closure)和回调
- 闭包的价值在于可以作为函数对象或者匿名函数,持有上下文数据,作为第一级对象进行传递和保存。
- 闭包广泛用于回调函数、函数式编程中。
Java中,闭包是通过“接口+内部类”实现,Java内部类也可以有匿名内部类。
闭包(closure)是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域。通过这个定义,可以看出内部类是面向对象的闭包,因为它不仅包含外部类对象(创建内部类的作用域)的信息,还自动拥有指向外部类对象的引用,在此作用域内,内部类有权操作所有的成员。
1 | class Writer{ |