It's perfectly normal to use these two together. Consider for instance AbstractList
(implementing List
) and AbstractMap
(implementing Map
) in the JDK.
My knee-jerk reaction would have been to have the abstract class implement the interface and then have the concrete classes derive from it:
abstract class Base implements TheInterface {
/* ...shared methods... */
}
class Concrete1 extends Base { }
class Concrete1 extends Base { }
But your question raising the other possibility made me think, and I can't see much of an argument against doing it that way:
abstract class Base {
/* ...shared methods... */
}
class Concrete1 extends Base implements TheInterface { }
class Concrete1 extends Base implements TheInterface { }
Further, I can see an argument for doing it that way, specifically that it removes the coupling between the abstract class and the interface. If you have another class that needs the functionality Base
provides but doesn't need to implement the interface, you have the flexibility to do that.
There's also a third option: Composition. You could not have an abstract class at all, but rather have the multiple concrete classes that implement the interface use a common helper class in their implementation:
class Helper {
/* ...shared methods... */
}
class Concrete1 implements TheInterface {
/* ...uses instance of Helper */
}
class Concrete1 implements TheInterface {
/* ...uses instance of Helper */
}
This has that same flexibility, in another form.