问题描述
我知道这是一个基本问题,但我找不到关于此的其他 StackOverflow 帖子或任何好的 API 文档.
I know this is a basic question, but I can't find other StackOverflow posts or any good API docs on this.
假设我有一个抽象类,比如 Appliance
,然后我有一些类,比如 Toaster
和 Blender
,它们扩展了 Appliance代码>.现在假设我想创建一个包含混合元素的 ArrayList,所有这些元素最终都是
Appliance
的成员,但也可以是 Toaster
或 Blender
> 还有.Blender
类有一个名为 turnBlenderOff()
的方法,Toaster
类有一个名为 turnToasterOff()
的方法,我将要遍历我的 ArrayList 并调用这些方法,具体取决于元素实际属于哪个子类.
Say I have an abstract class like Appliance
and then I have some classes like Toaster
and Blender
that extend Appliance
. Now suppose that I want to create an ArrayList that will contain mixed elements, all of which are ultimately members of Appliance
but could also be Toaster
or Blender
as well. The Blender
class has a method called turnBlenderOff()
and the Toaster
class has a method called turnToasterOff()
, and I will want to iterate over my ArrayList and call these methods, depending on which subclass the element actually belongs to.
目前我制作了一个名为 PowerPoint
的课程并尝试:
Currently I make a class called PowerPoint
and try:
// Constructor given an ArrayList of appliances.
public PowerPoint(ArrayList<Appliance> initial_list_of_appliances){
int listSize = initial_list_of_appliances.size();
for(int ii = 0; ii < listSize; ii++){
this.applianceList.add(initial_list_of_appliances.get(ii));
}
}
/////
// Method to switch everything in the list OFF simultaneously.
/////
public void switchOff(){
int N = this.applianceList.size();
String cur_name;
for(int ii = 0; ii < N; ii++){
cur_name = this.applianceList.get(ii).getClassName();
if(cur_name.equals("Blender")){
this.turnBlenderOff(this.applianceList.get(ii));
}
else if(cur_name.equals("Toaster")){
this.turnToasterOff(this.applianceList.get(ii));
}
else if(cur_name.equals("Oven")){
this.turnOvenOff(this.applianceList.get(ii));
}
}
}
我的大部分代码编译良好,但我不断收到此错误消息:
Most of my code compiles fine, but I keep getting this error message:
PowerPoint.java:83: turnBlenderOff(appliances.ApplianceWrapper.Blender) in PowerPoint cannot be applied to (appliances.ApplianceWrapper.Appliance)
this.turnBlenderOff(this.applianceList.get(ii));
我看到这个方法,只适用于 Blender
对象,它试图在 Appliance
对象上执行,该对象恰好是一个 Blender代码>但编译器没有意识到这一点.
I see that this method, implemented to work only on Blender
objects is trying to be executed on an Appliance
object that happens to be a Blender
but that the compiler doesn't realize this.
我尝试将 类型替换为
在 ArrayList 规范中,但这会产生额外的错误并且不再编译.
I tried to replace the <Appliance>
type with <? in the ArrayList specifications, but that gave additional errors and would not longer compile.
根据抽象类型创建列表,然后通过使用诸如getClassName()
之类的东西来调用子类类型的方法来检索子类类型的正确方法是什么?
What is the proper way to make a list based on the abstract type, but then call methods of the subclassed type by using something like getClassName()
to retrieve the subclass type?
已添加
既然很多人立刻指出了一个显而易见的道理:更好地使用继承,我需要解释一下.对于这个项目,我们必须假设 Appliance
的所有子类都是由第三方创建的,并放入一些我们无法更改的包中.这是以一种糟糕的、粗暴的方式完成的,其中所有不同的子类都有不同的开/关方法,并且无法更改.所以设计一个流畅的Appliance
抽象类的选项对我来说是不开放的.例如,Toaster
有方法 startToasting()
,而 Oven
有方法 heatUp()
,每个用作两个不同类的on"方法.
Since a lot of folks immediately pointed out the obvious: use inheritance better, I need to explain. For this project, we have to assume that all of the subclasses of Appliance
were created by third-party people and put into some package that we cannot change. This was done in a bad, crufty way in which all different subclasses have different on/off methods and this can't be changed. So the option of designing a smooth Appliance
abstract class is not open to me. For example, Toaster
has the method startToasting()
, while Oven
has the method heatUp()
, each of which serves as the 'on' method for the two different classes.
我认为这个练习是为了教我们:你会如何改造别人糟糕的设计工作,以尽量减少未来的损失.
I think the exercise is meant to teach us: how would you retro-fit someone else's bad design job so as to minimize future damage.
推荐答案
使用 instanceof
或 getClass
,而不是滚动您自己的 getClassName
,然后对您刚刚确定的类型进行显式转换.
Use instanceof
or getClass
, not rolling your own getClassName
, and then do an explicit cast to the type you just identified.
也就是说,更喜欢@guitarflow 的答案,但如果存在不能传递给 switchOff
方法的状态,这种方法可能不起作用.
That said, prefer @guitarflow's answer, though that approach might not work if there is state that you can't just pass to the switchOff
method.
这篇关于Java ArrayList 由一个抽象类和任何扩展它的类组成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!