Question

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?

Était-ce utile?

La solution

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.

Autres conseils

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top