【问题标题】:using constructor from the super class使用超类的构造函数
【发布时间】:2010-09-29 21:36:43
【问题描述】:

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 inheritance constructor super


【解决方案1】:

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

即使你在 C 中重写了 A 的方法“foo”,你也可以使用“super.foo()”获得 A 版本,假设 B 也没有重写它。

【讨论】:

    【解决方案2】:

    你必须在你的直接基类中调用 some 构造函数。这个可以

    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 可以引用任何基类中的任何非私有变量或方法。所以方法和变量在这方面和构造函数是不一样的。

    【讨论】:

    • 我从来没有做过,但我认为如果你不使用“super”调用来启动你的ctor,它会为你调用默认的(无参数)构造函数。
    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        但我感觉您是在试图欺骗 Java 来进行多重继承。那是一件坏事。相反,您可以使用接口以 Java 方式完成

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

        或使用聚合

        class B extends A {
            private C c;
        }
        

        【讨论】:

        • 多重继承不一定是坏事——只是在 java 中不支持。在这样做的语言中,它允许诸如mixins之类的好东西-您可以在其中扩展类以将功能添加到自己的功能中,而无需工作。例如在 ruby​​ mixins juixe.com/techknow/index.php/2006/06/15/mixins-in-ruby
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-25
        • 2013-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多