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

发布于 2024-11-14 09:54:02 字数 675 浏览 4 评论 0原文

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

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 是 T 的子类型,则类型 T 的对象可以替换为 S 类型的对象 [...] 而不改变该对象的任何所需属性程序(正确性、执行的任务等)。

Suppose I have an abstract class like:

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 Pets differently depending on whether the special treatment flag is set. My question is whether this counts as violating the Liskov substitution principle, which states that:

[...] 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.).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

廻憶裏菂餘溫 2024-11-21 09:54:02

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

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

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

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

这样做了,那么您将违反 LSP,因为使用 UnknownAnimal 实例时现有代码将被破坏。

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. 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.

稍尽春風 2024-11-21 09:54:02

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

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.

傻比既视感 2024-11-21 09:54:02

首先,强烈反对您对猫的歧视!

现在,当程序员引用所谓的“里氏替换原则”时,他们并不是真正在学术意义上谈论它。我们一定是在某种非正式的、粗俗的、混蛋的意义上使用它的。

这是什么意义?我发现这只不过是要求子类必须符合超类设定的契约。所以真的很无趣。人们引用这句话只是为了炫耀。

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. So it's really uninteresting. People invoke this phrase just to be fansy.

已下线请稍等 2024-11-21 09:54:02

这取决于合同。也就是说,使用类的代码必须获得一致的行为,无论它使用什么类型的派生。

如果合同规定“getSpecialTreatment”始终返回 true,那么您将在派生类中违反这一规定。

如果合约规定“getSpecialTreatment”返回一个确定 blabla. 的布尔值,那么您就没有违反 LSP。

如果引入了基类中不存在的附加约束,则可能会违反 LSP。

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.

If the contract states "getSpecialTreatment" returns a boolean value determining blabla., then you are not violating LSP.

You could violate LSP if you introduced additional constraint that is not present in the base class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文