使用超类的构造函数

发布于 2024-07-10 13:22:24 字数 675 浏览 8 评论 0原文

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() 我们只指直接超类的构造函数,无论继承层次结构中有多少其他类。 这不仅适用于构造函数,也适用于任何方法和实例变量。

问候

Java does not allow multiple inheritance, meaning that a class cannot inherit from two classes, which does not have anything in common, meaning that they are not on the same inheritance path. However, a class can inherit from more classes, if these classes are super classes of the direct super class of the class. But the class inherits from these classes indirectly, meaning that it does not "see" anything from these upper super classes, right? I was confused when considering constructors (using super() in the constructor). For example, if we have the following classes:

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

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

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

the constructor of class C invokes first the constructor of class B using super(). When this happens, the constructor of B itself invokes first the constructor of A (with super()), but the constructor of C does not know anything about the constructor of A, right? I mean, the inheritance is only from the direct super class - the first (nearest) class from the inheritance hierarchy. This is my question - with super() we mean only the constructor of the direct super class, no matter how many other classes we have in the inheritance hierarchy.
And this does not apply only for constructors, but for any methods and instance variables..

Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

始终不够 2024-07-17 13:22:24

您必须在直接基类中调用某个构造函数。 对于构造函数来说,

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();
      ....
   }
}

您不能避免构造中间基类,但您可以选择使用哪个构造函数。 如果只有无参数构造函数,则通过隐式调用 super 来为您处理所有内容。 有了多个构造函数,你就有了更多的选择。

super 可以引用任何基类中的任何非私有变量或方法。 因此,方法和变量在这方面与构造函数不同。

You have to invoke some constructor in your immediate base class. This can be

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();
      ....
   }
}

So for constructors you cannot AVOID constructing your intermediate base classes, but you can choose which constructor to use. If there is only the no-args constructor it's all handled for you with an implicit call to super. With multiple constructors you have some more choices.

super can refer to any non-private variable or method in any base class. So methods and variables are not the same as constructors in this respect.

意中人 2024-07-17 13:22:24

即使您可以避免调用中间构造函数,您也不会愿意这样做,因为这意味着您拥有中间类的未初始化部分,这些部分可能会被最底层的派生类访问。 造成可怕的影响。

但我感觉你正试图绕过 Java 来实现多重继承。 这是一件坏事。 相反,您可以通过使用接口

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

或使用聚合以Java 方式完成此操作

class B extends A {
    private C c;
}

Even if you could avoid calling the intermediate ctor, you wouldn't want to, because that would mean you had uninitialized pieces of the intermediate classes that might be acessed by the bottom-most derived class. To horrible effects.

But I sense that you're trying to trick your way around Java to do multiple inheritance. That is a Bad Thing. Instead, you can do it Java-wise by using an interface

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

or by using aggregation

class B extends A {
    private C c;
}
冷心人i 2024-07-17 13:22:24

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

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

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

Constructors for all parents are called. In fact, deep down C knows about A because B extends A. For example, if the class A contained method foo(), then you could call foo() from C.

So from your example, C calls the constructor from B, which calls the constructor from A. Additionnally, A also extends from the class Object. So the constructor in the class Object is also called!

Furthermore, you do not need to add a call to super(). If there is no call for the constructor of the parent, super is call implicitly.

南街九尾狐 2024-07-17 13:22:24

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

即使你在C中重写了A的方法“foo”,你也可以通过“super.foo( )”,假设 B 也没有覆盖它。

As you say, C's constructor invokes B's constructor which invokes A's constructor. You can call any "A" methods on a C object, and a C object can see non-private fields in A.

Even if you override A's method "foo" in C, you can get the A version with "super.foo()", assuming B doesn't also override it.

少女净妖师 2024-07-17 13:22:24

据 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 的构造函数。

As far as C knows, anything that it does not overwritten in C is contained in B, even if under the covers class A is where the implementation might be.

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();
   }
}

So in this case A handles the implementation of aMethod(), even though calling super() in C's constructor called B's constructor directly, not A's.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文