Reputation: 91
(I'm a novice developer still learning best practices and java - any help/direction would be appreciated, thank you!)
Suppose I have the following situation:
ClassA
extends abstract ClassB
which extends abstract ClassC
.ClassD
extends abstract ClassE
which extends abstract ClassF
which extends abstract ClassC
.[ClassC
is the parent class]
where ClassA
and ClassD
have a set of identical properties, getters, & setters.
I want to avoid that code duplication (properties,getters,setters). I also want to avoid writing different methods doSomething(ClassA class, ...)
and doSomething(ClassD class, ...)
that are identical in all but the argument type.
If these two classes inherited directly from ClassC
, I'd have them extend a class that had all the getters and setters and properties, and pass that type into the method doSomething(..)
. Since ClassA
and ClassD
can't extend multiple classes, what's the best way to deal with this situation?
Upvotes: 2
Views: 1820
Reputation: 61969
First of all, let me say that it is very good when a (by their own admission) novice developer is concerned about issues of this kind. Most developers refrain from thinking, and just write lots and lots of mindless code because this is the path that they know will work, no thinking necessary. (And having to maintain all that code never seems to be much of a problem because... it lies so far in the future!)
The approach that most Java shops follow is to avoid inheritance, because it is too complicated, and use composition instead, which also results in lots and lots of mindless code having to be written. More often than not, this is done due to a misinterpretation of the advice that said "favor composition over inheritance" as if it said "use only composition, never use inheritance".
I do not know exactly what you are working with, so I cannot advice you to drop what you are doing and use composition instead. I will just assume you have your reasons for using inheritance, so, I will not write more about composition here; if you are interested to learn more about composition, the term "composition vs. inheritance" can easily be googled.
Judging by the class structure you described, you seem to be in the typical kind of situation that would greatly benefit from the use of interfaces: In Java, a class cannot extend multiple classes, but it can implement multiple interfaces.
If two interfaces both define a method like reticulate( Spline s )
, and a class implements both of those interfaces, then it can provide a single implementation of reticulate()
, and it will satisfy both interfaces. (The disadvantage of this is that if you want your class to provide a different implementation of reticulate()
for each interface, you are stuck; it cannot be done.)
Furthermore, Java supports default
methods in interfaces, which means that a certain part of the functionality you need to offer can be coded straight into the interfaces, so that implementing classes inherit this functionality from the interface and therefore do not have to re-implement it.
Upvotes: 2
Reputation: 1254
You should really discuss the abstract classes here. How are you going to test A, B, and C, D, E, and F?
That will include a lot of duplicate testcases for any method implemented by C (since it is also used by all other classes), etc.
As has been said, really discuss composition over inheritance. A might have a C, and pass through methods. It might also have a Q, and so will D.
Both D and A can then implement the same interface (possibly also implemented by Q, although that would probably make it confusing)
Be aware, I'm not a fan of abstract classes, and prefer to use composition and/or strategies instead.
Upvotes: 0
Reputation: 11557
you can do like
class M
class A extends B
inherit B's stuff
class D extends E
inherit E's stuff
A b = new A();
D d = new D();
// or use anonymous classes
M has access to everything in A and D,
therefore M has access to A and D inheritable assets.
Now add you common method in C class
Upvotes: 0
Reputation: 953
Seems to me that it might be useful to have a ClassAD
, that extends ClassC
and contains the methods common to ClassA
and ClassD.
Another option is to create an interface InterfaceAD
and have ClassA
and ClassD
implement it. Use the interface as a parameter to the functions, like doSomething(InterfaceAD i)
Upvotes: 0
Reputation: 1209
I'm not sure if I understood your problem correctly but I'll give it a try. Instead of multiple abstract classes, create multiple interfaces. Then create a class that implements both interfaces. Java allows implementing multiple interfaces but not extending from multiple classes.
Upvotes: 0