我试图了解Java中内部类的需求。我正在阅读本书的作者,引用以下示例 -
内部类的一个特别重要的用途是制作适配器 类。适配器类是一个将一个类绑定到的“帮助器”类 另一个非常具体的方式。使用适配器类,您可以编写 你的课程更自然,而不必预测每一课 可预见的用户的需求提前。相反,您提供适配器 将您的类与特定接口结合的类。作为一个 例如,假设我们有一个EmployeeList对象:
public class EmployeeList {
private Employee [] employees = ... ;
...
}
EmployeeList包含有关一组员工的信息。假设我们希望EmployeeList通过提供其元素 迭代器。迭代器是序列的简单标准接口 对象java.util.Iterator接口有几个方法:
public interface Iterator {
boolean hasNext();
Object next();
void remove();
}
它让我们逐步介绍其元素,询问下一个元素并进行测试,看看是否还有更多元素。迭代器是一个很好的候选者 对于适配器类,因为它是我们的EmployeeList的接口 不能轻易实现自己。为什么列表不能实现 迭代器直接? 因为迭代器是“单向”,一次性视图 我们的数据。不打算重置并再次使用。它也可能 必须有多个迭代器遍历 列出不同的点。因此,我们必须保留迭代器 与EmployeeList本身分开的实现。这是在哭 out用于提供迭代器功能的简单类。但是什么 该课程应该是什么样的?在我们了解内部课程之前,我们的 唯一的办法就是建立一个新的“顶级”课程。我们 可能会觉得有必要称之为EmployeeListIterator: class EmployeeListIterator实现Iterator { //关于EmployeeList的大量知识 ... 这里我们有一个表示EmployeeListIterator所需机制的注释。想一想关于什么 你需要做的就是实现这个机器。由此产生的类 将完全耦合到EmployeeList并且在其他中无法使用 的情况。更糟糕的是,为了运作,它必须能够访问 EmployeeList的内部工作原理。我们必须允许 EmployeeListIterator访问EmployeeList中的私有数组, 比这应该更广泛地公开这些数据。这不到 理想的。
问题: 1)我不明白单程'一次性观点意味着它为何为内部阶级提供案例? EmployeeList类中的方法应该能够实现列表的单向导航,没有?
2)通过相同列表对象的多个迭代器似乎使迭代器成为一个类,所以我可以多次实例化它 - 但是,这对于下面的类X的一个实例是否意味着,我可以实例化多个Y级的实例?如果是这样,X的类定义并不清楚它有多个类型的成员(类Y) -
class X {
int x1;
class Y{ }
}
非常感谢任何指导!!!!
答案 0 :(得分:0)
类EmployeeList中的方法应该能够实现列表的单向导航,不是吗?
假设您需要适配器来实现接口,您可以使外部类实现接口,但现在您的方法没有完全分离。您有一些处理类原始意图的方法,以及一些适用于适配器的方法。当您的类实现多个接口时,它会变得更加混乱。
但是,这对于下面的X类的一个实例是否意味着,我可以实例化Y类的多个实例?
是的,您可以实例化Y的多个实例。代码中的class Y {}
定义它的外观,在您实例化之前它不代表class Y
的实例 - 您可以做多次。
class X {
private void myFunc() {
Y y0 = new Y();
Y y1 = new Y();
}
}
答案 1 :(得分:0)
假设列表直接提供该功能。这意味着当我开始迭代时,列表必须初始化一些状态以记住我在迭代中的位置(第一个元素,第二个元素等)。然后我决定停止迭代。列表如何知道?如果不调用一些stopIterating()
方法,它如何处理这个迭代状态?委托给一个单独的对象要容易得多:如果我停止迭代,我就会忘记保持迭代状态的迭代器。迭代器超出范围并被垃圾收集。
是的,当然。每次调用list.iterator()
时,都会返回迭代器的新实例。在外部类Inner
中声明内部类Outer
并不意味着外部类具有Inner类型的字段。它只是说必须使用new运算符创建的Inner类实例可以访问外部类的实例。外部类不与内部类实例保持任何关联。这与内部类是顶级类基本相同,类型为Outer的字段指向外部类实例。区别在于内部类可以访问外部类的所有私有成员,这对于顶级类是不可能的。