gpt4 book ai didi

scala - 理解抽象方法重写具体方法时的逻辑

转载 作者:行者123 更新时间:2023-12-04 04:01:31 25 4
gpt4 key购买 nike

首先,我意识到用子类中的抽象方法覆盖父类(super class)中的具体方法没有多大意义。但是...因为在 Scala 中实际上可以做到这一点,所以我尝试了以下代码片段,结果让我感到困惑。

第一个场景

  • 超父类(super class)中要重写的具体方法
  • 抽象方法在父类(super class)中
class A {
def x: String = "A"
}

abstract class B extends A {
def x: String
}

class C extends B {
def x: String = "C"
}

在 scala REPL 中执行上面的代码片段会导致以下错误:

  def x: String = "C"
^
<pastie>:10: error: `override` modifier required to override concrete member:
def x: String (defined in class A)

现在的问题是:为什么类 B 中的抽象方法似乎被忽略了?但如果从定义中删除 C.xB.x 实际上会产生影响。因为以下代码段也无法编译。

class A {
def x: String = "A"
}

abstract class B extends A {
def x: String
}

class C extends B

导致如下错误

class C extends B
^
<pastie>:9: error: class C needs to be abstract. No implementation found in a subclass for deferred declaration
def x: String (defined in class B)

第二种情况

  • 要在父类(super class)中重写的具体方法
  • 抽象方法在trait中
class A {
def x: String = "A"
}

trait B {
def x: String
}

class C extends A with B

尝试实例化C,

scala> (new C).x
val res0: String = A

看起来 B.x 抽象方法刚刚被编译器忽略了。


更新

在我的问题的第一版中,我愚蠢地忘记了在第二种情况中扩展A,这导致了一个错误的结论,即类和特征在我的行为中表现不同例子。对于我的疏忽,我深表歉意。

让我试着改一下我的问题:

在第一种和第二种情况下,类层次结构中间的抽象B.x有什么作用?

据我了解,通过继承和方法解析顺序(MRO),

  • 在第一个场景中,B.x 覆盖了 A.xC.x 覆盖了 B.x。由于B.x是抽象的,当C.x实现B.x时,不需要指定override修饰符。
  • 在第二种情况下,B.x 覆盖了A.x 并且C 没有实现抽象的B.x。所以C应该是抽象的,不编译。

但在我看来,编译器只是忽略了类层次结构中间的抽象方法 B.x 。这种行为是在语言规范的某处定义的,还是完全出乎意料和意外的(并且只是一个编译器错误)?

最佳答案

我不确定问题是关于 Traits 和 Abstract Classes 之间的区别还是关于 extends 之间的区别。

第一个场景中,您在这两种情况下都有abstract class B extends A,但在Second Scenario中,您有trait A 性状 BB 没有扩展 A。事实上,如果您将 trait A extends B 放在 Second Scenario 中,它不会编译

第二个场景的第二种情况下,您正在扩展 2 个具有相同方法的不同特征,extends A with B 您的类定义了方法 x因为当您从多个特征扩展时,顺序很重要。如果您尝试以相反的顺序 extends B with A,它将无法编译

换句话说:

第二种情况 - 第一种情况:定义抽象方法不需要覆盖

第二种情况 - 第二种情况:C extends A with B 不同于 B extends A + C extends B

关于scala - 理解抽象方法重写具体方法时的逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62992990/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com