包含X.Y.Z的封闭实例是必需的

时间:2012-07-24 23:25:46

标签: java class netbeans abstract-class instantiation

我希望有人可以帮助我。我一直在研究这个问题几个小时,似乎没有其他人有同样的问题(我遇到过)。我必须犯一些真正的傻瓜错误。

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

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

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

Student student = new Student();

Netbeans Student is abstract; can't be instantiated。好的,很好,我理解为什么抽象类无法实例化。然后我试试这个:

Student.Graduate student = new Graduate();

Netbeans an enclosing instance that contains studentmanager.Student.Graduate is required(studentmanager是我的包名)。我无法弄清楚这意味着什么。但是,我确实发现我可以像这样实例化学生而不会出错:

Student[] student = new Student[1];

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

student[0] = new Graduate();

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

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

感谢。

2 个答案:

答案 0 :(得分:7)

您是否将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

请注意,在此示例中,这不太可能是您想要的。拥有内部类的实例通常很有用,可以直接修改它们的封闭实例的字段,以便更新响应回调的封闭类的状态,但我怀疑这不是你的意图。

答案 1 :(得分:1)

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

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

或将毕业生转移到自己的Graduate.java文件中,可以让你做到

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

否则,如Mike D建议的那样,改变你实例化这些类的方式。