为什么需要内部类?内部类的好处?
- 内部类可访问其所在作用域(外部类)中的数据,包括私有数据
- 内部类可以对同一个包中的其他类隐藏起来
- 当想要定义一个回调函数且不想编写大量代码时,使用匿名 (anonymous) 内部类比较便捷
- 内部类可实现访问控制,只有其所在的外部类可访问其数据
- 内部类的对象总有一个隐式引用, 它指向了创建它的外部类对象,因此既可以访问自身的数据域,也可以访问创建它的外围类对象的数据域.
有哪些内部类?
- 局部内部类
- 静态内部类
- 匿名内部类
内部类特殊语法规则
- 内部类中声明的所有静态域都必须是 final。原因很简单。我们希望一个静态域只有一个实例, 不过对于每个外部对象,会分别有一个单独的内部类实例。如果这个域不是 final, 它可能就不是唯一的
- 在外围类的作用域之外,可以这样引用内部类:OuterClass.InnerClass
- 只有内部类可以声明为private和stiaic
- 非静态内部类不能有静态域和静态方法。静态内部类仅能访问其外部类的静态域和静态方法
局部内部类
- 当创建的内部类只在某一方法中使用一次的情况下,可以在方法中定义局部类
- 局部类不能用 public 或 private 访问说明符进行声明,它的作用域被限定在声明这个局部类的块中。(在 JavaSE 8 之前, 必须把从局部类访问的局部变量声明为 final。)
- 局部类有一个优势, 即对外部世界可以完全地隐藏起来,即使是此方法所在的外部类也不能访问它
匿名内部类
- 将局部内部类的使用再深人一步。 假如只创建这个类的一个对象,就不必命名了。这种类被称为匿名内部类
- 由于构造器的名字必须与类名相同, 而匿名类没有类名, 所以, 匿名类不能有构造器。取而代之的是,将构造器参数传递给超类 (superclass) 构造器。尤其是在内部类实现接口的时候, 不能有任何构造参数
- Java 程序员习惯的做法是用匿名内部类实现事件监听器和其他回调。 java8开始,可使用lambda表达式简化匿名内部类
- 双括号初始化技巧如下,这里利用了内部类语法
ArrayList<String> friends = new ArrayListoO;
friends,add("Harry");
friends,add("Tony");
invite(friends);
/*如果不再需要这个数组列表, 最好让它作为一个匿名列表。不过作为一个匿名列表,该如何为它添加元素呢? 方法如下:*/
invite(new ArrayList<String>(){{ add("Harry"); add("Tony"); }});
//注意这里的双括号。 外层括号建立了 ArrayList 的一个匿名子类。 内层括号则是一个对象构造块
静态内部类
- 有时候, 使用内部类只是为了把一个类隐藏在另外一个类的内部,并不需要内部类引用外围类对象。为此,可以将内部类声明为 static, 以便取消产生的引用。( 在内部类不需要访问外围类对象的时候, 应该使用静态内部类。 有些程序员用嵌套类表示静态内部类)
- 与常规内部类不同,静态内部类可以有静态域和方法。
- 声明在接口中的内部类自动成为 static 和 public 类。
网友评论