Search code examples
javaliskov-substitution-principle

Object toString method and Liskov substitution principle


Every class, directly or indirectly, inherits from the Object class.

The Object class, among the others, has the important method, most often overridden: toString.

The question is: doesn't the overriding of this method bring to Liskov Substitution Principle violation with respect to the Object class?

I'll do an example.

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);
    }
}

Obviously if I replace new Object() with new MyClass() the behavior of the system changes.


Solution

  • Well, it's a matter of taste. Object has almost no guaranteed properties. So there is no much to violate either.

    If you say that returning the class name is such a property that may be violated, then of course, a subclass should not change this. But reading the documentation of Object.toString() turns out that there is no such guarantee:

    Returns a string representation of the object. In general, the toString method returns a string that "textually represents" this object.

    So I see no LSP violation here.

    LSP does not say that a subclass must behave exactly the same as the superclass. This would make subclasses entirely useless. It only requires that subclasses meet the specification of the superclass.


    The only thing one could mention is that Object enforces a meaningless method toString for every object. A more sophisticated design might have put this into an interface.

    I think this design choice is just a compromise, taken over by other languages like .NET as well.