Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ArrayList由一个抽象类和任何扩展它的东西组成?_Java_Arraylist - Fatal编程技术网

Java ArrayList由一个抽象类和任何扩展它的东西组成?

Java ArrayList由一个抽象类和任何扩展它的东西组成?,java,arraylist,Java,Arraylist,我知道这是一个基本问题,但我找不到其他StackOverflow帖子或任何关于这个的好API文档 假设我有一个抽象类,比如Appliance,然后我有一些类,比如Toaster和Blender,它们扩展了Appliance。现在假设我想创建一个包含混合元素的ArrayList,所有这些元素最终都是Appliance的成员,但也可以是Toaster或Blender。Blender类有一个名为turnBlenderOff()的方法,Toaster类有一个名为turnToasterOff()的方法,我

我知道这是一个基本问题,但我找不到其他StackOverflow帖子或任何关于这个的好API文档

假设我有一个抽象类,比如
Appliance
,然后我有一些类,比如
Toaster
Blender
,它们扩展了
Appliance
。现在假设我想创建一个包含混合元素的ArrayList,所有这些元素最终都是
Appliance
的成员,但也可以是
Toaster
Blender
Blender
类有一个名为
turnBlenderOff()
的方法,
Toaster
类有一个名为
turnToasterOff()
的方法,我想迭代我的ArrayList并调用这些方法,具体取决于元素实际属于哪个子类

目前,我制作了一个名为
PowerPoint
的课程,并尝试:

 // 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));      
             }
         }
     }
我看到,这个方法只在
Blender
对象上实现,它试图在一个
Appliance
对象上执行,而这个对象恰好是
Blender
,但编译器没有意识到这一点

我尝试将
类型替换为
使用或,而不是滚动您自己的
getClassName
,然后对您刚刚识别的类型执行显式转换


也就是说,我们更喜欢@guitarflow的答案,尽管如果存在不能直接传递到
关闭方法的状态,那么这种方法可能不起作用。

如果您想使用一个抽象类,并且所有子类实际上都有相同的函数,为什么不在抽象基类中使用一个名为“turnDeviceOff”的函数呢并相应地在子类中重写它。这就是面向对象的方法。

数组列表还可以

但你可以这样做:

public abstract class Appliance{
 //declare an abstract method
abstract void switchOff();
}
然后

对于其他子类,也可以这样做

最后,

for(Appliance element: yourList){
element.switchOff();
}

您完全违背了继承的观点:
Appliance
应该定义一个
turnOff()
方法,它的子对象应该根据自己的需要适当地实现该方法。这样,您就可以只使用
设备的列表
s,而不必担心什么是什么

否则,他们首先扩展
设备
有什么意义

如果您确实需要找出某种类型的东西,请使用
instanceof
,将类名作为字符串进行测试是一种非常脆弱的方法

编辑 随机风格提示:几乎不再需要在
List
s上使用索引访问:

public PowerPoint(List<Appliance> initialList){
   for(Appliance app : initialList)
     applianceList.add(app);
}
编辑2 更直接的翻译:

public void switchOff(){
    for(Appliance app : applianceList)
        switchOff(app);
}

private void switchOff(Appliance app){
    if(app instanceof Blender)
        turnBlenderOff(app);
    else if(app instanceof Toaster)
        turnToasterOff(app);
    else if(app instanceof Oven)
        turnOvenOff(app);
    else
        throw new RuntimeException("unknown appliance: " + app);
}

您还可以在规范化API的不同设备类周围添加一个包装器,但这可能不值得(取决于涉及的程度)。

有两种方法可以做到这一点。第一种(也是不太推荐的)方法是使用instanceof关键字并将您的设备实例转换为混合器实例:

for(Appliance a : list){
    if(a instanceof Blender) this.turnBlenderOff((Blender)a);
    ...
}
这是不好的,因为instanceof速度很慢,并且不允许您利用Java最强大的多态性对应项后期绑定。更好的方法是让Appliance类有一个名为turnOff()的抽象公共方法。然后你可以做一些类似的事情:

for(Appliance a : list){
    a.turnOff();
    ...
}

正确的解决方法是在Appliance类中添加
turnOff()
方法,并让不同的子类适当地重写它们。如果您这样做,那么大的“If”代码就会消失。

My
getClassName()
只是基本
对象
方法
getSimpleName()
对象没有
getSimpleName
方法的包装。你的意思是
getClass().getSimpleName()
?是的,我的意思是
class
。我的synatx有:
Toaster.class.getSimpleName()
用于
Toaster
子类,例如.Ah。我仍然不相信这比就在那里做更好;如果(appliance.getClass()==Toaster.class)
,我会做一些类似的事情。我想你是对的。将此与Ben Lawry的答案结合起来,给出了一个很好的解决方案。这就是我在下面写的代码。这就是路!不幸的是,这一选择没有得到考虑。在我的项目中,我们必须假设,
烤面包机
搅拌机
等都来自某个第三方软件包,都是由不同的人实现的,并且都有自己粗糙、不同的开/关方法。这是练习要点的一部分。@EMS也是第三方软件包中的设备吗?是的。这是第三方抽象类。好的,然后我会比较类或类的名称。尽管您的示例将解释和使用接口或抽象基类!可以为第三方类添加方法吗?请参阅我对Kent答案的评论。请参阅我对Kent答案的评论。
public void switchOff(){
    for(Appliance app : applianceList)
        switchOff(app);
}

private void switchOff(Appliance app){
    if(app instanceof Blender)
        turnBlenderOff(app);
    else if(app instanceof Toaster)
        turnToasterOff(app);
    else if(app instanceof Oven)
        turnOvenOff(app);
    else
        throw new RuntimeException("unknown appliance: " + app);
}
for(Appliance a : list){
    if(a instanceof Blender) this.turnBlenderOff((Blender)a);
    ...
}
for(Appliance a : list){
    a.turnOff();
    ...
}