문제

I'm having some issues with inheritance and lower bounds in scala; I'll try to explain it with an example: I have a class Person with a signature like:

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

I've also created a child class Worker, and his method doSomething looks like this:

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

However this fires an error, stating that Worker.doSomething() doesn't override anything?

도움이 되었습니까?

해결책

You cannot inherit this way. It violates the Liskov Substitution Principle. I'll show why that is the case. Suppose you could compile these classes:

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

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

Now, this simple program would fail:

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

Since p2 is not a Worker, that call is invalid. However, since p1 is a Person, that call is valid! This contradiction is a result of the override you propose.

But it's worse than that! This ALSO won't work:

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

Now, even though it is passing a list of workers, as expected by p1, it fails because doSomething in Worker doesn't expect a type parameter. However, the method doSomething of Person declared that a type parameter should be passed! Again, the contradiction is a result of the override you propose.

Remember that inheritance is a is-a kind of relationship. If Worker is a Person, then it should act like a Person in all ways one expects a Person to act. If that's not the kind of relationship you want to create, then do not use inheritance.

다른 팁

A specific method cannot override a generic method (though a specific class can extend a generic class) because the generic method says it will work as long as you pass it any subclass of person. The specific method will not take any subclass; it will only take Worker.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top