2010-05-31 163 views
2

我一直在遺傳我的大腦一段時間了,但我仍然不能完全解決它。瞭解繼承

例如,有一天我在考慮將一個不可靠的人和一個可能發生的人聯繫起來。我們首先定義兩個:

  • 可靠的人類:一個永遠不會犯錯的人。它的do_task()方法永遠不會拋出異常
  • 易損人:一個偶爾會犯錯誤的人。其do_task()方法可能偶爾拋出異常ErrorProcessingRequest

的問題是: 是萬無一失的人類甲犯錯誤的人類 OR 是易錯的人一個犯錯人類嗎?

我收到的非常好的答案是一個問題的形式(我喜歡這些,因爲它給了我規則來回答我可能有的問題)。

「如果預計會出現易犯錯誤的人類,你能通過一個可靠的人嗎?

看起來很明顯,你可以通過一個可靠的人,預計一個易犯錯的人,但不是相反的方式。我想這回答了我的問題。

然而,它仍然感到有趣的說:「一個可靠的人是一個易犯錯的人」。當他們說出來時,其他人是否會感到不安?它幾乎感覺好像說出繼承樹就像從普通英語中的命題演算中讀出語句一樣(如果/然後暗示連接詞與英語口語中的意思不一樣)。其他人是否也有同感?

回答

8

「看來顯而易見的是,你可以通過 一個犯錯的人,其中一個會犯錯誤 人的預期,而不是其他 周圍道路」

這僅僅是在一定的語境中一個正確的假設。打破它是這樣的:如果你的系統的邏輯需要傳遞一個人的那犯錯誤

  1. ,那麼這是不正確的。

  2. 如果系統的邏輯不關心人們會做什麼,那麼這個是正確的。

換句話說,它完全依賴於系統的要求,以確定問題的答案"IS an infallible human A fallible human OR IS a fallible human AN infallible human?"

邏輯對象被擬人化的事實可能比任何事物都更令人困惑,因爲它似乎是你的混淆源於哲學立場而不是邏輯立場。用「對象X」和「對象Y」代替「可靠的人類」和「易犯錯誤的人類」,這可能會爲你清楚思考。

+4

+1。優秀點。這些解釋客體關係的比喻通常會失敗;它們通常很少或沒有清晰度,並導致無問題成爲問題。 – 2010-05-31 19:05:50

+0

我同意你所說的,但是OO已經被教給了我們想要試圖建模它們之間的關係的目標,當我們確實遇到這種情況時,它有時會感到古怪。 – dhruvbird 2010-06-01 08:00:50

+2

Shel Silverstein有一首名爲_The Zebra Question_的詩,其中有人問斑馬,如果他是黑色的白色條紋或白色的黑色條紋。斑馬不直接回答...但是它可能會問一些關於提問者的類似問題(「你對壞習慣有好處,或者有好習慣嗎?」)因爲斑馬不會讓這個傢伙閉嘴:「我永遠不會問斑馬/關於條紋/再次。「 :) – HostileFork 2010-06-13 04:49:42

5

在這種情況下,我會說一個父類是答案:FallibleHuman繼承自Human,就像InFallibleHuman一樣。

0

我Daenyth同意...

,因爲一旦不能犯錯誤,一個人,在邏輯上這就是答案。

契約式地說,如果一個方法期望一個沒有犯錯誤的人,它就不會得到一個那樣做的事物,如果它期望一個人不會得到那個不會犯的錯誤。

一個人的基類,可能會或可能不會犯錯誤它的答案。

2

繼承的主要目的是提供通用功能並描述類之間的通用性。我建議你描述兩個人類的特徵(萬無一失和易犯錯誤)會分散注意力並引起混淆。

關於人類的「共同點」是什麼?所有人都有一個公共的「do_task()」方法和一個私有/受保護的「do_something()」方法。因此,我們描述了它所謂的「人」

public abstract class Human 
{ 
    // describes commonality 
    public abstract void do_task(); 

    // provides common functionality 
    protected virtual void do_something() 
    { 
     throw new Exception("I made a mistake"); 
    } 
} 

現在的「繼承」類實現自己特定的邏輯爲do_task()方法,但它們共享保護do_something的通用功能()方法的超類

public class InfallibleHuman : Human 
{ 
    public override void do_task() 
    { 
     try 
     { 
      do_something(); 
     } 
     catch 
     { 
      // never throw an exception 
      // because I never make mistakes 
     } 
    } 
} 

public class FallibleHuman : Human 
{ 
    public override void do_task() 
    { 
     do_something(); 
     // always throw an exception if 
     // something goes wrong because I'm accountable 
     // for my own actions 
    } 
} 

現在,我們已經使用了繼承來形容人與人之間的共性並提供一個默認,共同實現,但子類的版本增加了,我們用了「易犯錯誤」和「無過失」,以具體行爲描述,這與繼承無關。

現在,如果您有使用人類的東西,並且會接受任何人類,您可以使用InfallibleHuman或FallibleHuman。

public void ImPrettyTolerantOfMistakes() 
{ 
    try 
    { 
     Human anyHumanWillDo = new FallibleHuman(); 
     anyHumanWillDo.do_task(); 
     Human anotherHuman = new InfallibleHuman(); 
     anotherHuman.do_task(); 
    } 
    catch 
    { 
     // I'll take care of a human 
     // making a mistake 
    } 
} 

但是,如果你正在使用的東西是不寬容的人是會犯錯誤的,你可以使用一個完美的人......

public void ImIntolerantOfHumansWhoMakeMistakes() 
{ 
    InfallibleHuman onlyAPerfectHumanWillDo = new InfallibleHuman(); 
    onlyAPerfectHumanWillDo.do_task(); 

    // if this guy fails, I'm dead meat 
} 

我希望事情清除的東西了你一下。

0

異常通常在特殊情況下拋出。如果一個易犯錯誤的人的觀點是它犯了錯誤,爲什麼會有一個例外?

至於手頭的問題,我會說他們不能從對方繼承,而是從父類人類繼承。他們都是人類的兩種類型。