简体   繁体   中英

class design: add derived class to a legacy inheritance hierarchy

Say I have

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
}

Correct me if i'm wrong, this is preferred over:

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
}

Because the latter exposes Derived1's internal to Derived2.

My question is, suppose Derived1 and Base are from an existing inheritance hierarchy and Derived1 has overridden both doA() and doB(). What would be the best way to add a new Derived2 without changing the legacy code?

Since Derived2 has the same implementation of doA() as Derived1, I have to accept the inferior second option. I thought about composition and have Derived1 as a member of Derived2, but doA() is protected so we cannot access it from Derived2.

Thanks a lot for the reply!

First, I think there is a mistake in your question: the methods doA and doB are declared as private . The child classes cannot access their parent's private methods and method overriding is impossible.

In your example, if you call Derived1.foo() , only Base.doA() will be called.

You should declare them as protected in order to allow methods overriding.

In that case, the second option is acceptable in my opinion but it depends of the actual 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
{
    @Override
    protected void doB(){...} //implementation for Derived1
}
Class Derived2 extends Base
{
    @Override
    protected void doB(){...} //a different implementation for Derived2
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM