Java调用子类方法

Java调用子类方法,java,arraylist,superclass,Java,Arraylist,Superclass,当我试图创建一个类的实例并将其添加到arraylist中时,我无法调用在子类中定义的方法 我该怎么做 列表类: import java.util.*; public class List { private ArrayList<Person> persons; public List(){ persons = new ArrayList<Person>(); } public void addAssistant(){ Person pers

当我试图创建一个类的实例并将其添加到arraylist中时,我无法调用在子类中定义的方法

我该怎么做

列表类

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!");
  }
}
助理班

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()方法中

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

您需要显式强制转换:

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

然而,我认为这种逻辑通常不应该被鼓励。

你必须把你的
变成
助手
,就像这样:

if(person instanceof Assistant){
  ((Assistant)person).assist();
}
我认为,这种类型的casting hower表明应用程序设计存在缺陷

只是旁注:

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

private ArrayList<Person> persons;
您可以在
助手
中实现:

@Override
public void doYourWork(){
    // doing something
}
在这种情况下,您不必显式地强制转换
Person
对象


若这个人并没有任何具体的实现,你们可以把它变成一个接口。

你们需要使用一个子类方法进行转换

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

按照
Java
语言的设计方式,它不会编译(正如您所理解的那样)。这样想吧,所有的助手都是人,但不是所有的人都是助手。如果您使用显式强制转换,您可以实现您想要实现的目标(正如NPE在他的回答中提到的)。

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

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

我会这样编码

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.assist();在List类的addAssistant()方法中。编译器找不到symbol-method assist()。谢谢。如果我更习惯java语言,我会记住找到另一种方法!现在还可以。谢谢你的深入解释。