【问题标题】:how to force method to be implemented in concrete subclass from trait如何强制方法在特征的具体子类中实现
【发布时间】:2023-03-13 16:01:01
【问题描述】:

我的特质中有一个方法

def controller: AnyRef

但我的具体类没有实现该方法,它仍在编译。编译器也不允许我向该方法添加抽象。如何在 trait 中创建一个方法来强制它的实现者实现它?

谢谢, 院长

【问题讨论】:

  • 该类是否扩展了您的特征抽象?
  • 是的,我想通了。在具体的子类中,有一个 val controller = new Controller,当这种情况发生时,由于某种原因,在 trait 方法中调用 controller 最终返回 null。我在下面添加了真正的答案(但随后有一个关于它为什么编译的新问题)

标签: scala scala-2.9


【解决方案1】:

编译器强制具体类实现它们从超类和特征继承的所有抽象方法。

如果您的类正在编译,则意味着它不是具体的,即它是 traitabstract class,您不能强制两者都实现抽象方法。

当然,一旦您尝试获取具体实例,编译器就会引发错误,因为该方法未实现。

REPL 中的实际例子

scala> trait A { def controller: AnyRef }
defined trait A

scala> trait B extends A
defined trait B

scala> abstract class C extends A
defined class C

scala> class D extends A
<console>:8: error: class D needs to be abstract, since method controller in trait A of type => AnyRef is not defined
       class D extends A

scala> new B { }
<console>:10: error: object creation impossible, since method controller in trait A of type => AnyRef is not defined
              new B { }
                  ^

scala> new C
<console>:10: error: class C is abstract; cannot be instantiated
              new C

【讨论】:

  • 啊,我可以发誓我已经用抽象方法编译并运行它,但在我的情况下它返回 null 但由于某种原因,今天我无法重现它:(。
  • 我现在可以复制它了。在具体的子类中有一个 val controller = new TheController() ,在这种情况下,当你在这种情况下调用控制器时,特征最终返回 null 。这似乎是一个 scala 错误或其他东西。
  • 可能是初始化顺序问题。您应该针对该特定问题打开一个新问题,并提供最少的可重现示例
【解决方案2】:

如果您在这种情况下没有收到任何编译错误,我认为您的 IDE 有问题,请尝试刷新/清理您的项目。

如果你的 trait 实现了“控制器”功能,那么扩展 trait 的具体类(非抽象类)需要有任何“控制器”功能的实现。这就是 Scala 中的 特征之美,而不是强制所有具体类实现一些具有相同实现的通用方法。

【讨论】:

  • 结果是如果你有 val controller= new Controller 的具体子类,它会编译!!!更糟糕的是,它返回 null 而不是控制器。
【解决方案3】:

好吧,似乎发生了一些奇怪的 scala 问题。

当你有一个具体的子类有一个

val controller = new Controller

它似乎会影响特征控制器,并且让您的特征调用控制器会导致返回 null。一切都编译得很好(尽管我认为这可能是一个 scala 错误,因为我不“认为”应该实际编译)。

如果它应该编译,那么有人可以解释它为什么编译。

【讨论】:

    猜你喜欢
    • 2013-10-31
    • 2010-12-18
    • 1970-01-01
    • 2013-07-07
    • 2015-09-19
    • 2019-07-09
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    相关资源
    最近更新 更多