Why is programming for abstract classes rather than interfaces wrong?

I was looking at the differences between Struts1 and Strust2, I found out that, A common problem in Struts 1 is programming abstract classes instead of interfaces.

Can someone please let me know: why is programming abstract classes instead of interfaces a problem?


source to share

10 replies


Programming for an abstract class is not a problem at all , it depends on how you create your relationship with objects.


An abstract class provides partial implementation that encourages code reuse, while an interface only provides methods without any implementation that encourages encapsulation.

So when is the acronym used?

You should use an abstract class if a specific implementation does not match its subclass and the other part of the behavior is the same for the entire subclass.



In Java, one of the reasons is that you don't have multiple inheritance, so the moment you extend an abstract class, you cannot extend others.

The only way to get around this is through a complex dependency tree, which is very bad for your architecture in the long run (it will be very difficult for you to quickly figure out what depends on it).

If your class C needs to expose the interface of an abstract class AC (interface in the broadest sense of the word), you can make class C an extension of AC. But now you also want your C class to expose the interface of another AC1 class ... and there is no easy way to do that. You either have to resort to composition (which I prefer to extend) or you have to make AC1 an AC extension ... or some other weird voodoo to get this to work.

In my opinion, architectural clarity and extensibility are the main reason why you prefer to use interfaces instead of abstract classes to compose your solution. There's also a question about how reliable your code can be. If you are extending a class from an external package / jar, you may be dependent on that particular implementation version, as changes to the abstract class might break your code.

On the other hand...

Not everything is ideal for use in an Interface. In some cases, trying to be a purist and exclusively use interfaces without any extensions can lead to some unnecessary code duplication. There really is no magic rule.

To address this issue and still maintain flexibility (without only compromising your available extensions), you can reuse code through composition instead of inheritance. Implement an interface, have a class with a common code base, make your "inherited" methods (from the interface), proxies for that common class (which will become an attribute of your class), and you have the best of both worlds.

Finally, my goal as a developer (especially in Java) is to one day be able to express my opinion that Joshua Bloch had no better idea before, so far I have not done so, so I leave this effective Java link that explains this last point is much better than I can:

Effective Java



I'm not familiar with Struts, so I can't comment on the specific problems of Struts 1. However, in general, abstract classes also include an implementation that an interface cannot. it

  • creates more dependencies, which can hurt maintainability and reuse,
  • makes them less resistant to change, which in turn can unexpectedly break the client code,
  • Last but not least (as @pcalcao rightly pointed out), this approach disallows inheritance from another class.


Wrong can be too strong word. Context always matters.

Why either / or? Can't you do both? Write an interface and provide an abstract implementation with default behavior, la java.util collections.

You can only inherit the implementation; interfaces allow multiple inheritance. Thus, this may be one of the reasons for the preference for interfaces. Another is that you cannot always use the default behavior.

Take Struts with a grain of salt. Struts 1 was the first MVC Web Model 2 back in 2000-2002. It has not benefited everything that has been studied since then (eg Joshua Bloch and Effective Java). Struts 2 was not radical enough to be rewritten because it had to be backward compatible.

I wouldn't hold back Struts as an example of good design or best practices. Look elsewhere.



There is a brilliant question with answers on SO on "interface programming":

What does "program to interface" mean?

This doesn't answer the question, but all the benefits described in the answers are lost with abstract classes because they (can) provide (partial) implementations.



This link can help you choose when programming by interface or abstact class: Interfaces and Abstract Classes



You can have the best of both worlds if you have abstract classes that implement an interface; instead of subclassing an abstract class, you can implement an interface. This way you can still subclass a different class.



there is nothing wrong with using abstract classes, but it might not be the best solution

an abstract class can partially implement methods, and an interface does nothing more than declare methods

When the need arises to implement an implementation, use abstract classes. Or they both define an interface AND (partially) implement a (abstract) class that implements that interface



In a nutshell and conceptually, it is often described as:

  • abstract classes: IS-A
  • : HAS-A (or can-do, -able ...)

Example: The Dog class and the Cat class extend the abstract Animal class to both animals (Dog is an animal). An abstract Animal class would have methods like walk () or sleep (). The Animal class can implement the Washable interface with the wash () method. This method will be implemented for every animal, because one could use mud, water, tongue, fingers of his monkey ...

As already mentioned, interfaces allow for a great deal of modularity. They are preferred in large projects because they reduce the number of code breaks and layouts. (For example, I have to use your service, but you didn't have enough time to implement it. If we are using an interface, I can create this mock-impl with the getProductId () method, which always returns the same number. You are done, we let's assume my layout is your actual service.). Mocks is great for testing.

Practical examples:



If an abstract class does not provide public fields directly, if you define an interface that includes all the public members of an abstract class and implements its class, then you can do almost anything with a variable or parameter type interface that you can do with an abstract class type. On the other hand, if the need arises to define a type that can do everything that an abstract class can do, but which derives from some other base class, that type will be used with subroutines that expect parameters of the interface type, but not those that which expect an abstract class type.

In short, a variable or parameter of an interface type is in some sense superior to one abstract type that implements the interface and has the same public members; it is almost in no way inferior. Therefore, you should use an interface type that is missing for a good reason in order not to.



All Articles