Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 理解用抽象方法重写具体方法时的逻辑_Scala - Fatal编程技术网

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" ^

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

第一种情况
  • 超类中要重写的具体方法
  • 抽象方法在超类中
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之间的差异。这是关于一个抽象方法覆盖同一个超类的具体方法时的效果。