scala - 在 trait 中实现方法的规则是什么?

标签 scala types extends traits

我定义了一个特征:

trait A {
   def hello(name:Any):Any
}

然后定义一个类 X 来实现它:
class X extends A {
  def hello(name:Any): Any = {}
}

它编译。然后我更改子类中的返回类型:
class X extends A {
  def hello(name:Any): String = "hello"
}

它也编译了。然后更改参数类型:
class X extends A {
  def hello(name:String): Any = {}
}

这次编译不了,报错是:
error: class X needs to be abstract, since method hello in trait A of type (name: Any)
Any is not defined
(Note that Any does not match String: class String in package lang is a subclass 
of class Any in package scala, but method parameter types must match exactly.)

似乎参数应该完全匹配,但返回类型可以是子类中的子类型?

更新:@Mik378,感谢您的回答,但为什么下面的例子不能工作?我认为它不会破坏 Liskov:
trait A {
   def hello(name:String):Any
}

class X extends A {
   def hello(name:Any): Any = {}
}

最佳答案

就像在 Java 中一样,保持 Liskov Substitution principle ,你不能覆盖 具有更细粒度参数的方法。

确实,如果您的代码处理 A 怎么办?类型,引用 X在引擎盖下键入。
根据 A ,您可以通过Any输入你想要的,但 B只允许 String .
因此 => 繁荣

从逻辑上讲,根据相同的推理,允许使用更细粒度的返回类型,因为它会覆盖任何处理 A 的代码的情况。类(class)。

您可能需要检查这些部分:
http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Covariant_method_return_type



http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Contravariant_method_argument_type

更新 - - - - - - - -

trait A {
   def hello(name:String):Any
}

class X extends A {
   def hello(name:Any): Any = {}
}

它将充当完美的重载,而不是覆盖。

关于scala - 在 trait 中实现方法的规则是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23264695/

相关文章:

scala - 使用Hive或Spark Scala进行数据排列

types - 为什么 Julia 的 Union 和 Tuple 实例是 DataType 而不是 UnionAll?

java - 如何在 Java 程序中使用 «extend»?

scala - 返回同质元组的函数的方法签名?

scala - 在 Scala 中使用惰性 val 的性能损失是什么,但在 def 中

scala - 如何迭代 Spark DataFrame 行?

class - 为什么无法通过 Type.getClass() 访问类的静态字段?

types - 在域特定语言的自定义编辑器中实现类似 IntelliSense 的行为

mongoose - 为服务扩展类时如何处理 NestJS 依赖注入(inject)?

PHP 扩展类和同级访问