GAlexMES
GAlexMES

Reputation: 355

Using class method inside generic function

Situation:

I want to write a generic function like the following:

public <T> void do(T para){
   para.something();
}

Question: I want to give instances of two different classes to the do() function. Both classes are coming from an library, which has a bad design. Both classes have a something() method. But they are not implementing the same interface or extending the same superclass.

My First though:

I could write something like:

if(para instanceof A){
    ((A)para).something();
else if(para instanceof B){
    ((B)para).something();
}

I guess that would work, but I need to call something() more often and dont want to spam my code with this if/else. Has anyone a good clue? Thanks in advance!

Upvotes: 2

Views: 84

Answers (2)

Bene
Bene

Reputation: 734

Since you can't change the existing library you could make your own interface:

public interface SomeInterface {
    void doSomething();
}

public class C extends A implements SomeInterface {
    @Override
    public void doSomething() {
        this.something();
    }
}

public class D extends B implements SomeInterface {
    @Override
    public void doSomething() {
        this.something();
    }
}

public <T extends SomeInterface> void do(T param) {
    param.doSomething();
}

As mentioned in the comments it might be better to not extend A and B, but keep instance variables of A and B in your wrapper class:

public class C implements SomeInterface {

        private A a;
        public C(A a) { this.a = a; }

        @Override
        public void doSomething() {
            a.something();
        }
}

Also, with Java 8 this might be an easier solution:

@FunctionalInterface
public interface SomeInterface {
        void doSomething();
}
public <T extends SomeInterface> void do(T param) {
    param.doSomething();
}
do(p -> a.something());

Upvotes: 3

wake-0
wake-0

Reputation: 3966

Extend and interface approach:

public interface ISomething {
    public void mySomething();
}

public ExtendA extends A implements ISomething {
    public void mySomething() { something(); }
}

public ExtendB extends B implements ISomething {
    public void mySomething() { something(); }
}

or like mentioned in the comments with a wrapper:

public interface ISomething {
    public void something();
}

public WrapperA implements ISomething {
    private A a;

    WrapperA(A a) {
       this.a = a;
    }

    public void something() {
        return a.something();
    }
}

public WrapperB implements ISomething {
    private B b;

    WrapperB(B b) {
       this.b = b;
    }

    public void something() {
        return b.something();
    }
}

A instanceOfA = ...;
ISomething some = new Wrapper(instanceOfA);
some.something();

another approach would be reflection, which is not as fast as the other approaches I suppose:

A instanceOfA = ...;
methodName = "something";
Method somethingMethod = instanceOfA.getClass().getMethod(methodName);
somethingMethod.invoke(instanceOfA);

Upvotes: 2

Related Questions