抽象属性是否违反Liskov替换原则?

Jak*_*ake 8 java oop liskov-substitution-principle

假设我有一个抽象类,如:

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; }
}
Run Code Online (Sandbox Code Playgroud)

我的程序将Pet根据是否设置特殊处理标志来区别对待s.我的问题是,这是否违反Liskov替代原则,该原则指出:

[...]在计算机程序中如果S是T的子类型,那么T类型的对象可以用S类型的对象替换而不改变该程序的任何所需属性(正确性,执行的任务)等).

gpe*_*che 6

在这种情况下,这些类的用户可能会写:

...
if (pet.getsSpecialTreatment()) {
    // special treatment
    ...
} else {
    // normal treatment
    ...
}
...
Run Code Online (Sandbox Code Playgroud)

此代码适用于这两种情况,因此您不会违反LSP.但是,如果你有

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

然后你会违反LSP,因为现有代码在使用UnknownAnimal实例时会中断.


Rob*_*bin 4

不会。程序中该方法的任何使用都将基于返回值做出后续决策,就像任何其他方法一样。由于该方法存在的本质,任何程序都不应对其结果做出假设。因此,此方法返回值的更改不应更改程序的属性。