简体   繁体   English

Java接口 - 泛型

[英]Java interface - Generics

I have two interfaces. 我有两个接口。 An interface A, and interface B, which extends interface A. Now, I have class which likes to keep reference of object that either implements A or B. And I would like to provide setter for it. 接口A和接口B,它扩展了接口A.现在,我有一个类,它喜欢保持实现A或B的对象的引用。我想为它提供setter。 I tried below, but getting type mis match exception. 我试过下面,但是获得类型错误匹配异常。

public interface A {
}

public interface B extends A {
}

public class AB {
private Class<? extends A> object;

public void setObject(Class<? extends A> o){
   this.object = o;
}
}

So basically, I would like setObject method to accept an object that either implements interface A or B. 基本上,我希望setObject方法接受一个实现接口A或B的对象。

Simple answer: 简单回答:

Type it as A : setObject(A a) . 输入AsetObject(A a)

A class that implements B also implements A . 实现B的类也实现了A Full code: 完整代码:

public class UsesA {
  private A a;

  public void setObject(A a){
    this.a = a;
  }
}

Now, if you really want to work with B , you'd type it as B , which would also allow you to treat it as an A , since B inherits from it: 现在,如果你真的想和B一起工作,你可以把它键入B ,这也可以让你把它当成A ,因为B继承了它:

public class UsesB {
  private B b; // can call A's methods on this field

  public void setObject(B b) {
    this.b = b;
  }
}

But now you can't pass an A (static) reference to setObject . 但是现在你无法将一个A (静态)引用传递给setObject If you really want to do this, then you'd need to first downcast it as a B , which could fail at runtime. 如果你真的想这样做,那么你需要首先将它作为B转发,这可能会在运行时失败。 Generics will not improve on this. 泛型不会改善这一点。

If you have an object implementing B , it will also be an instance of A . 如果您有一个实现B的对象,它也将是A的实例。 Because of this, you can make setObject accept any A , which will allow instances of A or B to be passed to it. 因此,您可以使setObject接受任何A ,这将允许将AB实例传递给它。

public void setObject(A a){
    this.object = a;
}

Your code doesn't actually match up with your question. 您的代码实际上与您的问题不符。 You've stated that 你说过了

I have class which likes to keep reference of object that either implements A or B 我有一个类,它喜欢保持实现A或B的对象的引用

but the field (called object ) is actually a Class, not an Object (instance of a Class). 但是字段(称为object )实际上是一个类,而不是一个Object(类的实例)。

Your code works if you were truly trying to have your setter accept any interface that extends A. But as you probably realize now from the other answers, you actually want an instance of A :) 如果你真的试图让你的setter接受任何扩展A的接口,那么你的代码是有效的 。但是你现在可能从其他答案中意识到,你实际上想要一个A :)的实例

public class AB {
    private Class<? extends A> type; // renamed from object for clarity

    public void setObject(Class<? extends A> type) {
        this.type = type;
    }

    @Test
    public void testSetter() {
        setObject(A.class); // no errors
        setObject(B.class); // no errors
    }
}

如前所述,如果您将使用(A a)它将起作用,因为B是A的类型。因此,子类始终可以表示它的父类。

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

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