首页 > 解决方案 > 对象 toString 方法和 Liskov 替换原理

问题描述

每个类都直接或间接地从该类继承Object

除其他外,该类Object具有重要的方法,通常被覆盖:toString.

问题是:这种方法的覆盖是否会导致对Object类的 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);
    }
}

显然,如果我替换new Object()new MyClass()系统的行为更改。

标签: javaliskov-substitution-principle

解决方案


嗯,这是一个品味问题。Object几乎没有保证的属性。所以也没有什么可违反的。

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

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

所以我在这里没有看到 LSP 违规

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


唯一可以提到的是对每个对象Object强制执行一种无意义的方法 。更复杂的设计可能会将其放入界面中。toString

我认为这种设计选择只是一种妥协,它也被 .NET 等其他语言所取代。


推荐阅读