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

この方法では継承できません。Liskov Substitution Principleに違反しています。なぜそうなのかを説明します。これらのクラスをコンパイルできるとします。

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は ではないため、Workerその呼び出しは無効です。ただし、p1は であるためPerson、その呼び出しは有効です。この矛盾は、提案したオーバーライドの結果です。

しかし、それはそれよりも悪いです!これも機能しません:

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

現在、ワーカーのリストを渡しているにもかかわらず、 で期待されているように、 inが型パラメーターを想定していないp1ため失敗します。ただし、型パラメーターを渡す必要があると宣言されたメソッド! 繰り返しますが、矛盾は提案したオーバーライドの結果です。doSomethingWorker doSomethingPerson

継承は一種のis-a関係であることを忘れないでください。Workerが である場合、 が期待するすべての点で のように動作Personする必要があります。そのような関係を作成したくない場合は、継承を使用しないでください。PersonPerson

于 2011-11-06T00:13:06.753 に答える