【问题标题】:scala traits case classes and inheritancescala 特征案例类和继承
【发布时间】:2018-06-02 20:27:18
【问题描述】:

在 scala 中定义案例类的类型层次结构时:

sealed trait FooBar {
  def A:Int
  def B:Int
  def C:Int
}

// works
final case class Bar(A:Int, B:Int, C:Int)extends FooBar

// fails
final case class Bar extends FooBar(A:Int, B:Int, C:Int)

// fails
final case class Foo extends FooBar

在定义继承类型时如何避免指定已经继承的参数?这是否可能没有任何宏:Scala case classes and constructors

抽象类是否更适合此目的?

【问题讨论】:

  • 小心,您的示例无法编译。密封特征声明中的 , 不是合法的 scala。
  • 抱歉 - 修复了示例。
  • 在您的任何情况下都没有“已经继承的参数”,因为FooBar 没有参数(并且特征永远不会有它们);它有 3 种方法,可以作为参数或任何其他方式实现。
  • 如果没有宏可能有人会建议它作为您所链接问题的答案。
  • 我认为问题出在这样一个事实,即您必须为 Bar 类的构造函数声明签名,并且类型名称后面的括号是您在 Scala 中这样做的位置(对于“主要”构造函数)。对于案例类,它也被重新用作字段声明的来源,但这是次要的。请注意,与方法不同,构造函数不会自动继承。除非您使用某些工具(如宏)为您生成构造函数 - 您无法避免将其签名显式放置到指定位置的需要。

标签: scala inheritance abstract-class traits case-class


【解决方案1】:

好吧,您声明的是具有三个抽象方法的特征。

您的第一个实现声明了一个具有 3 个值的案例类,这些值与FooBar 中声明的抽象方法相匹配。由于没有括号和值的方法在Scala中基本相同,因此可行。

您的第二个实现调用 FooBar 的构造函数,其中包含 3 个不存在的值。它从哪里得到A

您的第三个实现是声明一个不实现抽象方法且无法编译的具体类。

我不知道您所要求的(理智的)解决方案。您正在声明抽象方法并且不想实现它们。通过宏可能是可行的,但似乎需要做很多工作却没有太多好处。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    相关资源
    最近更新 更多