1

Java不允许多重继承,这意味着一个类不能从两个没有共同点的类继承,这意味着它们不在同一继承路径上。但是,如果这些类是该类的直接超类的超类,则一个类可以继承自更多类。但是该类间接地从这些类继承,这意味着它不会从这些上层超类中“看到”任何东西,对吧?在考虑构造函数时我很困惑(在构造函数中使用 super() )。例如,如果我们有以下类:

public class A {
    public A() { 
      .... 
    }
}

public class B extends A {
    public B() {
      super();
      ....
    }
}

public class C extends B {
    public C() {
      super();
      ....
   }
}

C 类的构造函数首先使用 super() 调用 B 类的构造函数。发生这种情况时,B 的构造函数本身首先调用 A 的构造函数(使用 super()),但是 C 的构造函数对 A 的构造函数一无所知,对吧?我的意思是,继承仅来自直接超类——继承层次结构中的第一个(最近的)类。这是我的问题——对于 super(),我们仅指直接超类的构造函数,无论继承层次结构中有多少其他类。这不仅适用于构造函数,还适用于任何方法和实例变量。

问候

4

5 回答 5

4

您必须在直接基类中调用一些构造函数。这可以是

public class A {
     public A() { 
      .... 
     }
    public A(String foo) { 
      .... 
    }
}

public class B extends A {
    public B() {
        super();
        .. or ..
        super("ThisIsAB")
    }
}

public class C extends B {
    public C() {
      super();
      ....
   }
}

因此,对于构造函数,您不能避免构造中间基类,但您可以选择使用哪个构造函数。如果只有 no-args 构造函数,它会通过对 super 的隐式调用为您处理。使用多个构造函数,您有更多选择。

super 可以引用任何基类中的任何非私有变量或方法。所以方法和变量在这方面和构造函数是不一样的。

于 2009-01-06T20:37:51.503 回答
4

即使您可以避免调用中间 ctor,您也不希望这样做,因为这意味着您有未初始化的中间类片段,这些片段可能会被最底层的派生类访问。到可怕的影响。

但我感觉到您正试图在 Java 中欺骗您的方式来进行多重继承。那是一件坏事。相反,您可以通过使用接口以 Java 方式执行此操作

class B extends A implements C {
    // ... implement C methods here
}

或通过使用聚合

class B extends A {
    private C c;
}
于 2009-01-06T20:49:57.733 回答
3

调用所有父母的构造函数。事实上,C 深知 A 是因为 B 扩展了 A。例如,如果类 A 包含方法 foo(),那么您可以从 C 调用 foo()。

因此,从您的示例中,C 从 B 调用构造函数,它从 A 调用构造函数。此外,A 还从类 Object 扩展。所以Object类中的构造函数也被调用了!

此外,您不需要添加对 super() 的调用。如果没有调用父级的构造函数,则隐式调用 super。

于 2009-01-06T20:39:26.867 回答
2

正如您所说,C 的构造函数调用 B 的构造函数,该构造函数调用 A 的构造函数。您可以在 C 对象上调用任何“A”方法,并且 C 对象可以看到 A 中的非私有字段。

即使您在 C 中覆盖 A 的方法“foo”,您也可以使用“super.foo()”获得 A 版本,假设 B 也不会覆盖它。

于 2009-01-06T20:33:20.623 回答
1

据 C 所知,它在 C 中未覆盖的任何内容都包含在 B 中,即使在幕后 A 可能是实现的地方。

public class A {
   public A() {
   }

   public void aMethod() {
   }
}

public class B extends A {
   public B() {
     super();
   }
}

public class C extends B {
   public C() {
     super();
   }

   public void doWork() {
     super.aMethod();
   }
}

所以在这种情况下,A 处理 aMethod() 的实现,即使在 C 的构造函数中调用 super() 直接调用 B 的构造函数,而不是 A 的构造函数。

于 2009-01-06T20:44:17.073 回答