Question

I have an interface A, for which I have to supply a few different implementations. However, those implementations share some helper methods, so I moved those methods to an abstract base class.

Interface A {
    void doX();
}

abstract Class B implements A {
    protected void commonY() {
        // ...
    }

    @Override
    public abstract void doX();
}

Class C extends B {
    @Override
    public void doX() {
        // ...
    }
}

Class D extends B {
    @Override
    public void doX() {
        // ...
    }
}

My code works as expected, but I have a few questions:

  • Should I declare the abstract Method doX() in Class B? Why (not)?

  • Should I also explicitly declare "implements A" on Class C and D? Why (not)?

Was it helpful?

Solution

I think it would be better to do it as follows:

Interface A {
        void doX();
}

abstract Class B {
        protected void commonY() {
                // ...
        }
}

Class C extends B implements A{

        public void doX() {
                // ...
        }
}

Class D extends B implements A{

        public void doX() {
                // ...
        }
}

You shouldn't mix the interface (signature of methods) with the implementation.

OTHER TIPS

  • Should I declare the abstract Method doX() in Class B? Why (not)?

No. It's an abstract class - defining the interface will mean that all subclasses will need to implement those methods. In other words, it's redundant.

  • Should I also explicitly declare "implements A" on Class C and D? Why (not)?

No, again - because your superclass (Abstract base class) implements that interface, your concrete subclasses will be guaranteed to implement that interface.

I'll just throw in the other option.

Turn abstract class B into an AUtil class that doesn't implement A. The method signatures may require an additional argument of type A to work with.

C and D implement A, and instantiate an AUtil internally. This does allow C and D to extend other classes.

I agree with JeeBee: consider implementing your helper methods somewhere other than an abstract base class.

If your helper method commonY() only exists in abstract base class B, all classes which implement Interface A will have to also extend base class B in order to take advantage of that implementation of commonY(). But, you might not always want to be forced to extend class B.

Also, what if you want to change the implementation of commonY() in the future? You will then affect lots of implementations of interface A. But if you don't control all these implementations of interface A, you may affect their functionality (in a bad way) without intending to.

Using an abstract base class in this situation may simply take away some flexibility without giving you anything in return.

An abstract class implementing an interface must implement that interface. Specifically, it must have a public method for every method-name-and-signature specified in that interface.

Inheritance is transitive. You do not need to write that class C implements interface A if class C derives class B which implements interface A. However, there isn't much harm to it either.

I would not declare doX() in B and not add "implements A" on C and D because you should not repeat yourself.

The abstract doX() in B adds nothing, as it's already specified by "implements A". The same is true for adding "implements A" to C and D.

The only possible use for those clauses would be documentation: If you want to make it very explicit that C (or D) is-a A, then you could add the implements, but you should be aware that it really doesn't matter to the compiler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top