2017-02-15 49 views
2

我想知道我该如何组织我的两堂课。在我的例子中违反了Liskov替换原则吗?

  • 其中之一代表Knife:只是一个简单,坚实,基本的,就像一把菜刀。
  • 另一个是PocketKnife,其状态为已打开已关闭
在我的代码的类
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(); 
    } 
    } 
} 

都不是抽象的。

这个例子是否违反LSP?

在我看来确实如此,因为对于cut()操作后置条件应该是:

  1. 刀越来越切割
  2. 一些对象后,有点“老”的刀片必须有一定的损伤它(如果它是一些游戏为例)

但随着其关闭状态,我们不会有这些后置条件的PocketKnife。或者我错了?

回答

0

Liskov替代原则(最简单的OOP设计准则之一)只是声明任何子类型必须可替代其父类而不会破坏程序。

如果你有像someFunc(Knife k)这样的方法调用k.cut(),并且你可以将Knife或Pocketknife或WhateverKnife传递给someFunc方法并让程序正常工作,那么你并没有违反LSP。

+1

这并没有回答他的问题,它只是重申LSP背后的想法/原理。他的代码是否违反了它?为什么? –

1

是否违反LSP,取决于“cut”的定义是什么(不应该是)。如果条件后的操作是,必须满足以下条件:

  1. 刀越来越切割
  2. 一些对象有后有点“老”有一些关于它的伤害(如果它是刀片一些游戏为例)

然后,PocketKnife不符合这些条件时,“封闭”。因此,PocketKnife无法在任何地方替代Knife,并且LSP被破坏。

如何解决?

那么,这取决于上下文,需要更多的信息。但是,一个例子可以是这样的:

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. 
     } 
     } 
    } 

由此,LSP不会被破坏。这个例子再一次给出了解决这个问题的方法。

相关问题