对象toString方法和Liskov替换原则

zer*_*uno 0 java liskov-substitution-principle

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

Object除了其他人之外,这个班级有一个重要的方法,最经常被覆盖:toString.

问题是:这个方法的重写不会导致Liskov替换原则违反了Object类吗?

我会做一个例子.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

显然,如果我更换new Object()new MyClass()系统的行为变化.

Mar*_*cel 8

嗯,这是一个品味问题.Object几乎没有保证的财产.因此,没有太多可以违反.

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

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

所以我在这里看不到LSP违规.

LSP并没有说子类的行为必须与超类完全相同.这会使子类完全无用.它只要求子类符合超类的规范.


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

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