类设计:将派生类添加到遗留继承层次结构中

时间:2016-03-31 08:45:19

标签: java inheritance legacy-code

说我有

Class Base
{
    public void foo() //a public interface to user
    {
        doA();
        doB();
    }
    protected void doA(){...} //common implementation
    protected void doB(){} //type specific implementation
}
Class Derived1 extends Base
{
    int a,b,c,d,e,f,g; //bulky, clumsy implementation details specific to Derived1
    @Override
    protected void doB(){...} //implementation for Derived1
}
Class Derived2 extends Base
{
    @Override
    protected void doB(){...} //a different implementation for Derived2
}

如果我错了,请纠正我,这是首选:

Class Derived1 extends Base
{
    int a,b,c,d,e,f,g; //bulky, clumsy implementation details specific to Derived1
    @Override
    protected void doA(){...} //move the common implementation to Derived1
    @Override
    protected void doB(){...} //implementation for Derived1
}
Class Derived2 extends Derived1
{
    @Override
    protected void doB(){...} //a different implementation for Derived2
}

因为后者将Derived1的内部暴露给Derived2。

我的问题是,假设Derived1和Base来自现有的继承层次结构,Derived1已经覆盖了doA()和doB()。在不更改遗留代码的情况下添加新Derived2的最佳方法是什么?

由于Derived2与Derived1具有相同的doA()实现,因此我必须接受劣质的第二个选项。我考虑过组合并将Derived1作为Derived2的成员,但doA()受到保护,因此我们无法从Derived2访问它。

非常感谢您的回复!

1 个答案:

答案 0 :(得分:0)

首先,我认为您的问题存在错误:方法doAdoB被声明为private。子类无法访问其父级的私有方法,并且方法覆盖是不可能的。

在您的示例中,如果您致电Derived1.foo(),则只会调用Base.doA()

您应该将它们声明为protected,以便允许方法覆盖。

在这种情况下,我认为第二种选择是可以接受的,但这取决于实际的代码。

Class Base
{
    public void foo() //a public interface to user
    {
        doA();
        doB();
    }
    protected void doA(){...} //common implementation
    protected void doB(){} //type specific implementation
}
Class Derived1 extends Base
{
    @Override
    protected void doB(){...} //implementation for Derived1
}
Class Derived2 extends Base
{
    @Override
    protected void doB(){...} //a different implementation for Derived2
}