0
votes

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!

1

1 Answers

0
votes

First, I think there is a mistake in your question: the methods doA and doBare 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 protectedin 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
}