【问题标题】:an enclosing instance that contains X.Y.Z is required需要包含 X.Y.Z 的封闭实例
【发布时间】:2012-07-24 23:25:46
【问题描述】:

我希望有人可以帮助我。我已经研究这个问题几个小时了,似乎没有其他人遇到过同样的问题(我遇到过)。我一定是犯了一些非常愚蠢的错误。

我是Java的新手,设计了一个非常简单的Java程序。

我有一个名为 Student 的抽象超类。这个Student 超类有3 个扩展类,分别称为GraduateUndergraduatePartTime。 Student 类有几个抽象方法和几个非抽象方法。我已验证Students 中定义的所有抽象方法都已在所有 3 个扩展类中实现。

现在我正在尝试做一些应该非常简单的事情。我正在尝试实例化这些扩展类之一。如果我这样做:

Student student = new Student();

NetbeansStudent is abstract; can't be instantiated。好的,好的,我明白为什么不能实例化抽象类了。然后我试试这个:

Student.Graduate student = new Graduate();

Netbeansan enclosing instance that contains studentmanager.Student.Graduate is required(studentmanager 是我的包名)。我不明白那是什么意思。但是,我确实发现我可以像这样实例化 Student 而不会出错:

Student[] student = new Student[1];

但是,如果我尝试做下一个合乎逻辑的事情:

student[0] = new Graduate();

我得到同样的an enclosing instance... 错误。

底线是我想知道如何实例化Graduate。谁能帮我吗?任何见解将不胜感激!

谢谢。

【问题讨论】:

标签: java class netbeans abstract-class instantiation


【解决方案1】:

您是否将GraduateUndergraduatePartTime 定义为Student内部 类?也就是这样:

public class Student {
    /* ... */
    public class Graduate extends Student { /* ... */ }
    public class Undergraduate extends Student { /* ... */ }
    public class PartTime extends Student { /* ... */ }
}

内部类的实例具有对封闭类实例的隐式引用,因此它可以执行诸如访问封闭实例的私有字段和方法之类的事情。当您尝试实例化其中一个子类的实例时,编译器会说“嘿,等等,我不知道将隐式引用设置为什么!”并产生错误。

有三种可能的解决方案:

  • 您可以将三个子类从 Student 类移到它们自己的文件中定义的顶级类中。
  • 您可以在子类的声明前添加关键字static。这告诉编译器您不希望从内部类到封闭类的隐式引用。这将阻止您执行诸如从子类访问 Student 的私有字段和方法之类的操作,但如果您不需要这样做,那就没有实际意义了。
  • 如果您确实需要子类来访问Student 的私有成员,您可以创建Student 的实例,然后使用这种特殊语法创建内部类的实例。

    Student s = new Student();
    Graduate g = s.new Graduate();

本例中的s.new 告诉编译器Graduate 的新实例应该隐式引用s

请注意,在此示例中,这不太可能是您想要的。让内部类的实例可以直接修改其封闭实例的字段以执行诸如更新封闭类的状态以响应回调之类的操作通常很有用,但我怀疑这不是您的意图。

【讨论】:

  • 谢谢迈克!我确实将子类创建为 Student 的内部类,尽管 Student 是作为抽象创建的。一旦我将扩展类分离到它们自己的文件中,我现在就可以毫无问题地创建每个类的实例。
【解决方案2】:

如果您可以更改类定义,则内部类必须是静态的,以便在没有封闭实例的情况下支持实例化。例如

// in file Student.java
public class Student {
    public static class Graduate {}
}

或者将Graduate移到它自己的Graduate.java文件中,让你做

Student.Graduate grad = new Student.Graduate();

否则,请按照 Mike D 的建议更改实例化这些类的方式。

【讨论】:

  • 感谢您的进一步解释。这是有道理的。
猜你喜欢
  • 1970-01-01
  • 2011-05-16
  • 2011-11-28
  • 1970-01-01
  • 2013-12-26
  • 2012-11-20
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
相关资源
最近更新 更多