前言
普通内部类(Non-static Inner Class,也称为成员内部类)是嵌套在其他类中的类,它不是静态的,普通内部类可以访问外部类的私有成员,因此可以用来隐藏外部类的实现细节,只暴露必要的接口给外部。
普通内部类在很多场景下都有用,以下是一些常见的应用场景:
- 事件处理:在图形用户界面(GUI)编程中,可以使用内部类来实现事件监听器。内部类可以轻松地访问外部类的控件和数据,以响应事件。
- 迭代器和集合类:内部类可用于实现迭代器,帮助遍历集合类中的元素。例如,Java中的
Iterator接口和ArrayList内部的Itr类就是这样实现的。 - 多重继承:内部类允许一个类在继承一个类的同时,还可以实现一个或多个接口,这种方式称为多重继承。
- 私有辅助类:有时候,外部类可能需要一个辅助类来完成某些任务,但这个辅助类对于外部世界来说并不需要可见性。在这种情况下,可以将辅助类定义为内部类。
使用示例
示例1:事件处理
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
public class MyButton {
private JButton button;
public MyButton() {
button = new JButton("Click Me");
button.addActionListener(new ButtonClickListener());
}
private class ButtonClickListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked!");
}
}
}
示例2:迭代器和集合类
import java.util.Iterator;
import java.util.List;
public class MyCollection<T> implements Iterable<T> {
private List<T> list;
public MyCollection(List<T> list) {
this.list = list;
}
@Override
public Iterator<T> iterator() {
return new MyIterator();
}
private class MyIterator implements Iterator<T> {
private int index = 0;
@Override
public boolean hasNext() {
return index < list.size();
}
@Override
public T next() {
return list.get(index++);
}
}
}
像ArrayList这种集合,类本身实现迭代器不行么,为什么非要使用内部类的方式呢?
- 内聚性:将迭代器作为内部类,将它们与
ArrayList类绑定在一起,增加了内聚性。这意味着迭代器与ArrayList之间的关系更紧密,使代码更具一致性和可维护性。 - 迭代器多样性:
ArrayList可以拥有多个不同类型的迭代器,而这些迭代器都可以实现相同的Iterator接口。这种多样性可以让客户端代码选择适合其需求的迭代器类型,而不必关心其具体实现。
示例3:多重继承
class Outer {
class Inner extends SuperClass implements Interface {
// ...
}
}
示例4:私有辅助类
class Outer {
private int data;
public void doSomething() {
Inner inner = new Inner();
inner.processData();
}
private class Inner {
void processData() {
// 可以访问外部类的私有数据和方法
data = 42;
// ...
}
}
}