在子类实例化中使用替代的超类构造函数

时间:2019-01-03 08:13:05

标签: scala inheritance constructor polymorphism superclass

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

示例代码:

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)

这将是解决此问题的唯一/常用方法,还是有一些更聪明的方法来减少复制和过去的代码? (因为我有大量相同样式的子类)

[edit]要澄清的是,第二个构造函数在每个子类中都应该是相同的,因此我希望在基类中仅实现一次。 但是,仍然必须在每个子类中放置另一个构造函数将以某种方式无法实现此目的,因此我在基类中不会只有两个构造器,而在所有子类中都没有。

2 个答案:

答案 0 :(得分:4)

  

是否可以使用[second]基类构造函数实例化子类?

否。

您永远不能使用超类构造函数来创建子类的实例。您必须为要创建的类调用构造函数。子类构造函数必须为超类调用构造函数,但是不能直接调用它。

所以您可以这样做的原因

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

RuleConditionAbove的构造函数带有这些参数。与RuleCondition的构造函数具有相同的参数无关。

以及您无法执行此操作的原因

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

RuleConditionAbove没有带有这些参数的构造函数。

答案 1 :(得分:0)

您必须按照说明在每个子类中添加一个构造函数定义。

isBackSpace = false;

onKeyDown(event:KeyboardEvent){
  this.isBackSpace = event.which === 8;
  /// rest of the method
}

onSearchChange(event){
  if (event.inputType === 'deleteContentForward' || event.inputType === 'deleteContentBackward' || this.IsBackSpace) {
    // delete event handling code.
  } else {
    // insert event handling code.
  }
  this.isBackSpace = false;
}

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

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