当前位置: 首页 > 知识库问答 >
问题:

从子类调用内部类的构造函数

赵镜
2023-03-14

我在班里学习。出于好奇,我扩展了具有参数化构造函数的内部类。但是当我编写super(inti)来调用它时,代码不会编译。

class Outer{
  class Inner{
    private int a;
    Inner(int i){
     this.a=i;
    }

    public void inheritFromInner(){
      System.out.println("Inherited from inner");
    }
  }       
}

class Test extends Outer.Inner{
  Test(int r){
   super(r);// This line does not compile.
  }
}

因为内部类是外部类的一部分(成员),必须通过外部类访问它们。如何调用测试类的超级构造函数。

编译错误是:由于某些中间构造函数调用,没有外部类型的封闭实例可用

共有3个答案

卞嘉许
2023-03-14

该错误实际上与特定代码行无关,也与超类构造函数接受参数无关。您可以使用更简单的示例再现错误:

class Outer {
    class Inner {
    }       
}

class Test extends Outer.Inner {
}

这将给出一个错误,例如:

Outer.java:6: error: an enclosing instance that contains Outer.Inner is required
class Test extends Outer.Inner {
^
1 error

有两种类型的内部类,非静态(默认)和静态(需要关键字static)。静态内部类与顶级类(始终是静态的)类似,但非静态内部类需要其封闭类的实例才能实例化。因为<代码>外部。内部是一个非静态的内部类,它只能在外部实例的“上下文”中实例化,这意味着外部实例方法的内部,或者通过如下代码进行实例化:

Outer outer = new Outer();
outer.new Inner();

(这种语法不常见。)

因为Test是一个顶级类,所以它是静态的,所以它不能子类一个非静态的内部类,因为当通过new Test()创建一个实例时,不会提供外层的实例。

但是请注意,此代码编译时不会出错:

class Outer {
    class Inner {
    }

    class Test extends Outer.Inner {
    }
}

在这种情况下,Test也是Outer的非静态内部类,因此必须在满足其超类要求的Outer实例的上下文中创建Test

当然,修改原始代码使其成为内部静态也将允许它进行编译。在实际代码中,创建非静态内部类是因为需要该类的实例才能访问封闭类的关联实例。在这种情况下,您没有将其设置为静态的选项。但是,如果它不需要这样的访问,那么您应该使内部类成为静态的(或者,使其成为顶级类)。

编辑:显然,可以创建非静态内部类的静态子类,方法是显式地将所需封闭类的实例作为构造函数参数传递给子类,并对其html" target="_blank">调用super()。请参见scottb的答案。

郭琨
2023-03-14

您需要将内部类声明为publicstatic

class Outer{
  public static class Inner{
    private int a;
    Inner(int i){
     this.a=i;
    }

    public void inheritFromInner(){
      System.out.println("Inherited from inner");
    }
  }       
}

class Test extends Outer.Inner{
  Test(int r){
   super(r);// This line does not compile.
  }
}
范京
2023-03-14

现有的答案并没有阐明不同类型的成员阶级之间的差异。

成员类是在另一个类中声明的任何类。它们有时被称为嵌套类。在成员类的种类中,匿名内部类和本地类在这里就不提了。剩下的成员类是内部类和静态成员类。

>

Outer out = new Outer();
Outer.Inner inner = out.new Inner();

因为Super()关键字必须是在子类构造函数中执行的第一行,所以如果构造函数确实需要在内部类中,则必须这样声明它:

class Test extends Outer.Inner{
    Test(Outer out, int r) {
        out.super(r);
    }
}

静态成员类。静态成员类在类声明中使用静态修饰符声明。在几乎所有重要的方面,静态成员类都是顶级类。与顶层类一样(与内部类不同),它们不需要任何其他对象实例来实例化。静态成员类对象通常被描述为:

Outer.Inner inner = new Outer.Inner();

只要有可能,您应该强烈支持使用静态成员类而不是内部类。仅当您的成员类对象确实必须具有超类实例(这应该不常见)时才使用内部类。

 类似资料:
  • 问题内容: 我正在尝试创建一个将字段作为参数的构造函数,然后将其放入存储在超类中的字段中。这是我正在使用的代码 在超类中,我用 我有一个访问器方法 我收到一个错误“ 味道在超类中具有私有访问权 ”,但是我认为这无关紧要,因为我正在调用将其返回到字段的访问器方法? 问题答案: 您应该做什么: 在您的超类中添加一个构造函数: 在Crisps类中: 注释 对您的问题的一些评论: “在超类中,我已经用”

  • 为什么第一个输出有柱线 = 空?是因为在创建类 B 之前调用了 B.foo() 吗?如果是,那么为什么可以调用 B.foo()?还是因为 B.foo() 中的字段栏试图从 A 获取柱线字段但无法访问它? 我的问题与链接的问题不同,我不是在问调用顺序,我是在问为什么第一个输出为空?另一个问题不是关于字段或空变量。 我不明白B.foo中的bar变量是如何为空的,如果它是在A和B中定义的。

  • 我有两个类:Date和Person Person有Date类的两个属性 案例1 类是与Person类分开的类。我有这段代码正常工作: 案例2:内部类(赋值要求) 我把作为Person的私有内部类 现在,上面的构造函数代码不再工作了。以下是错误消息: 说明资源路径位置类型由于某些中间构造函数调用人员,类型Person的封闭实例不可用。java/Wk03_Ch10_文件IO_Ch13_接口/Wk03_

  • 我有一个类,它有一些属性/方法,返回最初通过构造函数传递的值: 人们建议用泛型作为打字稿的等价物: 现在我有了一个子类,它调用超类的构造函数并传递以下选项: TypeScript编译器对此不满意,希望通过类型扩展Base类。但是我有两次信息,在超级呼叫和扩展符号中。什么是正确的ts语法来解决我的问题? (键入脚本中的代码)

  • 问题内容: 考虑以下代码 在我看来,目前有两种方法可以避免这种问题。 要么上A班最后一班。 要么 使getVar方法最终化 作者试图提出防止上述问题的方法。但是,该解决方案似乎很麻烦,因为要遵循一些规则。 http://benpryor.com/blog/2008/01/02/dont-call-subclass-methods-from-a- superclass-constructor/ 除了

  • 问题内容: 好的,所以我知道匿名内部类正在隐式扩展父类或实现接口,因此将需要调用超类的构造函数。但是,我不确定如何为匿名类创建一个构造函数(如果可能的话),并且在没有定义构造函数的情况下,我不确定如何对super()进行调用!这是我的练习代码: 我担心的是,如果您尝试从没有no- arg构造函数的类中创建一个匿名类,则该代码将在编译时失败,因为无法将参数传递给超构造函数。这是一个有效的问题吗?如果