Hacker News new | ask | show | jobs
by safety-third 2316 days ago
LSP just says that derived classes should behave similar to their base classes.

    class Base {
        virtual int size() { return size_; }
    ...
    class Derived : public Base {
        virtual int size() { return rand(); }
    ...
Here we see an issue. Derived is overriding Base's size method, which has a straightforward implementation, with something wild. If a Derived is sent to a method expecting Base-like behavior, something bad is going to happen.

Derived should act like a Base with slightly different implementation details. This is all LSP is. It's a fancy phrase for a very simple concept.

1 comments

Not just similar. All provable properties must be the same.

As I understand it, Java's Object.toString() is an example of an LSP violation because different subtypes of Object return different strings.

That just goes back to the question of what's the desired property. If the specification is that toString() must return a human-readable string, and eg. be a pure function/not throw exceptions, then most implementations would not violate the LSP.
No, it is very much LSP compliant. The purpose of toString() is to give a string representation of the object. Most overloads of this do exactly that.

An LSP violation of toString() would be something that returns a string that doesn't represent the object. If you were to return the current time as a string for an object that has nothing to do with time, that would be an LSP violation.

I'm very confused. The definition of LSP is:

> Subtype Requirement: Let ϕ(x) be a property provable about objects x of type T. Then ϕ(y) should be true for objects y of type S where S is a subtype of T.

Why is the exact value of the string returned not a provable property? And, to your example, if a provable property is that the returned string represents the object, how did you know it was a provable property? And how do you prove it?

The rule seems very formal, but your notions seem very informal, and I don't know how to reconcile them.

With the caveat that LSP is still violated in the given example, I think it's important to note that when talking about "all" instances of a given class you might not have much information about the exact value of a string.

Their notions are informal, but on some level it's just the experimentalist's interpretation of LSP -- much how some physicists (loosely) argue that if you can't make measurements to prove a theory wrong then the theory doesn't matter, it might similarly be reasonable to ignore LSP with respect to properties that you don't care about (where that definition is fuzzy and hard to pin down but should represent a definitive class of things within any given single program). E.g., most people don't rely on toString() doing much more than giving a bit of human intuition into the type and properties of an object, so any implementation which respects that behavior satisfies a realist's LSP.

The Java Language Specification does not state an exact value for what toString returns or anything else that would let you derive an exact value, hence it is not provable: https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html...