What is the point of AbstractClassWithoutAbstractMethod
?
#3044
-
This is less an issue / bug and more a support question: what is the point of the I can find no literature outside of PMD that would explain why declaring a class abstract without abstract methods is a code smell. Furthermore, why is it preferable to make the constructor of such a class protected rather than making the class abstract, especially if the class does indeed have concrete sub-classes? In addition, a class with a protected constructor is still instantiable via reflection while an abstract class is not. Marking a class |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
Thanks for the question. Reading the description of the rule, it seems, the rule was created based on a specific experience: Abstract class without any methods (neither abstract nor concrete) but apparently with fields (like in the given example): public class abstract Example {
String field;
int otherField;
} I guess, this abstract class was used as the base class for inheriting a common data structure, so that every subclass e.g. has a "field" property. The rule suggests to use a "simple data container" instead - which changes the class design from inheritance to composition. Every class could have an own instance of this data container. Depending on the use case, this however might result in a DataClass. An abstract class without any methods nor fields could be replaced by a marker interface. Since in that case, the abstract class was clearly not created to support code/behavior sharing in a class hierarchy via inheritance, but just to establish a "is-a" relationship between different types. I'd suggest to read through Composition vs. Inheritance: How to Choose? since there is no answer, that would satisfy all use cases.
These are two different way in how to prevent creating instance of this type from other places in the code (without taking reflection into consideration). If you have a class with a private constructor, you either creating a UtilityClass or you are providing specific factories or builder, so that the creation of the instances is in full control. E.g. there is only one place in the code, which can create instances of this specific type. And this place can guarantee that the instances are e.g. validated, are reused (enforcing singletons), and so on.
I would emphasize the second part of your statement: Making a class abstract clearly communicates that it is supposed to have sub-classes. That you can't instantiate abstract classes is merely a side-effect. Hope this helps understanding the rule better. Let me know, if you have further questions. All: Feel free to chime in. |
Beta Was this translation helpful? Give feedback.
-
I believe the point of having an abstract class is to mark it as "incomplete", therefore, having no reason to instantiate it. However, when an abstract class provides no abstract methods, it's unclear what's missing for it to be complete and usable. What particular behavior is it missing? This lends itself to think the class may not be actually incomplete, but the non-instantiability is arbitrary / artificial and not part of a pure Object Oriented Design (ie: getting an Hibernate mapping right). An abstract class with no abstract methods can be simply constructed with an empty anonymous class In my humble opinion, this is a hint that the class should be instantiable; and use composition into larger objects which may share a marker interface (possibly not a marker actually, as at least a getter on the no-longer-abstract class is probably needed). |
Beta Was this translation helpful? Give feedback.
I believe the point of having an abstract class is to mark it as "incomplete", therefore, having no reason to instantiate it.
However, when an abstract class provides no abstract methods, it's unclear what's missing for it to be complete and usable. What particular behavior is it missing? This lends itself to think the class may not be actually incomplete, but the non-instantiability is arbitrary / artificial and not part of a pure Object Oriented Design (ie: getting an Hibernate mapping right).
An abstract class with no abstract methods can be simply constructed with an empty anonymous class
new MyAbstractClass() {}
. Why is this valid whennew MyAbstractClass()
is not? How is this any di…