のコントラクトがBaseCollection
、そのadd
メソッドがから派生したオブジェクトを合法的に渡すことができると指定している場合Entity
、の継承されたadd
メソッドUserCollection
も同様に行う必要があり、そうしないとLSPに違反します。元のメソッドをから派生した任意のオブジェクトで使用できる場合、タイプのオブジェクトのみを受け入れるオーバーロード(オーバーライドではない)がUserCollection
含まれていても、LSPに違反することはありませんが、オーバーロードは特に適切ではない可能性があります。add
User
add
Entity
の代わりにadd
、問題のメソッドがsetItem(int index, Entity value)
ベースsetItem(int index, User value)
クラスと派生クラスのようなものであり、コントラクトが同じコレクションから読み取られたオブジェクトでのみ動作することが保証されていると指定されている場合、その読み取りを提供しますのUserCollection
インスタンス以外のものが生成されることはありませんUser
。このメソッドは、LSPに違反することなく、setItem
のインスタンスではないすべてのオブジェクトを合法的に拒否できます。メソッドがのインスタンスではないものをすべて拒否する場合はUser
、のみを受け入れるオーバーロードがあると便利で適切な場合があります。継承されたメソッドは、のインスタンスを識別したことを確認する必要がありますがsetItem
user
user
setItem
value
User
、そのタイプの引数を受け入れたオーバーロードは受け入れません。このようなオーバーロードを追加する際の最大の注意点は、同じことを行う2つの封印されていない仮想メソッドを使用しないようにすることです。オーバーロードを追加する場合は、基本クラスのメソッドをオーバーライドしてシールし、渡された引数をtypeに変換してUser
から、オーバーロードされたバージョンのメソッドにチェーンする必要があります。
配列は後者の形式のコントラクトと継承にサブスクライブすることに注意してください。タイプの変数は、 ;Animal[]
への参照を保持できます。を識別する任意のものをCat[]
に格納しようとすると失敗する可能性がありますが、からの読み取りはすべて同じ配列に「適合する」ことが保証されています。これにより、コードは、問題の配列の型を知らなくても、任意の参照型の配列内の要素を並べ替えたり並べ替えたりすることができます。Animal
Animal[]
Cat[]
Animal
Animal[]