1

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

我是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();

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

Student[] student = new Student[1];

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

student[0] = new Graduate();

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

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

谢谢。

4

2 回答 2

8

您是否将GraduateUndergraduate和定义PartTime为 的内部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

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

于 2012-07-24T23:37:21.477 回答
1

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

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

或将研究生移动到它自己的研究生.java文件中,会让你做

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

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

于 2012-07-24T23:40:52.657 回答