每个类都直接或间接地继承自Object
类。
对象
类有一个重要的方法,最常被重写:toString
。
问题是:对于对象
类,重写此方法是否会违反Liskov替换原则?
我举个例子。
public class Main
{
public static void main(String[] args)
{
Object o = new Object();
String s = o.toString();
if (s.indexOf('@') > -1) {
System.out.println("OK");
} else {
System.out.println(":-(");
}
}
}
public class MyClass
{
private int x;
public string toString()
{
return Integer.toString(x);
}
}
显然,如果我用newmyclass()
替换newobject()
,系统的行为就会改变。
请注意,如果您的实现将抛出任何异常,那么它将违反LSP as对象。toString()不会引发任何异常。
Liskov替换原则只要求接口兼容性。它没有说明任何潜在的行为。比如说
public interface Text {
String value();
}
public class SimpleText implements Text {
private final String value;
public SimpleText(String value) {
this.value = value;
}
@Override
public String value() {
return this.value;
}
}
public class NumberText implements Text {
private final Number number;
public NumberText(Number number) {
this.number = number;
}
@Override
public String value() {
return String.format("%.3f", this.number.doubleValue());
}
}
您不关心实现的细节,因此可以通过以下方式进行交换:
//We care only about value() method, not its specific implementation
Text text = new SimpleText("text");
text.value();
text = new NumberText(44);
text.value();
嗯,这是品味的问题<代码>对象几乎没有保证的属性。因此,也没有什么可以违反的。
如果你说返回类名是这样一个可能被侵犯的属性,那么当然,一个子类不应该改变这一点。但是阅读Object.toString()的留档结果发现没有这样的保证:
返回对象的字符串表示形式。通常,toString方法返回一个“文本表示”此对象的字符串。
所以我看这里没有LSP违规。
LSP并没有说子类的行为必须与超类完全相同。这将使子类完全无用。它只要求子类满足超类的规范。
唯一可以提到的是,Object
为每个对象强制执行一个无意义的方法toString
。一个更复杂的设计可能会把它放到一个接口中。
我认为这种设计选择只是一种折衷,被其他语言所取代。NET。
Liskov替代原理(LSP)说: 先决条件不能在子类型中得到加强。 在C#中,我可能违反以下整个原则: 但是,如果是一种方法,会发生什么呢 现在是无合同的。或者它的合同就是一切允许的。 那么,前提条件是否违反了Liskov替代原则?
我发现很难理解这个概念。我脑子里有几个问题。我试着在网上查询,但是没有太多的资源。 子类是否需要在其整个生命周期中保持其独特性? 我很确定LSP定义了超级类和子类之间的契约,如果我错了,请纠正我。 如果一个给定的函数使用某个对象,你能用它的一个子类替换这个对象而不破坏它的执行吗? 如果有一个类型为超类的变量,程序是否仍然有效。如果我将该超类或任何子类的实例放入该变量中。 如果这没有道理,我很抱歉。
在创建我的班级结构时,我努力坚持利斯科夫替代原则。我想在Day类中存储一组日历项。需要有几种不同类型的日历项,例如: 任命项目 备注项目 轮换项目 它们都共享一些抽象基类CalendarItem中的常见功能: 但例如RotaItem有一些额外的功能: 其他类也添加了自己的逻辑等。 我有一组CalendarBaseItem用于我的日课: 但在回顾这一点时,我可以看到我正在打破LSP原则,因为我必须检
我在派生类中重写了带有附加先决条件的虚拟函数。这是快照- 如果我理解正确的话,这里的代码通过附加一个先决条件打破了Liskov替换-IsImmediateProcess和其他日期检查。对吗?或者一个被重写的函数调用一个基函数,然后向它添加自己的行为,这样可以吗? 我不能将重写方法中由初始过程类型引入的条件移动到基本类型,因为它是特定于初始过程的。 在这种情况下,如果派生类重写行为并希望在不违反Li
Java不允许
LSP定义指出,如果S是T的子类型,则程序中T类型的对象可以替换为S类型的对象,而不改变该程序的任何期望属性。 子类型中的前提条件不能加强 例如,我有下面的类,这是违反(在子类型中不能加强前提条件)。我正试图把我的头绕在这上面,请有人提供一个好的例子来理解它。