我有这个课程:
public abstract class Parent {}
public class Child extends Parent{}
我创建了类Connector,我希望T类型将采用Parent的子类:
public class Connector <T extends Parent>{
T t;
public Connector(T t){
this.t=t;
}
public T getObject(T t){
Child p = new Child();
return (T) p;
}
}
实现:
Child c1 = new Child();
Connector<Parent> cConnector = new Connector<Parent>(c1);
Child c2 = cConnector.getObject(c1);
一切都与演员合作,但我不明白为什么我必须在getObject
方法中添加一个强制转换,如果T扩展为父
答案 0 :(得分:0)
您在Child p
中引入的本地T
变量与通用类型Connector
之间没有任何关联。 T t
方法中未使用字段T t
和参数getObject
,因此需要显式cat。
如果您提供以下getObject
实施:
public T getObject(){
return t;
}
不再需要演员了。
答案 1 :(得分:0)
问题是T
假定与Child
类没有任何关联。创建另一个名为Pet
的类,其扩展为Parent
,
public class Pet extends Parent{
...
}
现在让我们重新审视您的getObject
方法。用Pet
,
总的来说,我们现在有了
Pet p = new Pet();
Connector<Pet> cConnector = new Connector<Pet>(p);
在Connector类中,
//** symbol is used as placeholder, not actually part of the code
public *Pet* getObject(*Pet* t){
Child p = new Child();
return (*Pet*) p;
}
需要演员表的原因是无法保证Pet
和Child
相关。如果省略了强制转换,那么当返回类型为Child
时,将返回类型为Pet
的对象,这会导致错误,因为Pet
不等于{{1} }。如果你想返回Child
类型的新对象,那么我建议你做这样的事情(因为你之前没有使用它,所以可以省略参数),
Child
或
public Child getObject(){
Child p = new Child();
return p;
}
答案 2 :(得分:0)
在getObject
方法中,当结果应为Child
的任何子项时,您创建Parent
的实例。如果您尝试将其与任何其他类型AnotherChild extends Parent
解决此问题的方法是为子对象传递工厂方法。
public class Connector <T extends Parent>{
Supplier<T> factory;
T t;
public Connector(T t, Supplier<T> factory){
this.t=t;
this.factory = factory;
}
public T getObject(T t){
return factory.get();
}
}
然后用法看起来像
Child someChild = new Child();
Connector<Child> connector = new Connector<>(someChild, Child::new);
答案 3 :(得分:0)
你是什么意思&#34;一切都适合演员&#34;当然,它有效,但它容易出错,顺便说一句,你使用泛型,错误的方式。
当你写作时:
TestOne
这意味着您的类接受作为Parent子类的每个类型T.为了使其更清晰,请参阅此代码:
<T extends Parent>
因为在你的课程定义中,你明确表示你接受从水果延伸的类型,所以不必担心从你的水果篮中添加或检索到的obj(不需要施法),如果有人试图要将dog添加到您的fruitbasket中,他将获得编译时异常,您可以捕获并修复它并防止运行时异常。