简体   繁体   English

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

[英]Do abstract properties violate the Liskov substitution principle?

Suppose I have an abstract class like:假设我有一个抽象的 class 像:

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; }
}

My program will treat Pet s differently depending on whether the special treatment flag is set.我的程序会根据是否设置了特殊处理标志来区别对待Pet My question is whether this counts as violating the Liskov substitution principle, which states that:我的问题是这是否算作违反了 Liskov 替代原则,该原则指出:

[...] in a computer program if S is a subtype of T, then objects of type T may be replaced with objects of type S [...] without altering any of the desirable properties of that program (correctness, task performed , etc.). [...] 在计算机程序中,如果 S 是 T 的子类型,那么 T 类型的对象可以被 S 类型的对象替换 [...]而不会改变该程序的任何期望属性(正确性,执行的任务) , ETC。)。

In this case, users of those classes will probably write:在这种情况下,这些类的用户可能会写:

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

This code will work on both cases, so you would not be violating LSP.此代码适用于这两种情况,因此您不会违反 LSP。 However, if you had但是,如果你有

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

then you would be violating LSP, because existing code will break when using UnknownAnimal instances.那么您将违反 LSP,因为现有代码在使用UnknownAnimal实例时会中断。

No. Any usage of the method in the program would base subsequent decisions on the return value, just like any other method.不会。程序中对该方法的任何使用都将基于返回值做出后续决策,就像任何其他方法一样。 By the very nature of the existence of the method, no program should make assumptions as to its outcome.由于该方法存在的本质,任何程序都不应该对其结果做出假设。 Therefore the change in the value returned by this method should not change the properties of the program.因此,此方法返回的值的变化不应该改变程序的属性。

First, strong objection to your discrimination against cats!首先,强烈反对你对猫的歧视!

Now, when programmers invoke the so called "Liskov substitution principle", they are not really talking about it in its academic sense.现在,当程序员调用所谓的“里氏替换原则”时,他们并不是真正在谈论它的学术意义。 We must be using it in some informal, vulgar, bastardized sense.我们一定是在某种非正式的、粗俗的、卑鄙的意义上使用它。

What sense is that?那是什么意思? I find it nothing more than requiring that subclass must conform to the contract set by the super class.我发现它只不过是要求子类必须符合超级 class 设定的合同。 So it's really uninteresting.所以真的很无趣。 People invoke this phrase just to be fansy.人们引用这句话只是为了狂热。

It depends on the contract.这取决于合同。 That is, the code using your classes must get consistent behavior, regardless what derivation of your type is it using.也就是说,使用您的类的代码必须获得一致的行为,无论它使用的是什么类型的派生。

If the contract stated "getSpecialTreatment" always returns true, you would be violating that in your derived class.如果合同规定“getSpecialTreatment”总是返回 true,那么您将在派生的 class 中违反这一点。

If the contract states "getSpecialTreatment" returns a boolean value determining blabla., then you are not violating LSP.如果合同规定“getSpecialTreatment”返回确定 blabla. 的 boolean 值,那么您没有违反 LSP。

You could violate LSP if you introduced additional constraint that is not present in the base class.如果您引入了基础 class 中不存在的附加约束,则可能违反 LSP。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM