scala - "override"当继承的特征组合时如何工作?

标签 scala multiple-inheritance traits diamond-problem

我正在 Scala 中尝试多重继承。我知道有一个从右到左的分辨率,但我不明白 override 的作用关键词。让我们考虑以下代码段:

trait A           { def          method                }
class B extends A { def          method = println("B") }
trait C extends A { override def method = println("C") }
trait E           {                                    }
class D extends B with C with E

它编译得很好,但如果我删除 override从最右边的特征定义 method ,坏了。为什么是这样 ?即使没有关键字,该方法也不会被覆盖吗?

最佳答案

如果 trait 应该替换(而不是提供缺失的实现)一个方法,你需要使用 override关键词。无论以 trait 还是以其他方式提供另一种方法,都是如此。例如:

trait X { def foo = "foo" }
class Y { def foo = "bar" }
class Z extends Y with X  // Does not compile

因此,它实际上与抽象类的规则完全相同:您需要覆盖要替换其实现的方法(而不是第一次提供)。

注意用traits,只要最后提供的方法是override就够了:
trait L { def m: String }
trait M extends L { def m = "m" }
trait N extends L { def m = "M" }
trait O extends L { override def m = "?" }
class P extends M with N with O  // All good
class Q extends M with N { override def m = "." } // Also good

在这里,算作“已经提供”的是扩展的早期部分,一切都很好。所以
class R extends O with N

不起作用,因为 O提供了 m 的实现(如果需要,可以覆盖),但是 N然后尝试应用另一个,并且不允许覆盖。

另一方面,P很好,因为即使 MN两者都试图为 m 提供一个实现, O最后并声明其实现可以覆盖。确实如此,而且一切都很好。

关于scala - "override"当继承的特征组合时如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28005766/

相关文章:

rust - 为什么 len() 和 is_empty() 没有在特征中定义?

scala - 更改多个 Spark DataFrame 列类型,动态且可配置

scala - Json 转换器 - 来自 2 个现有字段的新字段

python - 解决元类冲突

python - Django 中是否可以继承多个抽象基类?

c++ - C+ +'s concepts and Rust' 的特质有什么异同?

scala - 使用 Maven 打包并运行 Scala Spark 项目

scala - 何时下载/构建 SBT 包?

php - 从两个父类继承

php - 在特征中使用类的属性