Java 访问子类的属性
我对Java非常陌生,我很难理解为什么我总是在命令行中出错。我有一个超类Guest,带有变量guestID、fName、lName和dateJoin。我还有一个子类VIPGuest,它带有附加变量VIPstartDate和VIPexpiryDate 我有一个ArrayList guests,它保存我记录中的所有来宾对象。我希望遍历ArrayList并将每个来宾写入一个文本文件,每个来宾都以guestID、fName、lName、dateJoin的形式出现在新行中,并用逗号分隔(如果来宾是VIPGuest,则使用guestID、fName、lName、dateJoin、VIPstartDate、VIPexpiryDate) 我的代码如下。当我使用类似的代码为一个没有子类的类的对象的ArrayList做类似的事情时,效果很好,但是当我试图让它解决一些来宾有额外变量这一事实时,错误是:Java 访问子类的属性,java,inheritance,compiler-errors,iteration,Java,Inheritance,Compiler Errors,Iteration,我对Java非常陌生,我很难理解为什么我总是在命令行中出错。我有一个超类Guest,带有变量guestID、fName、lName和dateJoin。我还有一个子类VIPGuest,它带有附加变量VIPstartDate和VIPexpiryDate 我有一个ArrayList guests,它保存我记录中的所有来宾对象。我希望遍历ArrayList并将每个来宾写入一个文本文件,每个来宾都以guestID、fName、lName、dateJoin的形式出现在新行中,并用逗号分隔(如果来宾是VIPG
HotelImpl.java:440: error: cannot find symbol
+ "," + g.getVIPstartDate() + "," + g.getVIPexpiryDate());
^
symbol: method getVIPstartDate()
location: variable g of type Guest
HotelImpl.java:440: error: cannot find symbol
+ "," + g.getVIPstartDate() + "," + g.getVIPexpiryDate());
^
symbol: method getVIPexpiryDate()
location: variable g of type Guest
2 errors
我可以看出,VIPGuest对象的额外变量有问题,但我想我已经用if/else解决了这个问题:
public boolean saveGuestsData(String guestsTxtFileName){
BufferedWriter writer;
try{
writer = new BufferedWriter(new FileWriter(guestsTxtFileName));
} catch (IOException e){
System.out.print("Invalid file.");
return false;
}
try{
for (Guest g : guests){
if (!(g instanceof VIPGuest)){
writer.write(
g.getGuestID() + "," + g.getFName() + "," + getLName()
+ "," + g.getDateJoin());
}
else {
writer.write(
g.getGuestID() + "," + g.getFName() + "," +
getLName() + "," + g.getDateJoin() + "," +
g.getVIPstartDate() + "," + g.getVIPexpiryDate());
}
writer.newLine();
}
writer.close();
return true;
} catch (FileNotFoundException ex) {
System.out.print("File not found.");
return false;
} catch (IOException e){
System.out.print("Invalid file.");
return false;
}
}
在这个答案中,我假设
VIPGuest
扩展了Guest
在常规Guest
上使用任何VIPGuest
方法之前,您需要将Guest强制转换为VIPGuest
for (Guest g : guests){
if (!(g instanceof VIPGuest)){
// omitted for brevity
} else {
VIPGuest vip = (VIPGuest)g;
writer.write(vip.getGuestID() + "," + vip.getFName() + "," + vip.getLName() + "," +
vip.getDateJoin() + "," + vip.getVIPstartDate() + "," + vip.getVIPexpiryDate());
}
writer.newLine();
}
虽然通过使用instanceof
检查,您知道g
实际上是一个VIPGuest,但您对它的引用仅限于一位来宾
请注意,如果
g
实际上不是VIPGuest
的实例,则尝试的强制转换(VIPGuest)g
可能会引发ClassCastException。您的变量g
的类型为Guest
,尽管该实例是VIPGuest
,方法getVIPstartDate
不可用
你应该做的是:
else
{
VIPGuest vg;
vg = (VIPGuest)g;
writer.write(
vg.getGuestID() + "," + vg.getFName() + "," +
getLName() + "," + vg.getDateJoin() + "," +
vg.getVIPstartDate() + "," + vg.getVIPexpiryDate());
}
更好的是:
覆盖Guest
和VIPGuest
中的方法toString()
后者调用
super.toString()
并添加附加信息。g
是类型为Guest
的引用,因此您只能从中访问Guest
的成员。如果要访问VIPGuest
的成员,必须显式地向下转换它。例如:
VIPGuest vg = (VIPGuest) g;
writer.write(g.getGuestID() + "," +
g.getFName() + "," +
g.getLName() + "," +
g.getDateJoin() + "," +
vg.getVIPstartDate() + "," +
vg.getVIPexpiryDate());
这应该是可行的,但这是一个糟糕的设计,它迫使您的saveGuestsData
方法熟悉您的Guest
实现。更健壮的设计是将此逻辑移动到Guest
类,并让此方法调用它们:
public class Guest {
@Override
public String toString() {
return getGuestID() + "," + getFName() + "," + getLName() + "," + g.getDateJoin();
}
// other methods...
}
public class VIPGuest extends Guest {
@Override
public String toString() {
return super.toString() + ", " + getVIPstartDate() + "," + getVIPexpiryDate());
// other methods...
}
然后调用这个方法:
for (Guest g : guests) {
writer.write(g.toString());
}
g
是客人,不是客人。如果要在VIPGuest类上使用方法,需要将g
强制转换为VIPGuest——例如((VIPGuest)g)。getVIPstartDate()
修复了它!谢谢:)@Habilee我建议你使用IDE,它会向你解释这种错误。我正要发布一个类似的答案;)