[英]Generic behaviour
(对不起,双关语)
假设有人想定义一个通用生成器,如下所示:
public abstract class GenericBuilder<T extends Product> {
int x;
int y;
<K extends GenericBuilder<T>> K setX(int x) {
this.x = x;
return (K)this;
}
<K extends GenericBuilder<T>> K setY(int y) {
this.y = y;
return (K) this;
}
abstract T build();
}
abstract class Product {
int x;
int y;
}
class ConcreteProduct extends Product {
int z;
}
class ConcreteBuilder extends GenericBuilder<ConcreteProduct>{
int z;
<K extends GenericBuilder<ConcreteProduct>> K setZ(int z) {
this.z = z;
return (K) this;
}
@Override
ConcreteProduct build() {
ConcreteProduct cp = new ConcreteProduct();
cp.x = x;
cp.y = y;
cp.z = z;
return cp;
}
public static void main(String[] args) {
new ConcreteBuilder().setX(1).setY(2).setZ(3);
}
}
调用ConcreteBuilder.setZ()时,编译期间将失败。
这是为什么? 是否应删除? 还是说泛型不携带有关其泛型参数的信息?
编辑:
任何想法如何避免在以下情况中使用第二个通用参数:
public class ConcreteBuilder extends GenericBuilder<ConcreteProduct, ConcreteBuilder>
即<...,ConcreteBuilder>,这似乎有点笨拙? 我想这是不可能的。 是否有其他语言(可能是C#?)允许这样做?
以这种方式破坏代码,您将了解您的类GenericBuilder<ConcreteProduct>
没有定义任何setZ()方法。
GenericBuilder<ConcreteProduct> setY = new ConcreteBuilder().setX(1).setY(2);
setY.setZ(3);
在你GenericBuilder
你的函数返回一个GenericBuilder
时不指定函数的类型参数。 在您的主函数中,对setX
的调用将返回GenericBuilder
,您将丢失实际上正在使用ConcreteBuilder
。 要成功进行调用,您必须为设置器指定通用参数:
new ConcreteBuilder().<ConcreteBuilder>setX(1).<ConcreteBuilder>setY(2).setZ(3);
您可以向GenericBuilder
添加第二个类型参数:
public abstract class GenericBuilder<T extends Product, K extends GenericBuilder<T, K>> {
int x;
int y;
K setX(int x) {
this.x = x;
return (K)this;
}
K setY(int y) {
this.y = y;
return (K) this;
}
abstract T build();
}
并将ConcreteBuilder
更改为:
public class ConcreteBuilder extends GenericBuilder<ConcreteProduct, ConcreteBuilder> {
int z;
ConcreteBuilder setZ(int z) {
this.z = z;
return this;
}
@Override
public ConcreteProduct build() {
ConcreteProduct cp = new ConcreteProduct();
cp.x = x;
cp.y = y;
cp.z = z;
return cp;
}
public static void main(String[] args) {
new ConcreteBuilder().setX(1).setY(2).setZ(3);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.