简体   繁体   English

如何根据类型的泛型调用方法?

[英]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? 如何根据票证的类型( AB )等升级票证?

Why does Ticket know anything about what update actually means. Ticket为何不知道更新的实际含义。 It just needs to forward the call to an instance of MySuperClass . 它只需要将调用转发到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();
  }
  /* ... */
}

update() is an instance method, so you will need an instance to call it. update()是一个实例方法,因此您将需要一个实例来调用它。 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(). 由于多态性,它将从A或B调用正确的方法。但是要以一种更加面向对象的方式解决该问题,您应该将一个实例传递给Ticket构造函数,而只需调用update()。

I've tweaked your example so that it makes more sense ... and implemented update . 我已经对您的示例进行了调整,以使其更有意义...并实现了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. update方法调用t.update() ,它将多态地分派到t引用的实际对象的update方法。 Note that I added code to create and store the instance of Class<T> . 请注意,我添加了代码来创建和存储Class<T>的实例。

UPDATE - I've added the exceptions to the Ticket constructor. 更新 -我已将异常添加到Ticket构造函数。 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. 这是您使用反射来创建实例的价格的一部分……而不是使用new来创建实例并将其作为参数传递。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM