我在抽象父类中有一个通用方法,要在具体子代中重写:
家长班:
public abstract class AbstractParentDataAccess<S extends AbstractParentDataModel>
{
...
public void save(Collection<? extends S> collection) {...}
...
}
儿童班:
public class ConcreteDataAccess extends AbstractParentDataAccess<ConcreteDataModel>
{
...
// this does not compile
@Override
public void save(Collection<ConcreteDataModel> collection) {...}
// this compiles but never gets called, the parent method is being called instead
@Override
public void save(Collection<? extends ConcreteDataModel> collection) {...}
...
}
ConcreteDataModel类继承自AbstractParentDataModel:
public class ConcreteDataModel extends AbstractParentDataModel {...}
这是我调用save方法的方式:
...
@Autowired
private ConcreteDataAccess concreteDataAccess;
....
List<ConcreteDataModel> dataList = DataService.getDataList();
concreteDataAccess.save(dataList);
...
所以我的问题是:
为什么:
第一种方法不能编译吗?
是在第二个方法中调用父方法而不是子方法,如何解决?
最佳答案
鉴于您给我们提供的信息,调用父方法是不可能的。您输入了方法名(save
),或者您的调用代码在这里有问题。
请注意,在VM级别上,泛型不存在。两种方法都具有完全相同的JVM签名:save(Ljava/util/Collection;)V
-即使泛型不受欢迎,就VM而言,也是相同的方法,因此,子类中的save
会覆盖来自父母List<ConcreteDataModel>
在这里不编译,因为Collection<? extends S>
允许的类型多于List<ConcreteDataModel>
的类型。例如,这:
List<ConcreteDataModel> x = new ArrayList<SubTypeOfConcreteDataModel>();
无法编译,但这:
List<? extends ConcreteDataModel> x = new ArrayList<SubTypeOfConcreteDataModel>();
做。 (原因:您可以在
x.add(new ConcreteDataModel());
上调用List<ConcreteDataModel>
,将一些不是SubTypeOfConcreteDataModel的内容放到SubTypeOfConcreteDataModel列表中。请注意,除非您通过,否则根本无法在.add()
上调用List<? extends WhateverYouWantToWriteHere>
实际上是null
。