Frage

I have a Super class and some Sub class that extend the super class. Every sub class have some constructor methods that accept a type of any Sub type.

abstract class Super {}
    final class Sub1 extends Super {
        public Sub1(Sub1 arg) {}
        //...
        public Sub1(Sub4 arg) {}
    }
    //...
    final class SubN extends Super {
        public SubN(Sub3 arg) {}
        //...
        public SubN(SubN arg) {}
    }
}

Now I want to create a method in the Super class to cast from one Sub type to another. Let's say

public Super cast(Super arg) {
    if (arg instanceof Sub1)  {
        return new Sub1(this);
    } else if (arg instanceof Sub2) {
        return new Sub2(this);
    }//...
    return null;
}

It would be stupid to repeat this pattern for all the sub classes. A solution that I found out is this one (using reflection) but is too slow.

public Super cast(Super arg) {
    try {
        Class<? extends Super> type = arg.getClass();
        return type.getConstructor(this.getClass()).newInstance(this);
    } catch (Exception e) {
        return null;
    }
}

Are there alternatives?

War es hilfreich?

Lösung

Why not do the reverse? Instead of super.cast(sub) do sub.copy(super) Example:

class Sub1 extends Super {
    public Super copy(Super input) {
        return new Sub1(input);
    }
}

class Sub2 extends Super {
    public Super copy(Super input) {
        return new Sub2(input);
    }
}

etc.

This is called in nearly the same way and prevents having any if statements, and gets exactly the same functionality.

If your old code was:

void doSomething(Super super, Super iAmActuallyASub) {
    Super superDuper = super.cast(iAmActuallyASub);
}

The new code would be

void doSomething(Super super, Super iAmActuallyASub) {
    Super superDuper = iAmActuallyASub.copy(super);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top