是否可以将从同一抽象对象扩展的不同对象存储在单个容器中,并且能够访问这些对象的所有自定义字段。让我举一个例子: 假设我有两辆车:福特和本田。由于所有汽车都有重量和颜色,我可以制作以下抽象类:
public abstract class Car{
private double weight;
private String color;
public Car(){
this.weight=0;
this.color="";
}
...getters and
...setters
}
现在假设我的福特班有一个额外的字段' radio ',看起来像这样:
public Ford extends Car(){
private String radio;
public Ford(){
super();
this.radio = "generic";
}
}
同样,Honda类有一个自定义字段“相机”
public Honda extends Car(){
private String camera;
public Honda(){
super();
this.camera= "analog";
}
}
是否可以将这些类的实例保存在单个容器中,如下所示。请注意下面的代码有效,但这不是我想要的。见下面的评论:
Ford ford = new Ford();
Honda honda = new Honda();
ArrayList<Car> myCars = new ArrayList<Car>();
myCars.add(ford);
myCars.add(honda);
这是我的问题:
当我myCars.get(0)
时,我得到了一个类Car
的对象(显然),我永远无法获得自定义字段 radio 。当然我可以做((Ford) myCars.get(0))
这样的事情,并且能够看到无线电字段,但是有可能创建一个更好的容器,可以显示所有字段而无需向下转换等等喜欢:
myContainer.get(0)
- 会返回 Ford 类,我可以访问权重,颜色和广播
myContainer.get(1)
- 将返回本田课程,我可以访问重量,颜色和相机。
我的预感告诉我解决方案已经接近并且有可能,但我在Java方面的专业知识尚未实现。也许我对某种泛型或哈希映射做了什么?
谢谢你们!!
答案 0 :(得分:2)
有几种选择,其中没有一种完全符合您的理想。
Car
类中添加特定属性的所有getter,并返回Null
或在不适用的情况下抛出异常。CarContainer
类,并具有返回特定类型的所有元素的方法,例如: List<Ford> getAllTheFords()
。通过这种方式,您可以隐藏容器类中的丑陋演员表。我根据个人喜好列出了替代方案: - )
答案 1 :(得分:2)
你可以做的是使用泛型。
您的存储库可以实现这些方法:
public static <T extends Car> T getFromRepository(Class<T> type, Object key)
public static <T extends Car> boolean addToRepository(Class<T> type, Object key, T value)
然后你可以用类似的东西来打电话(假设你已经拥有了福特的钥匙):
Ford ford = Repository.getFromRepository(Ford.class, fordKey)
当然,您可以实现方法来获取给定类型的所有对象,等等......
PS:一个简单的替代方案,如果你可以在子类上使用相同的方法是模板方法模式: http://en.wikipedia.org/wiki/Template_method_pattern
答案 2 :(得分:1)
myCars.get(0)
会返回一个福特对象。除了这只是在运行时才知道。问题是,要拨打car.radio
,您需要知道它是福特,如果不是,您就不能调用该方法。所以在任何情况下你都需要检查类型和演员。
一种解决方案是在您的抽象类中添加List<Accessory>
字段。
您现在可以编写如下内容:
Car car = cars.get(0);
if (car.hasAccessories()) {
car.getAccessory(0).operate();
}
不确定这是否是您的用例所需。