2

我在scala中遇到了一些继承和下限问题;我将尝试用一个例子来解释它:我有一个类 Person ,其签名如下:

def doSomething[P<%Person](persons :List[P]) {
}

我还创建了一个子类 Worker,他的方法 doSomething 如下所示:

override def doSomething(persons: List[Worker]) {
}

然而,这会引发一个错误,指出 Worker.doSomething() 没有覆盖任何东西?

4

2 回答 2

4

一个特定的方法不能覆盖一个泛型方法(尽管一个特定的类可以扩展一个泛型类),因为泛型方法说只要你传递它的任何子类 person 就可以工作。具体方法不会取任何子类;它只需要Worker.

于 2011-11-05T21:43:08.137 回答
3

你不能以这种方式继承。它违反了里氏替换原则。我会说明为什么会这样。假设您可以编译这些类:

class Person {
    def doSomething[P<%Person](persons :List[P]) {
    }
}

class Worker extends Person {
    override def doSomething(persons: List[Worker]) {
    }
}

现在,这个简单的程序会失败:

val p1: Person = new Worker
val p2: Person = new Person
p1.doSomething(List(p2))

由于p2不是 a Worker,因此该调用无效。但是,既然p1是 a Person,那么该调用是有效的!这种矛盾是您提出的覆盖的结果。

但比这更糟糕!这也不起作用:

p1.doSomething[Worker](List(p1))

现在,即使它传递了一个工人列表,正如预期的那样p1,它失败了,因为doSomethinginWorker 不需要类型参数。但是,声明应该传递类型参数的doSomething方法Person!同样,矛盾是您建议的覆盖的结果。

请记住,继承是一种is-a关系。如果Worker是 a Person,那么它应该在人们期望 a 的所有方面表现得像a 。如果这不是您想要创建的那种关系,那么不要使用继承。PersonPerson

于 2011-11-06T00:13:06.753 回答