Neitrino
Neitrino

Reputation: 31

Is Liskov Substitution Principle violated in my example?

I wonder how I should organize my two classes.

class Knife{
  public function cut() {/* do the cutting */}
}
class PocketKnife extends Knife{
  private $opened = 0; // 0/1
  // ...
  public function cut() {
    if ($this->opened) {
      parent::cut();
    }
  }
}

None of the classes in my code are abstract.

Does this example violate the LSP?

In my opinion it does, because post-conditions for the cut() operation should be:

  1. the blade of the knife getting a bit "older" after cutting
  2. some object has to have some damage on it (if it is some game for example)

But with the PocketKnife in its closed state we won't have these post-conditions. Or am I wrong?

Upvotes: 2

Views: 527

Answers (2)

Nazar Merza
Nazar Merza

Reputation: 3454

Whether it violates LSP or not, depends on what the definition of "cut" IS (not should be). If post-condition for the operation is that the following MUST be true:

  1. the blade of the knife getting a bit "older" after cutting
  2. some object has to have some damage on it (if it is some game for example)

Then, PocketKnife does not meet these conditions when "closed". Hence, a PocketKnife cannot be substituted for Knife everywhere and LSP is broken.

How to solve it?

Well, it depends on the context and need more information. But, one example could be this:

   class Knife{
      public function cut() {/* do the cutting */}
    }

    class PocketKnife extends Knife{

      private $opened = 0; // 0/1
      // ...

      public function cut() {
        if (!$this->opened) {

          // state is changed for cut to be performed.
          $this->opened = 1; 

          parent::cut();

          // may need to close again, after operation.
        }
      }
    }

With this, LSP will not be broken. Again, the example just gives an idea about ways of tackling such problem.

Upvotes: 1

user2321864
user2321864

Reputation: 2307

Liskov Substitution Principle (one of the simplest OOP design guidelines) simply states that any child type must be substitutable for its parent without breaking the program.

If you have a method like someFunc(Knife k) which calls k.cut() and you can pass Knife or Pocketknife or WhateverKnife into that someFunc method and have the program work correctly, then you are not violating LSP.

Upvotes: 0

Related Questions