[英]Java - Defining a member that extends class A and implements interface B
I have a variable that must meet two conditions, and I want to set them in the definition 我有一个必须满足两个条件的变量,我想在定义中设置它们
I know that I can define either condition with an individual variable, like in any of these examples 我知道我可以使用单个变量定义任一条件,就像这些示例中的任何一个一样
private Class<? extends A> variable; //or
private A variable; //or
private Class<? extends B> variable; //or
private B variable;
But is there a way to have the variable meet both conditions? 但是有办法让变量同时满足两个条件吗?
I was hoping for something like this 我希望有这样的东西
private Class<? extends A implements B> variable;
But I can't find any way to do this without typecasting when I need to call it or storing multiple copies of it 但是当我需要调用它或存储它的多个副本时,如果没有类型转换,我找不到任何方法
You can declare type parameters that have multiple bounds, such as: 您可以声明具有多个界限的类型参数,例如:
public static <T extends A & B> void test(Class<T> clazz)
But you cannot declare a variable that has multiple bounds: 但是您不能声明具有多个边界的变量:
private Class<? extends A & B> variable; // doesn't work
You can create an abstract
class C
that extends A
and implements B
, so that only one bound is required. 您可以创建一个
abstract
类C
,该类扩展A
并实现B
,因此只需要一个界限。
abstract class C extends A implements B {}
Then: 然后:
private Class<? extends C> variable;
While Java does not directly support intersection types like A&B
, such types do appear in type parameter bounds and capture conversions. 尽管Java不直接支持
A&B
类A&B
交集类型,但此类类型的确会出现在类型参数范围内并捕获转换。 We can express A&B
with a layer of abstraction. 我们可以用抽象层来表达
A&B
。
public class ValueAB<T extends A&B>
{
public final T v;
// constructor ...
}
public class ClassAB<T extends A&B>
{
public final Class<T> clazz;
// constructor ...
}
Instead of A&B, Class<? extends A&B>
代替
A&B, Class<? extends A&B>
A&B, Class<? extends A&B>
, we use wrappers ValueAB, ClassAB
A&B, Class<? extends A&B>
,我们使用包装器ValueAB, ClassAB
ClassAB<?> clazz = new ClassAB<>(Foo.class);
ValueAB<?> value = new ValueAB<>(clazz.c.newInstance());
value.v.methodOfA();
value.v.methodOfB();
This solution would require a wrapper for each combination of As and Bs. 该解决方案将需要针对As和B的每种组合使用包装器。
Another solution is to use only A
as type parameter bound; 另一种解决方案是仅使用
A
作为类型参数绑定; B
will be supplied by wildcard bound. B
将由通配符绑定提供。 This is probably better if you need to express multiple A&B1, A&B2, ...
types at use site. 如果您需要在使用现场表达多种
A&B1, A&B2, ...
类型,可能会更好。
public class ValueA<T extends A>
{
public final T v;
...
}
public class ClassA<T extends A>
{
public final Class<T> c;
...
}
---
ClassA<? extends B> clazz = new ClassA<>(Foo.class);
ValueA<? extends B> value = new ValueA<>(clazz.c.newInstance());
If it's confusing how wildcard works in these cases, see my article on wildcard 如果在这种情况下混淆通配符的工作方式,请参阅我的通配符文章
A 3rd solution is free of A or B at declaration site of wrappers; 在包装的声明位置,第三个解决方案不含A或B; the use site provides A and B.
使用站点提供A和B。
public class Value<T extends S, S>
{
public final T v;
...
}
public class Clazz<T extends S, S>
{
public final Class<T> c;
...
}
---
Clazz<? extends A, B> clazz = new Clazz<>(Foo.class);
Value<? extends A, B> value = new Value<>(clazz.c.newInstance());
This is however probably too confusing. 但是,这可能太令人困惑了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.