【问题标题】:Calling Constructor from another Constructor从另一个构造函数调用构造函数
【发布时间】:2011-03-24 13:05:41
【问题描述】:

我想做这样的事情

public class Class1
    {
       public Class1()
       {

       }
       public Class1(int a)
       {

       }
    }
   public class Class2 :Class1
    {
       public Class2(int a)
       {

       }
       public Class2(): base(2)
       {
         this(2);   // new Class2(2);
       }

    }

我知道这在 Java 中无法实现(可以在第一行中使用介于 (super 或 this) 之间的一个)

但不知何故我需要这种工作如何实现呢?表示在派生类的默认构造函数中调用基类的参数化和派生类的参数化构造函数。

【问题讨论】:

    标签: c# java oop


    【解决方案1】:

    MSDN article 在构造函数上非常好。以下是一些相关位:

    构造函数可以使用 base 关键字 调用基的构造函数 上课。
    ....
    构造函数可以调用另一个 同一对象中的构造函数使用 this 关键字。像base一样,这可以 可带或不带参数使用, 以及构造函数中的任何参数 可用作此参数, 或作为表达式的一部分。

    这应该可行:

    public class Class1
    {
       public Class1()
       {
    
       }
       public Class1(int a)
       {
    
       }
    }
    public class Class2 :Class1
    {
       public Class2(int a) : base(a)
       {
    
       }
       public Class2(): this(2)
       {
       }
    
    }
    

    【讨论】:

    • 我在这里看到的唯一可能的问题是,如果您想要Class2(int a) : base(a),但确实想要Class2() : base(2)。但是,我想不出这样的决定是最佳设计的类结构。
    • 我知道,但是我想在派生类的默认构造函数中执行其中两个,即我想执行基类的参数化构造函数以及通过派生类的默认构造函数派生的构造函数(可以写在定义中的某处)
    • 对,你不能这样做,你只能调用另一个构造函数,不能同时调用。我认为您应该重新考虑需要以这种方式调用构造函数的设计。
    • 这就是我想知道的,如果我们能以某种方式做到这一点,如果你能让我更好地理解,那么为什么在 JAVA 和 C# 中都没有给出这种类型的东西。就像我们可以使用类似 public Class2(int a) : base(a) 但不能用于定义派生类的默认构造函数
    【解决方案2】:

    Igor 的回答是在这种情况下应该如何编写构造函数的一个很好的例子。为了解决最后一句话的更一般情况:您不能链接到多个构造函数。您不能在当前类中调用基础构造函数另一个构造函数。

    重载构造函数有两种典型的模式。在第一个模式中,派生类的重载集与基类的重载集大致匹配——你试图让派生类感觉它有效地继承了构造函数。 (构造函数本身不是继承的,但如果您提供相同的签名,那么调用者会觉得是这样。)当您的派生类不需要额外信息时,通常会出现这种情况。当然,每个构造函数可以有额外的参数,并且只将一个子集传递给基本构造函数,但这可能会开始变得复杂。

    在第二种模式中,派生类中有多个构造函数,每个构造函数都调用同一个(派生)类中的“主”构造函数。这个主构造函数具有最多的参数,因为它需要能够处理任何其他构造函数指定的所有内容。有时主构造函数应该是私有的,如果某些组合没有意义,但是当您知道只能通过合理的公共构造函数访问代码时,可以方便地在一个地方指定。在这种情况下,只有“主”构造函数直接链接到基类构造函数。这通常在派生类具有超出基类所需的几条额外信息时使用。

    存在这种模式的混合体,其中您有多个主控,其中“组”重载调用主控...但我建议您尽可能保持简单。还要考虑提供静态工厂方法而不是构造函数的可能性——这最终会产生更具可读性的代码,因为你可以通过它们的目的/参数来命名方法——例如,参见TimeSpan.FromMinutes

    【讨论】:

      【解决方案3】:

      这在两种语言中都是不可能的(有充分的理由)。否则,如果没有显式基数或 this,由于隐式基数调用,您将多次调用基数构造函数。这可能会导致不良行为。

      【讨论】:

      • 这对我来说也不错。但是,如果我们将更多时间称为相同的基础构造函数,会有什么害处
      • 构造函数应该只运行一次。如果它只是像设置默认变量这样简单的初始化没有问题(除了性能,因为您执行了两次任务)但是如果您要在构造函数中填充一个列表,那么您将拥有所有条目两次。我认为有更好的理由,对我来说只是感觉不安全。也许有人可以提供一个更好的例子?
      【解决方案4】:

      编写多个构造函数,一个Init()方法

      在每个构造函数中,您可以编写任何需要执行的代码,然后再将其传递给 Init 方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-15
        • 1970-01-01
        • 2014-03-12
        • 1970-01-01
        • 2015-07-02
        • 2012-06-22
        • 2016-07-03
        相关资源
        最近更新 更多