Scala 理解用抽象方法重写具体方法时的逻辑
首先,我意识到用子类中的抽象方法覆盖超类中的具体方法没有多大意义。但是因为在Scala中实际上可以做到这一点,所以我尝试了下面的代码片段,结果让我感到困惑 第一种情况Scala 理解用抽象方法重写具体方法时的逻辑,scala,Scala,首先,我意识到用子类中的抽象方法覆盖超类中的具体方法没有多大意义。但是因为在Scala中实际上可以做到这一点,所以我尝试了下面的代码片段,结果让我感到困惑 第一种情况 超类中要重写的具体方法 抽象方法在超类中 A类{ def x:String=“A” } 抽象类B扩展了{ def x:String } C类扩展到B类{ def x:String=“C” } 在scala REPL中执行上述代码段会导致以下错误: def x: String = "C" ^
- 超类中要重写的具体方法
- 抽象方法在超类中
A类{
def x:String=“A”
}
抽象类B扩展了{
def x:String
}
C类扩展到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)
导致以下错误
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)
尝试实例化C
scala> (new C).x
val res0: String = A
看起来编译器刚刚忽略了B.x
抽象方法
更新 在我问题的第一版中,我愚蠢地忘记了在第二个场景中扩展
A
,这导致了一个错误的结论,即在我的示例中,类和特质的行为不同。我由衷地为我的疏忽道歉
让我试着把我的问题重新分阶段:
在第一个和第二个场景中,抽象<代码> B.X <代码>在班级等级的中间是什么?
据我所知,通过继承和方法解析顺序(MRO)- 在第一个场景中,
覆盖B.x
和A.x
覆盖C.x
。由于B.x
是抽象的,当B.x
实现C.x
时,它不需要指定B.x
修饰符覆盖
- 在第二个场景中,
覆盖B.x
和A.x
没有实现抽象C
。所以B.x
应该是抽象的,不需要编译C
<>但是在我看来,编译器只是忽略了抽象方法<代码> B.X//C>在类层次结构中间。这种行为是在语言规范的某个地方定义的,还是完全出乎意料的(只是一个编译器错误)?我不确定问题是关于Traits和抽象类之间的差异,还是关于extends之间的差异 在第一个场景中两种情况下都有
抽象类B扩展了A
,但在第二个场景中有特征A
和特征B
<代码>B未扩展A
。
事实上,如果你把特征A扩展B
放在第二个场景中,它就不会编译
在第二个场景的第二种情况下,您扩展了两个具有相同方法的不同trait,让用B扩展A
您的类定义了方法x,因为从多个trait扩展时顺序很重要。如果您尝试以相反的顺序执行此操作,它将无法编译
换言之:
第二种情况-第一种情况:定义抽象方法不需要重写
第二种情况-第二种情况:
C用B扩展A
与B扩展A
+C扩展B
嗨,我很抱歉,在我的第二种情况代码示例中,我愚蠢地忘记了扩展A
,这误导了我的错误结论,即类和特征在这种情况下表现不同。我已经更新了问题描述,希望它能澄清。这个问题既不是关于traits和抽象类之间的差异,也不是关于extends之间的差异。这是关于一个抽象方法覆盖同一个超类的具体方法时的效果。