我是新来的,所以如果我在事故中没有遵守标准的礼仪,我提前道歉。
我想知道如何使用ArrayLists从子类中获取数据。
import java.io.*;
import java.util.*;
public class MyProgrammingLab {
public static void main(String[] args){
ArrayList<Test> testArray = new ArrayList<>();
testArray.add(new Test("First"));
testArray.add(new SubTest("Last"));
System.out.println(testArray.get(0).getFirstName());
System.out.println(testArray.get(1).getLastName());
}
}
public class Test {
private String firstName;
public Test(){
}
public Test(String firstName){
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
}
public class SubTest extends Test{
private String lastName;
public SubTest(){
super();
}
public SubTest(String lastName){
this.lastName = lastName;
}
public String getLastName(){
return lastName;
}
}我的主"System.out.println(test.Array.get(1).getLastName());“中的这行代码向我抛出了错误,而我却不知道为什么?
在我的主程序中,我将使用一个大于1的ArrayList。
提前谢谢你!
发布于 2012-11-27 07:34:12
我建议在使用我即将提出的解决方案时要非常谨慎,但是:
System.out.println(((SubTest) testArray.get(1)).getLastName());但是,只有在确定位置1处的元素是SubTest时才这样做,否则将得到ClassCastException。
如果你不确定,你可能应该检查一下。
Test whatIGot = testArray.get(1);
if(whatIGot instanceof SubTest) {
SubTest whatIActuallyGot = (SubTest)whatIGot;
System.out.println(whatIActuallyGot.getLastName());
}通常,当你有一个超类类型的变量时,你应该避免依赖于子类的属性。这样做是一种代码气味,可能是由糟糕的设计引起的。
正确的解决方案应该包括问你自己这两个问题:
getLastName属于SubTest而不是Test吗?如果getLastName()是在Test中,那就解决了你真正需要从getLastName元素访问testArray的问题了--如果getLastName()确实属于Test( Test的所有实例都有某个姓氏),但是没有合适的默认值,那么可以考虑让Test成为具有抽象方法getLastName的抽象类。请注意,这会使new Test()停止工作。
发布于 2012-11-27 07:47:00
您的列表已声明为Arraylist<Test>。这意味着它很灵活:您可以在其中放置Test的任何实例(包括子类的实例)。
这种灵活性带来了一个限制:稍后,当您再次取出一个元素时,您所能告诉的关于该元素的所有信息就是它是Test的一个实例-正如您已经发现的那样,如果没有特定的类型检查,您就无法判断该条目是Test还是SubTest。(考虑一下,如果列表必须返回条目的确切类型,那么您将如何在ArrayList上编写get方法-该方法的返回类型将根据传入的索引而变化!)
如果您需要这种灵活性(您的示例代码表明您需要这样做,因为您还将Test实例与SubTest一起存储),那么您最简单的选择就是检查类型和类型转换:
Test secondEntry = testArray.get(1);
if (secondEntry instanceof SubTest) {
System.out.println(((SubTest) secondEntry).getLastName());
}尽管如其他人所指出的那样,这在某种程度上削弱了使用泛型的意义。
其他替代方案包括:
getLastName方法上移到父类,然后在子类中重写它(如果父类具有此方法是有意义的);这看起来像这样:
import java.io.*;
import java.util.*;
public class MyProgrammingLab {
public static void main(String[] args) {
ArrayList<Test> testArray = new ArrayList<Test>();
testArray.add(new Test("First"));
testArray.add(new SubTest("Last"));
for (Test aTest : testArray) {
emit(aTest);
}
}
public static void emit(Test aTest) {
if (aTest instanceof SubTest) {
System.out.println(((SubTest) aTest).getLastName());
} else {
System.out.println(aTest.getFirstName());
}
}
}发布于 2012-11-27 07:37:14
testArray.get(1)返回的类型为Test,而不是SubTest。如果您绝对确定它是一个SubTest (您可以使用instanceof进行检查),那么您可以使用
System.out.println(((SubTest) testArray.get(1)).getLastName());https://stackoverflow.com/questions/13574973
复制相似问题