我想编写一个应该使用特定类型对象的通用服务。当我编写该服务的自定义实现时,我想反对变量。因此,我想覆盖创建该对象的方法。
但它不会奏效。在java中无法实现以下目标吗?
class MyService<T extends Foo> {
//Type mismatch: cannot convert from Foo to T
public T createObject() {
return new Foo();
}
public void run() {
T t = createObject();
//work with the object
}
}
class Bar extends Foo;
class CustomService<Bar> {
@Override
public Bar createObject() {
return new Bar();
}
}
答案 0 :(得分:2)
问题是您提供的返回Foo
的默认实现。该实现不适用于子类,并且无法强制子类重写。
您应该有MyService<T>
和abstract T createObject()
。对于Foo
,请创建一个Foo
特定的子类FooService<Foo>
。
答案 1 :(得分:2)
class NewArrayList extends ArrayList {
}
abstract class MyService<T> {
public abstract T createObject();
public void run() {
T t = createObject();
//work with the object
}
}
class CustomService extends MyService<NewArrayList> {
@Override
public NewArrayList createObject() {
return new NewArrayList();
}
}
答案 2 :(得分:1)
正确;你不能这样做。您的T
泛型参数代表“某个类,它是Foo
的子类”(其中类是其自身的子类)。您不能完全认为它 Foo
,因为它可能是一个扩展Foo
的类。
考虑一下:如果你有一个班级Bar extends Foo
并且你做了:
MyService<Bar> service = ...
Bar myBar = createObject();
然后您的代码会创建一个Foo
并尝试将其向下转换为Bar
,从而产生ClassCastException
。泛型的全部意义在于避免错误的强制转换及其产生的异常。