首先为不太好的标题道歉,我是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不一定支持该特定类型。