如何传递实现相同接口的多个类型?



首先为不太好的标题道歉,我是Java新手,不知道如何命名。

我有一个接口类"TestInterface":

ublic interface TestInterface {
String getForename();
void setForename(String forename);
String getSurname();
void setSurname(String surname);
}

"TestImpl"实现"TestInterface"

public class TestImpl implements TestInterface{
private String forename;
private String surname;
@Override
public String getForename() {
return forename;
}
public void setForename(String forename) {
this.forename = forename;
}
@Override
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
}

然后我有一个名为"ExtendTest"它扩展了"TestImpl":

public class ExtendTest extends TestImpl{
private String firstLineAddress;
public String getFirstLineAddress() {
return firstLineAddress;
}
public void setFirstLineAddress(String firstLineAddress) {
this.firstLineAddress = firstLineAddress;
}
}

我有了这个&;entity &;类:


import java.util.List;
public class Entity {
private List<TestInterface> testInterfaces;
private List<ExtendTest> extendTests;
public List<TestInterface> getTestInterfaces() {
return testInterfaces;
}
public void setTestInterfaces(List<TestInterface> testInterfaces) {
this.testInterfaces = testInterfaces;
}
public List<ExtendTest> getExtendTests() {
return extendTests;
}
public void setExtendTests(List<ExtendTest> extendTests) {
this.extendTests = extendTests;
}
}

最后是这个"DoStuff"类,其中dostuff方法接受List

类型的参数。
import java.util.List;
public class DoStuff {
public void doStuff(List<TestInterface> testData) {
}
}

我试着这样测试:

public class Main {

public static void main(String[] args) {
System.out.println("Hello, World!");
DoStuff doStuff = new DoStuff();

Entity entity = new Entity();
// Works
doStuff.doStuff(entity.getTestInterfaces());
// Does not work
doStuff.doStuff(entity.getExtendTests());
}
}

然而,注释是"Does not work">

Required type:
List<TestInterface>
Provided:
List<ExtendTest>

我的问题是如何使它可以传递进去。我的理解是,因为他们都实现了TestInterface,所以它会工作,但我认为我错了。

谢谢你的帮助和学习:)

您与PECS发生了冲突。我建议阅读链接的答案以获得更详细的解释,但这里是特定于您的用例的部分。

当你有一个泛型类型(在你的例子中是List),如果你只从读取,你应该写List<? extends MyInterface>。如果你只写到它,你应该写List<? super MyInterface>。如果两者都做,那么你需要List<MyInterface>。我们为什么要这样做?好吧,看看你的代码。

public void doStuff(List<TestInterface> testData) { ... }

这个函数的参数是List<TestInterface>List接口具有大量的功能。除了读取之外,还可以添加和删除内容。doStuff期望TestInterface的列表。所以doStuff的实现是完全公平的

testData.add(new ClassIJustMadeUp());

假设ClassIJustMadeUp实现TestInterface。所以我们肯定不能给这个函数传递List<ExtendTest>,因为这个列表类型不能包含ClassIJustMadeUp

然而,如果你的函数只从列表中读取,而不打算添加任何内容,你可以将签名写为
public void doStuff(List<? extends TestInterface> testData) { ... }

,现在你可以传递List的任何类型扩展TestInterface。可以从这个列表中读取,因为任何扩展TestInterface的类型都可以安全地向上转换为TestInterface。但是,如果尝试添加list元素,则会导致编译器错误,因为list不一定支持该特定类型。

最新更新