Dia McThrees
Dia McThrees

Reputation: 261

Type variable vs instanceof for identification

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

Answers (2)

Robin Kreuzer
Robin Kreuzer

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

Jeroen Vannevel
Jeroen Vannevel

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

Related Questions