barroco
barroco

Reputation: 3108

How to call a method depending on its type generic?

Let the following code:

    public abstract class MySuperClass { 
       public abstract void update();
       /* ... */
    }

    public class A extends MySuperClass { 
       @Override
       public void update() { /* ... */ }
       /* ... */
    }

    public class B extends MySuperClass { 
       @Override
       public void update() { /* ... */ }
       /* ... */
    }

    public class Ticket<T extends MySuperClass> {
      private Class<T> c;
      public Ticket(Class<T> c){ this.c = c; }
      public Class<T> getClass() { return this.c; } 
      public void update() { /* HOW TO DO! */ }
      /* ... */
    }

    public class Main {
      public static void main(String[] args) {
        Ticket<A> myTicket1 = new Ticket<A>(A.class);
        Ticket<B> myTicket2 = new Ticket<B>(B.class);
        myTicket1.update();
        myTicket2.update();
      }
    }

How do I upgrade the tickets depending on his type (A, B), or so on?

Upvotes: 0

Views: 2232

Answers (3)

Stephen C
Stephen C

Reputation: 718926

I've tweaked your example so that it makes more sense ... and implemented update.

public class Ticket<T extends MySuperClass> {
    private Class<T> c;
    private T t;

    public Ticket(Class<T> c) throws InstantiationException, IllegalAccessException { 
        this.c = c; 
        this.t = c.newInstance();
    }

    public Class<T> getClass() { 
        return this.c; 
    } 

    public void update() {
        t.update();
    }
    /* ... */
}

The update method calls t.update() which will polymorphically dispatch to the update method of the actual object that t refers to. Note that I added code to create and store the instance of Class<T>.

UPDATE - I've added the exceptions to the Ticket constructor. This is the part of the price you pay for using reflection to create instances ... rather than creating them using new and passing them as arguments.

Upvotes: 0

unholysampler
unholysampler

Reputation: 17331

Why does Ticket know anything about what update actually means. It just needs to forward the call to an instance of MySuperClass. The whole point of generic classes is that the generic class will work with any object (or subset of objects) without having to know exactly what kind it is.

public class Ticket<T extends MySuperClass> {
  private T thing;
  public Ticket(T thing) {
    this.thing = thing;
  }
  public void update() {
    thing.update();
  }
  /* ... */
}

Upvotes: 4

Zeemee
Zeemee

Reputation: 10714

update() is an instance method, so you will need an instance to call it. This can be achieved with

getClass().newInstance().update();

Due to polymorhism, it will call the correct method from A or B. But to solve it in a more object oriented way, you should pass a instance to the Ticket constructor and just call update().

Upvotes: 0

Related Questions