为什么覆盖到什么都不是子类中的好方法

时间:2014-03-05 09:33:23

标签: design-patterns

我正在阅读Head First Design Patterns, 在第一章中,作者试图解释一种设计方法。他首先展示了一个问题,然后试图通过使用设计模式来解决它。

假设我有一个Duck基类:

class Duck
{
   swim();
   quack();
   display();
}

和派生类RubberDuck

class RubberDuck : Duck
{
   quack(); //override to nothing
}

他说,如果RubberDuck没有嘎嘎叫,我必须把它改写为什么。的为什么吗

我认为,如果RubberDuck没有嘎嘎我就不会将其添加到RubberDuck。所以没有覆盖,就像:

class RubberDuck : Duck
{
   //other methods
}

他说: 所以我们知道使用继承并没有很好地解决,因为 鸭子行为在子类中不断变化,而且就是这样 不适合所有子类具有这些行为。

为什么?

如果我不重写任何方法,我不会调用那些在代码中实现子类对象的方法。我的意思是,如果我不使用任何能力,这意味着我没有那种能力,这有什么不对吗?

3 个答案:

答案 0 :(得分:1)

如果您不重写方法,则该方法将从基类继承。因此,RubberDuckquack作为Duck

这正是继承的用途。否则,会有什么用?

如果覆盖方法,则必须调用base.Quack(),如果仍然需要与基类相同的行为。 不覆盖该方法与:

相同
public void Quack()
{
    base.Quack();
}

因此,覆盖该方法的唯一原因是更改或扩展它。

聚合的行为可能更符合您的预期,例如:

public interface IDuck
{
    void Quack();
}


public class RubberDuck : IDuck 
{
    private readonly Duck duck = new Duck();

    public void Quack() 
    {
        this.duck.Quack();
    }
}

VS

public class RubberDuck : IDuck 
{  
    public void Quack() 
    {
        // not doing anything, but we still need to implement the method since it's defined by IDuck
    }
}

答案 1 :(得分:1)

在那本书中,只有display()方法是抽象的,基类为所有其他方法提供默认实现,如quack()swim()等。所以它更像是:

class Duck
{
    swim() {
        // do some swimming
    }

    quack() {
        // do some quacking
    }

    abstract display();
}

答案 2 :(得分:1)

你应该知道java中没有多重继承,所以如果你从rubbercock扩展另一个子类,如果子类quaks那么它应该在rubbercock中重写,否则子类必须定义一个新的quak方法但是不能继承/覆盖它来自rubbercock ..