【问题标题】:how to inherit Constructor from super class to sub class如何将构造函数从超类继承到子类
【发布时间】:2011-01-20 03:51:15
【问题描述】:

如何将构造函数从超类继承到子类?

【问题讨论】:

    标签: java inheritance constructor superclass


    【解决方案1】:

    构造函数不是继承的,您必须在子类中创建一个新的、原型相同的构造函数,该构造函数映射到其在超类中的匹配构造函数。

    这是一个如何工作的示例:

    class Foo {
        Foo(String str) { }
    }
    
    class Bar extends Foo {
        Bar(String str) {
            // Here I am explicitly calling the superclass 
            // constructor - since constructors are not inherited
            // you must chain them like this.
            super(str);
        }
    }
    

    【讨论】:

    • 即使作为非 n00b Java 程序员,我也不清楚。你能澄清一下吗?
    • @Bears 会吃掉你:如果父类有这样的构造函数:public Class(String arg1) { /* implementation here /* },那么子类需要这样的构造函数:public Subclass(String arg1) { super(arg1); }
    • 这听起来像是在说“在子类的构造函数中使用super”。我不知道 Java 中的构造函数原型是什么。
    • 我相信“构造函数原型”,安德鲁指的是构造函数签名。但是,答案不一定正确(或者至少不是很清楚)——您不必声明具有相同签名的构造函数,并且没有太多意义,因为客户端代码必须引用无论如何都要到新的子类。如果您想调用底层构造函数,用户只需调用 super(/* parameter list */),并为其提供参数所需的任何值。 (这就是我试图用下面的答案来表达的观点,至少......)
    • 如何在 Eclipse 中自动执行此操作?当您创建一个新类时,Eclipse 可以自动为您编写超级构造函数定义。但是,在您创建了该类并忘记选中该框以告诉 Eclipse 执行此操作之后呢?有什么办法吗?
    【解决方案2】:

    超类构造函数不能在扩展类中继承。虽然它可以在扩展类构造函数中以 super() 作为第一条语句来调用。

    【讨论】:

    • 是的......或者您可以调用您想要使用的超类构造函数的任何变体(它可能没有参数,正如@GoodManish 所说,或者它可能有更多)。在某些情况下,编译器会在执行任何构造函数的其余部分之前显式调用super();
    【解决方案3】:

    默认构造函数——没有参数的公共构造函数(无论是声明的还是隐含的)——默认被继承。您可以尝试以下代码作为示例:

    public class CtorTest {
        public static void main(String[] args) {
            final Sub sub = new Sub();
            System.err.println("Finished.");
        }
    
        private static class Base {
            public Base() {
                System.err.println("In Base ctor");
            }
        }
    
        private static class Sub extends Base {
            public Sub() {
                System.err.println("In Sub ctor");
            }
        }
    }
    

    如果你想显式调用超类的构造函数,你需要这样做:

    public class Ctor2Test {
        public static void main(String[] args) {
            final Sub sub = new Sub();
            System.err.println("Finished.");
        }
    
        private static class Base {
            public Base() {
                System.err.println("In Base ctor");
            }
    
            public Base(final String toPrint) {
                System.err.println("In Base ctor.  To Print: " + toPrint);
            }
        }
    
        private static class Sub extends Base {
            public Sub() {
                super("Hello World!");
                System.err.println("In Sub ctor");
            }
        }
    }
    

    唯一需要注意的是 super() 调用必须作为构造函数的第一行,否则编译器会生你的气。

    【讨论】:

    • 默认构造函数实际上不是“继承的”。如果超类中存在公共无参数(AKA 默认)构造函数且未在子类中显式定义,并且如果子类也没有任何显式定义的重载构造函数(即带参数的构造函数),则编译器将自动将只包含super(); 的公共无参数构造函数插入到子类中。这会调用超类的默认构造函数。
    【解决方案4】:

    阅读super keyword(向下滚动子类构造函数)。如果我理解您的问题,您可能想调用超类构造函数?

    值得注意的是,如果您没有显式调用超类构造函数,Java 编译器将自动对超类进行无参数构造函数调用。

    【讨论】:

      【解决方案5】:

      如果你有的话就说

      /**
       * 
       */
      public KKSSocket(final KKSApp app, final String name) {
          this.app = app;
          this.name = name;
          ...
      }
      

      然后一个名为 KKSUDPSocket 的子类扩展 KKSSocket 可以有:

      /**
       * @param app
       * @param path
       * @param remoteAddr
       */
      public KKSUDPSocket(KKSApp app, String path, KKSAddress remoteAddr) {
          super(app, path, remoteAddr);
      }
      

      /**
       * @param app
       * @param path
       */
      public KKSUDPSocket(KKSApp app, String path) {
          super(app, path);
      }
      

      您只需将参数沿构造函数链向上传递,就像对超类的方法调用一样,但是使用 super(...) 引用超类构造函数并传入给定的参数。

      【讨论】:

        【解决方案6】:

        你继承类属性,而不是类构造函数。事情就是这样:

        如果超类中没有添加构造函数,如果没有,则编译器添加一个无参数构造函数。每当创建子类的新实例时,都会隐式调用此默认构造函数。这里子类可能有也可能没有构造函数,一切正常。

        如果超类中提供了构造函数,编译器会判断它是无参构造函数还是带参数构造函数。

        如果没有参数,那么编译器将为任何子类实例化调用它。这里的子类也可能有也可能没有构造函数,一切正常。

        如果父类中的 1 个或多个构造函数具有参数并且不存在 args 构造函数,则子类必须具有至少 1 个构造函数,其中通过 super (parent_contractor params) 对父类构造进行隐式调用。

        这样你就可以确保继承的类属性总是被实例化。

        【讨论】:

        • " 编译器将为任何子类实例化调用它" - 上面的观点似乎是,如果你的子类有一个无参数的构造函数,你必须显式调用 super()。
        猜你喜欢
        • 1970-01-01
        • 2018-06-06
        • 1970-01-01
        • 2012-10-16
        • 1970-01-01
        • 1970-01-01
        • 2015-06-01
        • 2018-12-22
        • 2015-03-21
        相关资源
        最近更新 更多