Object toString method and Liskov substitution principle











up vote
0
down vote

favorite












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.










share|improve this question




















  • 5




    Why do you think it violates that principle?
    – Eran
    Nov 18 at 13:40










  • @Eran I updated my question.
    – zer0uno
    Nov 18 at 13:48










  • @Eran. You still haven't explained why you think it violates substitution.
    – Mad Physicist
    Nov 18 at 13:51










  • @MadPhysicist Replacing new Object() with new MyClass() the behavior of the system changes.
    – zer0uno
    Nov 18 at 13:52










  • @zeroOuno. That's to be expected. If something weren't to change, why bother having a subclass and overriding in the first place? The substitution principle tells you how much you're allowed to change while still retaining interoperability. The posted answer does a good job relating that allowance to the contract of the method.
    – Mad Physicist
    Nov 18 at 13:56















up vote
0
down vote

favorite












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.










share|improve this question




















  • 5




    Why do you think it violates that principle?
    – Eran
    Nov 18 at 13:40










  • @Eran I updated my question.
    – zer0uno
    Nov 18 at 13:48










  • @Eran. You still haven't explained why you think it violates substitution.
    – Mad Physicist
    Nov 18 at 13:51










  • @MadPhysicist Replacing new Object() with new MyClass() the behavior of the system changes.
    – zer0uno
    Nov 18 at 13:52










  • @zeroOuno. That's to be expected. If something weren't to change, why bother having a subclass and overriding in the first place? The substitution principle tells you how much you're allowed to change while still retaining interoperability. The posted answer does a good job relating that allowance to the contract of the method.
    – Mad Physicist
    Nov 18 at 13:56













up vote
0
down vote

favorite









up vote
0
down vote

favorite











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.










share|improve this question















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.







java lsp






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 18 at 13:53

























asked Nov 18 at 13:34









zer0uno

2,34683055




2,34683055








  • 5




    Why do you think it violates that principle?
    – Eran
    Nov 18 at 13:40










  • @Eran I updated my question.
    – zer0uno
    Nov 18 at 13:48










  • @Eran. You still haven't explained why you think it violates substitution.
    – Mad Physicist
    Nov 18 at 13:51










  • @MadPhysicist Replacing new Object() with new MyClass() the behavior of the system changes.
    – zer0uno
    Nov 18 at 13:52










  • @zeroOuno. That's to be expected. If something weren't to change, why bother having a subclass and overriding in the first place? The substitution principle tells you how much you're allowed to change while still retaining interoperability. The posted answer does a good job relating that allowance to the contract of the method.
    – Mad Physicist
    Nov 18 at 13:56














  • 5




    Why do you think it violates that principle?
    – Eran
    Nov 18 at 13:40










  • @Eran I updated my question.
    – zer0uno
    Nov 18 at 13:48










  • @Eran. You still haven't explained why you think it violates substitution.
    – Mad Physicist
    Nov 18 at 13:51










  • @MadPhysicist Replacing new Object() with new MyClass() the behavior of the system changes.
    – zer0uno
    Nov 18 at 13:52










  • @zeroOuno. That's to be expected. If something weren't to change, why bother having a subclass and overriding in the first place? The substitution principle tells you how much you're allowed to change while still retaining interoperability. The posted answer does a good job relating that allowance to the contract of the method.
    – Mad Physicist
    Nov 18 at 13:56








5




5




Why do you think it violates that principle?
– Eran
Nov 18 at 13:40




Why do you think it violates that principle?
– Eran
Nov 18 at 13:40












@Eran I updated my question.
– zer0uno
Nov 18 at 13:48




@Eran I updated my question.
– zer0uno
Nov 18 at 13:48












@Eran. You still haven't explained why you think it violates substitution.
– Mad Physicist
Nov 18 at 13:51




@Eran. You still haven't explained why you think it violates substitution.
– Mad Physicist
Nov 18 at 13:51












@MadPhysicist Replacing new Object() with new MyClass() the behavior of the system changes.
– zer0uno
Nov 18 at 13:52




@MadPhysicist Replacing new Object() with new MyClass() the behavior of the system changes.
– zer0uno
Nov 18 at 13:52












@zeroOuno. That's to be expected. If something weren't to change, why bother having a subclass and overriding in the first place? The substitution principle tells you how much you're allowed to change while still retaining interoperability. The posted answer does a good job relating that allowance to the contract of the method.
– Mad Physicist
Nov 18 at 13:56




@zeroOuno. That's to be expected. If something weren't to change, why bother having a subclass and overriding in the first place? The substitution principle tells you how much you're allowed to change while still retaining interoperability. The posted answer does a good job relating that allowance to the contract of the method.
– Mad Physicist
Nov 18 at 13:56












2 Answers
2






active

oldest

votes

















up vote
8
down vote



accepted










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.






share|improve this answer




























    up vote
    1
    down vote













    Liskov substitution principle requires only interface compatibility. It does not say anything abound 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 it's specific implementation
    Text text = new SimpleText("text");
    text.value();
    text = new NumberText(44);
    text.value();





    share|improve this answer





















      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














       

      draft saved


      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53361431%2fobject-tostring-method-and-liskov-substitution-principle%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      8
      down vote



      accepted










      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.






      share|improve this answer

























        up vote
        8
        down vote



        accepted










        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.






        share|improve this answer























          up vote
          8
          down vote



          accepted







          up vote
          8
          down vote



          accepted






          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.






          share|improve this answer












          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.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 18 at 13:49









          Marcel

          880216




          880216
























              up vote
              1
              down vote













              Liskov substitution principle requires only interface compatibility. It does not say anything abound 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 it's specific implementation
              Text text = new SimpleText("text");
              text.value();
              text = new NumberText(44);
              text.value();





              share|improve this answer

























                up vote
                1
                down vote













                Liskov substitution principle requires only interface compatibility. It does not say anything abound 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 it's specific implementation
                Text text = new SimpleText("text");
                text.value();
                text = new NumberText(44);
                text.value();





                share|improve this answer























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  Liskov substitution principle requires only interface compatibility. It does not say anything abound 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 it's specific implementation
                  Text text = new SimpleText("text");
                  text.value();
                  text = new NumberText(44);
                  text.value();





                  share|improve this answer












                  Liskov substitution principle requires only interface compatibility. It does not say anything abound 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 it's specific implementation
                  Text text = new SimpleText("text");
                  text.value();
                  text = new NumberText(44);
                  text.value();






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 18 at 15:14









                  Igor

                  864




                  864






























                       

                      draft saved


                      draft discarded



















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53361431%2fobject-tostring-method-and-liskov-substitution-principle%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Costa Masnaga

                      Fotorealismo

                      Sidney Franklin