【问题标题】:What is the purpose of nested classes in Java?Java中嵌套类的目的是什么?
【发布时间】:2013-10-11 10:01:53
【问题描述】:

我从Oracle Website 看到了这个关于 Java 的示例代码?

public class Parent {
    class InnerClass {
        void methodInFirstLevel(int x) {
           // some code
        }
    }

    public static void main(String... args) {
        Parent parent = new Parent();
        Parent.InnerClass inner = parent.new InnerClass();
    }
}
  • 构造parent.new InnerClass()的目的是什么?
  • 什么样的类适合这种结构?

标题可能具有误导性:我了解这个结构的一切。

我只是不明白何时何地使用此 Java 功能。

我发现另一种语法可以做到这一点:Java: Non-static nested classes and instance.super()

有很多关于这个结构的参考资料,但没有关于应用程序的。

[参考文献]

【问题讨论】:

标签: java inner-classes nested-class


【解决方案1】:

parent.new InnerClass()的目的是什么?

这是为了演示 - 使用这种机制来构造内部类是很少见的。通常内部类只由外部类创建,当它像往常一样使用new InnerClass() 创建时。

什么样的类适合这种结构?

看看Map.Entry<K,V> 是一个经典的例子。在这里您可以看到一个名为Entry 的内部类,它应该由所有实现Map 的类创建。

【讨论】:

  • 示例中提供的结构要求在创建InnerClass 的实例之前创建Parent 的实例。我不明白与 Map.Entry 的链接?
  • @chepseskaf - 对于非静态内部类,每个内部类都有与其父级的连接,以便它可以访问父级的字段和方法,因此父级必须已经存在每个孩子都要依附。将Entry 类包含在Map 类中是有意义的,因为每种类型的Map 可能有不同类型的Entry
  • 我在@chepseskaf 旁边,我们完全不明白内部非静态类是什么以及它与父类的关系。我们无法弄清楚为什么有人会实例化一个 Parent 然后需要从 Parent 实例实例化一个 InnerClass。这与 Map.Entry 示例非常不同。什么用例需要这样的技术?
  • @Pigelvy - 主要用于演示。我不记得在现实生活中需要这样做。
【解决方案2】:

我在这里看到很多解释内部类使用的答案,但据我所知,问题是关于特定构造 parent.new InnerClass()

这种语法的原因很简单:内部类的实例必须属于周围类的实例。但是由于main是一个静态方法,所以没有环绕Parent对象。因此,您必须明确指定该对象。

public static void main(String[] args) {
    // this results in an error:
    // no enclosing instance of type Parent is available
    InnterClass inner = new InnerClass();

    // this works because you specify the surrounding object
    Parent parent = new Parent();
    InnerClass inner = parent.new InnerClass();     
}

我正在标准包中搜索此构造的用法,但到目前为止我还没有找到示例。

【讨论】:

  • 您似乎理解了这个问题,但您的答案完全是关于技术本身,而不是该技术的针对性/用途。
  • @Pigelvy 你是对的。原因是我看不到这种语法的用途。没有它,我想出的每一个例子都可以更容易解决......
【解决方案3】:

内部类嵌套在其他类中。普通类是包的直接成员,是顶级类。 Java 1.1 中提供的内部类有四种风格:

  • 静态成员类
  • 会员课程
  • 本地类
  • 匿名类

内部类最重要的特性是它允许您将通常不会变成对象的事物变成对象。与没有内部类的情况相比,这使您的代码更加面向对象。

public class DataStructure {
    // create an array
    private final static int SIZE = 15;
    private int[] arrayOfInts = new int[SIZE];

    public DataStructure() {
        // fill the array with ascending integer values
        for (int i = 0; i < SIZE; i++) {
            arrayOfInts[i] = i;
        }
    }

    public void printEven() {
        // print out values of even indices of the array
        InnerEvenIterator iterator = this.new InnerEvenIterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.getNext() + " ");
        }
    }

    // inner class implements the Iterator pattern
    private class InnerEvenIterator {
        // start stepping through the array from the beginning
        private int next = 0;

        public boolean hasNext() {
            // check if a current element is the last in the array
            return (next <= SIZE - 1);
        }

        public int getNext() {
            // record a value of an even index of the array
            int retValue = arrayOfInts[next];
            //get the next even element
            next += 2;
            return retValue;
        }
    }

    public static void main(String s[]) {
        // fill the array with integer values and print out only
        // values of even indices
        DataStructure ds = new DataStructure();
        ds.printEven();
    }
}

【讨论】:

  • 这句话“允许你把东西变成你通常不会变成对象的东西”对我来说没有多大意义。
  • 请看我的编辑,用一个例子完美地说明这句话
  • 我不明白这如何说明这句话;有人可能想知道是否需要和想要在这里创建一个迭代器。
猜你喜欢
  • 1970-01-01
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-02
  • 2014-02-19
相关资源
最近更新 更多