2

当我尝试创建一个类的实例并将其添加到我的数组列表中时,我无法调用子项中定义的方法。

我如何使这项工作?

列表类

import java.util.*;
public class List {
  private ArrayList<Person> persons;
  public List(){
    persons = new ArrayList<Person>();
  }
  public void addAssistant(){
    Person person = new Assistant();
    persons.add(person);
    if(person instanceof Assistant){
      person.assist();
    }
  }
}

人物类

public class Person {
  public Person(){}
}

助理班

public class Assistant extends Person {
  public Assistant(){}
  public void assist(){
     System.out.println("I am assisting!");
  }
}

编译器:行:person.assist(); 在 List 类的 addAssistant() 方法中。

编译器错误:编译器找不到符号 - 方法辅助()。

4

6 回答 6

8

你需要一个明确的演员:

if(person instanceof Assistant){
  ((Assistant)person).assist();
}

但是,我认为这种类型的逻辑通常应该被劝阻。

于 2012-12-20T14:49:28.967 回答
1

你必须把你Person变成Assistant这样的:

if(person instanceof Assistant){
  ((Assistant)person).assist();
}

我认为这种类型的转换表明存在缺陷的应用程序设计。

只是一个旁注:

您应该使用接口而不是具体的实现。所以你应该替换这个:

private ArrayList<Person> persons;

有了这个:

private List<Person> persons;

如果您希望您Person的 s 完成他们的特定工作并且Assistants 的工作有帮助,那么您可以通过在Person

public abstract void doYourWork();

你可以实现它Assistant

@Override
public void doYourWork(){
    // doing something
}

在这种情况下,您不必显式地转换您的Person对象。

如果 Person 没有任何具体的实现,您可以将其设为接口。

于 2012-12-20T14:50:19.497 回答
1

您需要进行强制转换以使用子类方法

if(person instanceof Assistant){
  ((Assistant)person).assist();
}
于 2012-12-20T14:50:40.777 回答
1

Person 类没有定义辅助方法,因此您必须显式转换为 Assistant 类,例如

if(person instanceof Assistant){
  ((Assistant)person).assist();
}
于 2012-12-20T14:51:59.233 回答
1

我会这样编码

public void addAssistant(){
    Assistant assistant = new Assistant();
    assistant.add(person);
    assistant.assist();
}

将自己从您最近创建的对象实际上是助手的知识中抽象出来是没有意义的。

从具体类型中抽象出自己是减少两段代码之间耦合的好方法,并且它对于做多态之类的好事情是必要的......但是在这个特定的例子中,您向我们展示了您已经与助手紧密耦合(在事实上你只是在上面两行实例化它)。

另一种可能的实现方式是使用多态性,您可以通过将assist() 方法添加到Person 的接口来实现。

public class Person {
  public Person(){}

  public void assist() {
     //I'm a just a person who doesn't assist anywhere
  }
}

通过这样做,您将能够做您正在尝试的事情:

public void addAssistant(){
    Person person = new Assistant();
    persons.add(person);
    person.assist();     
}

但是我不建议这样做,主要是因为您将开始用未正确放置在那里的职责填充您的 Person 接口。这完全是设计问题,您需要为您的特定问题选择更好的(当然也是最舒适的)解决方案。

好运克劳迪奥

于 2012-12-20T15:23:03.557 回答
0

设计语言的方式Java,这不会编译(正如您所想的那样)。这样想,所有的助手都是人,但不是所有的人都是助手。如果您使用显式强制转换,您可以做您想做的事情(正如 NPE 在他的回答中提到的那样)。

于 2012-12-20T14:51:00.783 回答