作为一项练习,我必须为游泳池编写一个非常简单的软件。
父类是用户。
成人和儿童是两个扩展用户的类。
DisabledChild 和 DisabledAdult 扩展用户并使用一个仅打印“我已禁用”的额外方法实现已禁用界面
在main中,根据它们的age参数和'disabled'布尔值创建这些类的不同对象,然后我将它们放入一个列表中,如下所示:
public void insertData()
{
int age;
Adult a = null;
DisabledAdult da = null;
Scanner scanIn = new Scanner(System.in);
List l = new ArrayList();
do {
System.out.println("Insert user name, type 'quit' to exit");
name = scanIn.next();
System.out.println("Insert age");
age = scanIn.nextInt();
if (age > 16) {
System.out.println("Is the adult disabled? ( y/n)");
String disabled = scanIn.next();
if("y".equals(disabled))
{
da = new DisabledAdult();
l.add(da); // l is a list!
} else
{
a = new Adult();
l.add(a);
}
}
else{
// similar as above, but for children.
}
} while (!"quit".equals(name));
scanIn.close();
问题出在这里:当我把东西放入我的列表中时,它们变成了对象,即使使用.getClass()。getName()也无法回到原来的类。所以我不能使用他们的特定方法,比如从Disabled接口实现的方法。
我被迫将Obj投入用户(因为游泳池中的每个人都是用户),如下所示:
for (Object obj : l) {
User u = (User) obj;
}
但是我不能使用DisabledAdult或DisabledChild的额外方法,因为它们是在接口Disabled中定义的,而不是User!
如果我这样做
obj.getClass().getName();
我可以看到他们的原始类,但我只能访问Object方法。
我想我可以这样做:
if (obj instanceof Adult){
Adult a = (Adult) obj;
}
if (obj instanceof Child){
Child c = (Child) obj;
}
...
但它看起来很糟糕,因为我应该检查每个用户,如果他们是否被禁用等等。
我该怎么办?
谢谢。
答案 0 :(得分:3)
使用generics列表。由于l
中的所有对象都是User
s,因此您应该将其指定为类型参数。
而不是:
List l = new ArrayList();
使用:
List<User> l = new ArrayList<User>();
// or List<User> l = new ArrayList<>(); if you are on Java 7 or higher.
这样,当你从列表中获取它们时,你不需要重新投入User
。
此外,要检查已禁用的用户,您可以执行以下操作:
if(user instanceof Disabled) {
Disabled disabledUser = (Disabled) user;
//do disabled-specific stuff here on disabledUser, which is the same as user
}
这将允许您为禁用的用户执行特定于禁用的内容。
答案 1 :(得分:2)
答案 2 :(得分:1)
首先,您应该使用泛型,即List<User>
而不是List
。如果这是一个课程,并且你被教导以长期过时的方式去做,那就找一个更好的老师。
其次,以您描述的方式区分禁用和非禁用用户是非常糟糕的OO建模。通常,被User
被禁用只是一个属性,而User
会有setDisabled()
和isDiabled()
等方法。如果练习的目的是要了解继承,那么您可能会使用describeSelf()
中的User
方法打印&#34;我没有禁用&#34;并在DisabledUser
中重写以打印其他内容。然后,您可以在两种类型的实例上调用此方法,而无需测试实际类并执行强制转换。
我真诚地希望这项练习旨在教你不该做什么。