当前位置: 首页 > 知识库问答 >
问题:

对象toString方法和Liskov替换原则

咸疏珂
2023-03-14

每个类都直接或间接地继承自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(),系统的行为就会改变。

共有3个答案

江阳羽
2023-03-14

请注意,如果您的实现将抛出任何异常,那么它将违反LSP as对象。toString()不会引发任何异常。

湛鸿雪
2023-03-14

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();
西门嘉石
2023-03-14

嗯,这是品味的问题<代码>对象几乎没有保证的属性。因此,也没有什么可以违反的。

如果你说返回类名是这样一个可能被侵犯的属性,那么当然,一个子类不应该改变这一点。但是阅读Object.toString()的留档结果发现没有这样的保证:

返回对象的字符串表示形式。通常,toString方法返回一个“文本表示”此对象的字符串。

所以我看这里没有LSP违规。

LSP并没有说子类的行为必须与超类完全相同。这将使子类完全无用。它只要求子类满足超类的规范。

唯一可以提到的是,Object为每个对象强制执行一个无意义的方法toString。一个更复杂的设计可能会把它放到一个接口中。

我认为这种设计选择只是一种折衷,被其他语言所取代。NET。

 类似资料:
  • Liskov替代原理(LSP)说: 先决条件不能在子类型中得到加强。 在C#中,我可能违反以下整个原则: 但是,如果是一种方法,会发生什么呢 现在是无合同的。或者它的合同就是一切允许的。 那么,前提条件是否违反了Liskov替代原则?

  • 我发现很难理解这个概念。我脑子里有几个问题。我试着在网上查询,但是没有太多的资源。 子类是否需要在其整个生命周期中保持其独特性? 我很确定LSP定义了超级类和子类之间的契约,如果我错了,请纠正我。 如果一个给定的函数使用某个对象,你能用它的一个子类替换这个对象而不破坏它的执行吗? 如果有一个类型为超类的变量,程序是否仍然有效。如果我将该超类或任何子类的实例放入该变量中。 如果这没有道理,我很抱歉。

  • 在创建我的班级结构时,我努力坚持利斯科夫替代原则。我想在Day类中存储一组日历项。需要有几种不同类型的日历项,例如: 任命项目 备注项目 轮换项目 它们都共享一些抽象基类CalendarItem中的常见功能: 但例如RotaItem有一些额外的功能: 其他类也添加了自己的逻辑等。 我有一组CalendarBaseItem用于我的日课: 但在回顾这一点时,我可以看到我正在打破LSP原则,因为我必须检

  • 我在派生类中重写了带有附加先决条件的虚拟函数。这是快照- 如果我理解正确的话,这里的代码通过附加一个先决条件打破了Liskov替换-IsImmediateProcess和其他日期检查。对吗?或者一个被重写的函数调用一个基函数,然后向它添加自己的行为,这样可以吗? 我不能将重写方法中由初始过程类型引入的条件移动到基本类型,因为它是特定于初始过程的。 在这种情况下,如果派生类重写行为并希望在不违反Li

  • LSP定义指出,如果S是T的子类型,则程序中T类型的对象可以替换为S类型的对象,而不改变该程序的任何期望属性。 子类型中的前提条件不能加强 例如,我有下面的类,这是违反(在子类型中不能加强前提条件)。我正试图把我的头绕在这上面,请有人提供一个好的例子来理解它。