Fre*_*ind 4 extends types scala traits
我定义了一个特征:
trait A {
def hello(name:Any):Any
}
Run Code Online (Sandbox Code Playgroud)
然后定义一个类X来实现它:
class X extends A {
def hello(name:Any): Any = {}
}
Run Code Online (Sandbox Code Playgroud)
它汇编了.然后我更改子类中的返回类型:
class X extends A {
def hello(name:Any): String = "hello"
}
Run Code Online (Sandbox Code Playgroud)
它也汇编了.然后更改参数类型:
class X extends A {
def hello(name:String): Any = {}
}
Run Code Online (Sandbox Code Playgroud)
这次无法编译,错误是:
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.)
Run Code Online (Sandbox Code Playgroud)
看起来参数应该完全匹配,但返回类型可以是子类中的子类型?
更新:@ Mik378,感谢您的回答,但为什么以下示例无效?我认为它不会打破Liskov:
trait A {
def hello(name:String):Any
}
class X extends A {
def hello(name:Any): Any = {}
}
Run Code Online (Sandbox Code Playgroud)
就像在Java中一样,保持Liskov Substitution原则,你不能用更精细的参数覆盖一个方法.
实际上,如果您的代码处理A类型,引用X类型下的内容,该怎么办?根据A,您可以传递Any您想要的类型,但B仅允许String.因此=> BOOM
逻辑上,使用相同的推理,允许更细粒度的返回类型,因为它将覆盖任何处理A类的代码的情况.
您可能需要检查这些部分:http: //en.wikipedia.org/wiki/Covariance_and_contravariance_ (computer_science)#Covariant_method_return_type
和
UPDATE ----------------
trait A {
def hello(name:String):Any
}
class X extends A {
def hello(name:Any): Any = {}
}
Run Code Online (Sandbox Code Playgroud)
它将充当一个完美的超载,而不是压倒一切.
| 归档时间: |
|
| 查看次数: |
253 次 |
| 最近记录: |