2010-05-31 123 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

异常通常在特殊情况下抛出。如果一个易犯错误的人的观点是它犯了错误,为什么会有一个例外?

至于手头的问题,我会说他们不能从对方继承,而是从父类人类继承。他们都是人类的两种类型。