我有一个类和一个像这样的接口:
interface Employee {...}
class Developer implements Employee {...}
然后我有一些课程来实现入职流程中的步骤:
interface OnboardingStep<T extends Employee> {
void perform(T newEmployee);
}
class GeneralOnboardingStep implements OnboardingStep<Employee> {
GeneralOnboardingStep() {}
@Override
void perform(Employee newEmployee) {...}
}
class DeveloperOnboardingStep implements OnboardingStep<Developer> {
DeveloperOnboardingStep() {}
@Override
void perform(Developer newDeveloper) {...}
}
完整的入职流程包括一般入职流程和针对开发人员的特定入职流程。
所以我想做的是:
abstract class OnboardingProcess<T extends Employee> {
// This is where I need help, see below
private final List<OnboardingStep<T>> onboardingSteps;
protected OnboardingProcess(List<OnboardingStep<T>> onboardingSteps) {
this.onboardingSteps = onboardingSteps;
}
public void perform(T newEmployee) {
for (var onboardingStep: onboardingSteps) {
onboardingStep.perform(newEmployee);
}
}
class DeveloperOnboardingProcess extends OnboardingProcess<Developer> {
DeveloperOnboardingProcess() {
// This does not work
super(List.of(
new GeneralOnboardingStep(),
new DeveloperOnboardingStep()
));
}
}
这不起作用,因为
DeveloperOnboardingProcess
中的列表可能只包含 OnboardingStep<Developer>
而不是 OnboardingStep<Employee>
。
但它应该可以工作,因为
Developer
实现了Employee
。 (“应该有效”我的意思是:“我希望它有效”)。
如何调整抽象类中的列表类型以接受界面的入门步骤?
您可能想要的是这个(但见下文):
private final List<OnboardingStep<? super T>> onboardingSteps;
protected OnboardingProcess(List<OnboardingStep<? super T>> onboardingSteps) {
this.onboardingSteps = onboardingSteps;
}
? super T
意味着每个列表元素的 perform
方法保证接受 T 实例,因为它将构造函数参数限制为类型为 T 或 T 的超类的步骤。因此,对于 DeveloperOnboardingProcess,构造函数可以采用列出 OnboardingStep<Developer>
或 OnboardStep 元素,其泛型类型是 Developer 的任何超类,包括 Employee 本身。
但是,您不能做的一件事就是通过
List<DeveloperOnboardingStep>
。 List<DeveloperOnboardingStep>
not 相当于 List<OnboardingStep<Developer>>
或 List<OnboardingStep<Employee>>
,因为后者有一个 add
(和 addAll 等)方法,该方法允许 OnboardingStep、DeveloperOnboardinStep 或 OnboardingStep 的任何其他未来子类,而 List<DeveloperOnboardingStep>
有一个 add
方法,该方法仅接受 DeveloperOnboardingStep 参数。
要允许
List<DeveloperOnboardingStep>
参数,请使用以下命令:
private final List<? extends OnboardingStep<? super T>> onboardingSteps;
protected OnboardingProcess(List<? extends OnboardingStep<? super T>> onboardingSteps) {
this.onboardingSteps = onboardingSteps;
}