Reputation: 261
I have two classes that are subclasses of an abstract class A
:
class X extends A {}
class Y extends A {}
I would like to identify the subclass of an A
object passed to a function. I can see two alternatives:
void myfunction(A myobj) {
if(myobj instanceof X)
doXStuff((X) myobj);
if(myobj instanceof Y)
doYStuff((Y) myobj);
}
or add an enum
to A
with the different types:
abstract class A {
enum Type { X, Y };
Type type;
...
}
class X extends A {
type = Type.X;
...
}
class Y extends A {
type = Type.Y;
...
}
void myfunction(A myobj) {
if(myobj.type == Type.X)
doXStuff((X) myobj);
if(myobj.type == Type.Y)
doYStuff((Y) myobj);
}
Which is better? I am leaning towards the second, because instanceof
doesn't feel right for a production application. Is there another, best way? If the second is better, is there a better place to put the enum
?
Upvotes: 5
Views: 1037
Reputation: 180
Short answer would be: "both are bad".
It might be a nice solution in terms of implementation, but I think it is not a nice solution in terms of design.
Particularly, it is a violation of the Single Responsibilty Principle. You put alien code into class X
and Y
, but this code belongs to the Client
, which used X
and Y
.
Another point is that you need in to use casting in both cases.
do_stuff(Object generic_data){((cast_so_special_class)generic_data).do_something_spcial_class_specific();}
Upvotes: 0
Reputation: 44449
Both are bad.
Define the method in A
, override the method in X
and Y
and call that method on the object passed in. You're throwing away polymorphism, a cornerstone of object oriented programming.
abstract class A {
void doStuff();
}
class Y extends A {
@Override
void doStuff() {
// Y specific implementation
}
}
class X extends A {
@Override
void doStuff() {
// X specific implementation
}
}
Call it using
void myfunction(A myobj) {
myobj.doStuff();
}
Upvotes: 7