【问题标题】:Java calling a subclass methodJava调用子类方法
【发布时间】:2012-12-20 14:47:19
【问题描述】:

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

我该如何进行这项工作?

列表类:

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

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

【问题讨论】:

  • 我不会调用类List,我会使用接口
  • 与您的问题没有直接关系:您可能需要考虑一下助理是否是人,或者它是否是人的角色。
  • 我可以,但它是一堆代码,在简化版本之上以使其易于阅读。这条线出了问题:person.assist();在 List 类的 addAssistant() 方法中。编译器找不到符号 - 方法assist()。

标签: java arraylist superclass


【解决方案1】:

你需要一个明确的演员:

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

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

【讨论】:

  • 谢谢。如果我更习惯 java 语言,我会记住找到另一种方法!它现在工作正常。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      您必须将您的 Person 转换为 Assistant,如下所示:

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

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

      只是一个旁注:

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

      private ArrayList<Person> persons;
      

      用这个:

      private List<Person> persons;
      

      如果您希望您的 Persons 完成他们的特定工作并且 Assistants 的工作正在协助您,那么您可以通过在 Person 中创建一个抽象方法来解决此问题

      public abstract void doYourWork();
      

      您可以在Assistant 中实现它:

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

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

      如果 Person 不打算有任何具体的实现,你可以把它变成一个接口。

      【讨论】:

      • 感谢您的深入解释。
      【解决方案5】:

      我会这样编码

      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 界面中填充未正确放置在那里的职责。这完全是设计问题,您需要为您的特定问题选择更好(当然也是最舒适)的解决方案。

      祝你好运 克劳迪奥

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多