8

次のような抽象クラスがあるとします。

public abstract class Pet {
    private final String name;
    public Pet(String name) { 
        this.name = name 
    };

    public abstract boolean getsSpecialTreatment();
}

public final class Dog extends Pet {
    @Override public boolean getsSpecialTreatment() { return true; }
}

public final class Cat extends Pet {
    @Override public boolean getsSpecialTreatment() { return false; }
}

私のプログラムはPet、特別な処理フラグが設定されているかどうかに応じて、 s を異なる方法で扱います。私の質問は、これが次のように述べている Liskov 置換原則に違反していると見なされるかどうかです。

[...]コンピュータプログラムでは、SがTのサブタイプである場合、タイプTのオブジェクトはタイプSのオブジェクトに置き換えることができます[...]そのプログラムの望ましいプロパティ(正確さ、実行されるタスク)を変更することなくなど)。

4

4 に答える 4

6

この場合、それらのクラスのユーザーはおそらく次のように書くでしょう:

...
if (pet.getsSpecialTreatment()) {
    // special treatment
    ...
} else {
    // normal treatment
    ...
}
...

このコードは両方のケースで機能するため、LSP に違反することはありません。しかし、あなたが持っていた場合

public class UnknownAnimal extends Pet {
    @Override public boolean getsSpecialTreatment() {
        throw new UnsupportedOperationException("Unknown species"); 
    }
}

UnknownAnimalインスタンスを使用すると既存のコードが壊れるため、LSP に違反することになります。

于 2011-06-06T19:04:48.303 に答える
4

いいえ。プログラム内でのメソッドの使用は、他のメソッドと同様に、戻り値に基づいてその後の決定を行います。メソッドの存在の性質上、どのプログラムもその結果について仮定を行うべきではありません。したがって、このメソッドによって返される値の変更によって、プログラムのプロパティが変更されることはありません。

于 2011-06-06T19:05:13.833 に答える
1

まず、猫差別に断固反対!

さて、プログラマーがいわゆる「リスコフ置換原理」を呼び出すとき、彼らは実際には学問的な意味でそれについて話しているわけではありません。私たちはそれを非公式で、下品で、卑劣な意味で使用しているに違いありません。

それはどういう意味ですか?サブクラスがスーパークラスによって設定された契約に準拠しなければならないことを要求することに他なりません。だから本当に面白くない。人々はただファンシーにするためにこのフレーズを呼び出します。

于 2011-06-06T19:33:13.670 に答える