2017-02-15 50 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不會被破壞。這個例子再一次給出瞭解決這個問題的方法。

相關問題