Reputation: 8030
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.
Upvotes: 0
Views: 332
Reputation: 529
Note that if your implementation will throw any exception then it will violate LSP as Object.toString() doesn't throw any exceptions.
Upvotes: 0
Reputation: 168
Liskov substitution principle requires only interface compatibility. It does not say anything about underlying behavior. So for example
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());
}
}
You do not care about details of implementation, so you can exchange them this way:
//We care only about value() method, not its specific implementation
Text text = new SimpleText("text");
text.value();
text = new NumberText(44);
text.value();
Upvotes: 1
Reputation: 1855
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.
Upvotes: 8