Java 泛型类之间的依赖关系
我有以下接口:Java 泛型类之间的依赖关系,java,generics,Java,Generics,我有以下接口: public interface Assembler<T, S> { S assemble( T val); } public interface Slicer<T, V> { V[] slice(T val); } 公共接口汇编程序{ S组装(T-val); } 公共接口切片器{ V[]切片(T值); } 我想让汇编器实例使用切片器实例并调用它的slice()。我有以下资料: public class MyAssembler<T,
public interface Assembler<T, S> {
S assemble( T val);
}
public interface Slicer<T, V> {
V[] slice(T val);
}
公共接口汇编程序{
S组装(T-val);
}
公共接口切片器{
V[]切片(T值);
}
我想让汇编器实例使用切片器实例并调用它的slice()。我有以下资料:
public class MyAssembler<T, S> implements Assembler<T, S> {
private final Slicer<T, V> slicer;
//ctor
public MyAssembler() {
slicer = new MySlicer<T, V>();
}
@Override
public S assemble(T val) {
V[] v = mySlicer.slice(val);
}
公共类MyAssembler实现汇编程序{
私人最终切片机;
//执行器
公共MyAssembler(){
切片器=新的MySlicer();
}
@凌驾
公众集会(T val){
V[]V=mySlicer.slice(val);
}
这不会编译,因为V类型未知(无法解析为类型)在MyAssembler中。我无法将Assembler接口更改为
Assembler
。是否有其他方法可以定义依赖项?这不是非泛型类的问题。即使使用静态工厂方法获取对切片器的引用,未知V的问题仍然存在。有什么建议吗?如果不能这样做,可以吗我们推荐一种不同的方法或设计模式,允许汇编器调用切片器的切片()?继承将解决您的问题,而不是在这种情况下组合,如下所示:
public class MyAssembler<T,S,V> extends MySlicer<T,V> implements Assembler<T,S> {
public MyAssembler() {
}
@Override
public S assemble(T val) {
V[] v = this.slice(val);
...
}
}
公共类MyAssembler扩展MySlice实现汇编程序{
公共MyAssembler(){
}
@凌驾
公众集会(T val){
V[]V=此.slice(val);
...
}
}
汇编程序是否总是将切片器作为其两个泛型之一?如果是,您只需要定义一个泛型,并将切片器作为非泛型成员变量
但是,如果泛型类型可能是切片器,也可能不是切片器,那么当其中一个类型是具有反射的切片器时,可以实现特殊处理,尤其是
If(v instanceof Slicer)
,如果为真,则将其转换为切片器。由于您的S
和V
是泛型的,因此您可以将它们转换为任何其他类型,甚至其他泛型。您可以执行以下操作:
public class MyAssembler<T, S> implements Assembler<T, S> {
private final Slicer<T, S> slicer;
public MyAssembler() {
slicer = new MySlicer<T, S>();
}
@Override
public S assemble(T val) {
S[] v = slicer.slice(val);
return v[0]; // for example
}
}
公共类MyAssembler实现汇编程序{
私人最终切片机;
公共MyAssembler(){
切片器=新的MySlicer();
}
@凌驾
公众集会(T val){
S[]v=切片器切片(val);
返回v[0];//例如
}
}
我所做的是将
T
和S
定义为相同的类型。在我自己的实现中,我可以毫无问题地做到这一点。重新发布Sotirios Delimanolis的评论作为答案
要允许在MyAssembler中使用V,请声明
MyAssembler扩展Assembler
。要使用它,请使用for ex:Assembler asmblr=new MyAssembler
实例化。您可以为MyAssembler
声明第三种类型变量。我尝试使用MyAssembler
。它会编译,但一旦尝试实例化例如:Assembler asmblr=new MyAssembler
编译失败,原因是:类型Assembler的参数数量不正确;无法使用参数对其进行参数化。第三个类型参数是MyAssembler
所必需的,而不是声明的类型,Assembler
所必需的。但它在这里似乎不是很有用,因为您没有执行任何操作使用V
的nything。在实际用例中,假设将使用V。但是,您将无法通过它使用类型Assembler
的引用。切片器将不是Assembler中的泛型类型t或S之一。这可能会在假设类型始终相同的情况下起作用,但这不限制S和原始V现在是相同的t吗ype?可能希望Assember S是字符串,切片器V是整数。确实如此。但是正如您所指出的,汇编程序应该调用切片器的切片()。如果类型S和V不同,则无法保证任何内容。如何将V'强制转换为S?通过调用slice`您有一个V
,但在assemble
中,您希望返回S
。如果您希望支持任意类型,则无法执行此操作。但是:如我的示例所示,您无法选择切片器的类型。它将由汇编器的类型决定。由于切片器封装得很好,您甚至不知道在汇编器后面有什么东西可以完成这项工作。您只需使用行为类似于黑匣子的汇编器。我认为现在在汇编器中使用V更灵活:MyAssembler Extendes assembler
。