2009-11-24 58 views
3

這是不好的?或者這在PHP框架中很常見?

例如,在父類中,有一個save()函數,它返回數據庫中受影響的行數。然後在子類中,我重寫此函數以執行一些預驗證,並且還想簡單地返回成功/失敗的布爾值。在PHP中創建子類中的函數時更改返回類型?

回答

5

我同意共識:改變返回值的類型(甚至含義)是不好的。

這裏有一個例子怎麼會不好:

比方說您有一個接受一個字符串和一個「作家」的功能:

​​

這裏是原來的「作家」類:

class Writer { 
    public function write(String $text) { 
     print $text; 
     return strlen($text); 
    } 
} 

如果我們通過了 '惰性寫入' 而不是功能:

class LazyWriter extends Writer { 
    public function write(String $text) { 
     return true; 
    } 
} 

假設Writer::write()的返回值是printThroughWriter中的字符數已被破壞,從而導致不一致。

3

是的,這是不好的。該方法的客戶很難知道該期望。除非這個方法被設計來處理它(在這種情況下,它看起來並不像)。

我會強烈反對它。

3

您應該覆蓋底層代碼,而不是合同。

因此,不改變返回值(這是合同的一部分)是不好的。

2

雖然在PHP中沒有強制執行返回類型,但最好保持與重寫的方法保持一致,因爲否則這意味着您將增加耦合並減少封裝。

考慮公共方法及其在網點和設備方面的返回類型。任何電器應該能夠插入任何插座,並且每個插座應該向每個電器輸出相同數量的能量,除非插座是專門爲特定類型的電器設計的。如果有人決定綠色出口應該輸出一個能量而另一個輸出紅色能量,會發生什麼。突然之間,您必須始終關注您的設備正在處理的特定類別的插座。

設計公共方法和屬性是完全一樣的,重寫的方法和屬性應始終保持一致,而不管它們的訪問環境如何。

2

我同意,這通常是一個壞主意。

如果您迫切需要從函數中傳遞另一個值,而不是返回值,那麼可以添加一個傳遞引用參數。或者,如果出現錯誤消息,請使用例外。

2

繼承的想法是允許客戶端交替使用類的子類型。如果要更改返回類型的子類型,那麼你正在破壞遺產的規範效用和最終只會造成混亂: 「在這裏,我需要一種集合,但myCollection.add()將返回我一個布爾值或添加的元素或其他東西?我不知道!我不能再用這種類型做任何事了!我將不得不爲每個子類型創建一個方法來處理這個問題!「

1

您可以返回多個指定類型,如從覆蓋方法的返回類型的後代的實例,而不會破壞合同。

如果重寫的方法返回一個布爾值,最重要的方法,可以改爲返回一個數字,如果0返回值對應,將導致重寫的方法返回FALSE和非零值對應於一個TRUE返回值的條件。這還可能導致潛在的問題,如果有人使用了相同的比較操作符(===)的返回值,但你通常只看到這個的時候(例如)的方法可能同時返回FALSE0不同的條件下。

在你的榜樣,壓倒一切的返回類型並不比覆蓋的返回類型更具體,所以你不應該這樣做。