代码之家  ›  专栏  ›  技术社区  ›  user826955

在子类实例化中使用可选的超类构造函数

  •  1
  • user826955  · 技术社区  · 6 年前

    我有一个具有两个构造函数的基类,以及一个具有一个构造函数的子类。是否可以使用第二个基类构造函数实例化子类?

    示例代码:

    abstract class RuleCondition(rule:Rule, field:String, equal:Boolean, inverted:Boolean)
    {
      // alternate constructor with RuleValue instead of static comparation value
    
      def this(rule:Rule, field:String, ref:RuleValue, equal:Boolean = false, inverted:Boolean = false) = ???
     }
    
    class RuleConditionAbove(rule:Rule, field:String, comparationValue:Long, equal:Boolean = false, inverted:Boolean = false)
      extends RuleCondition(rule, field, equal, inverted)
    {
        // ...
    }
    

    现在我可以这样做了:

    val myAboveCondition = new RuleConditionAbove(rule, "bla", 10, true, false)
    

    但我不能这样做:

    val myAboveCondition = new RuleConditionAbove(rule, "bla", RuleValue(...), true, false)
    

    因为 RuleCondition 基类不可见。它 添加到子类后可见:

    def this(rule:Rule, field:String, ref:RuleValue, equal:Boolean = false, inverted:Boolean = false) = this(rule, field, ref, equal, inverted)
    

    这是解决此问题的唯一/常见方法,还是有更聪明的方法,涉及更少的复制和过去的代码?(因为我有很多相同模式的儿童班)

    [编辑]澄清,第二个构造函数 在每个子类中都是相同的,因此我希望它在基类中只实现一次。 然而,仍然必须在每个子类中放置另一个构造函数会以某种方式破坏这个目的,因此我不会在基类中有两个构造函数,而是只在所有子类中有。

    2 回复  |  直到 6 年前
        1
  •  4
  •   Tim    6 年前

    是否可以使用[second]基类构造函数来声明子类?

    不。

    不能使用超类构造函数创建子类的实例。必须为正在创建的类调用构造函数。子类构造函数必须为超类调用一个构造函数,但不能直接调用它。

    所以你能这么做的原因

    val myAboveCondition = new RuleConditionAbove(rule, "bla", 10, true, false)
    

    那是 RuleConditionAbove 有一个带有这些参数的构造函数。这与事实无关 RuleCondition 具有具有相同参数的构造函数。

    你不能这样做的原因

    val myAboveCondition = new RuleConditionAbove(rule, "bla", RuleValue(...), true, false)
    

    那是 以上规则条件 没有具有这些参数的构造函数。

        2
  •  0
  •   Ivan Stanislavciuc    6 年前

    如您所描述的,您必须在每个子类中添加一个构造函数定义。

    def this(rule:Rule, field:String, ref:RuleValue, equal:Boolean = false, inverted:Boolean = false) = this(rule, field, ref, equal, inverted)
    

    假设子类定义了基类中不可用的新字段。使用基构造函数创建子类不会定义此类字段,并且会使类的实例部分初始化。

    如果您的基本构造函数具有有价值的逻辑,那么将其保留在基类中是有意义的。只需将其“链接”到子类中的基本构造函数。