从父类对象调用子类方法

use*_*663 17 java inheritance

我有以下课程

class Person {
    private String name;
    void getName(){...}}

class Student extends Person{
    String class;
    void getClass(){...}
}

class Teacher extends Person{
    String experience;
    void getExperience(){...}
}
Run Code Online (Sandbox Code Playgroud)

这只是我实际架构的简化版本.最初我不知道需要创建的人的类型,因此处理这些对象的创建的函数将通用Person对象作为参数.

void calculate(Person p){...}
Run Code Online (Sandbox Code Playgroud)

现在我想使用这个父类对象访问子类的方法.我还需要不时访问父类方法,所以我不能理解它.


我猜我在上面的例子中简化得太多了,所以这就是实际的结构.

class Question {
  // private attributes
  :
  private QuestionOption option;
  // getters and setters for private attributes
  :
  public QuestionOption getOption(){...}
 }

 class QuestionOption{
 ....
 }
 class ChoiceQuestionOption extends QuestionOption{
 private boolean allowMultiple;
 public boolean getMultiple(){...}
 }

 class Survey{
  void renderSurvey(Question q) {
      /*
          Depending on the type of question (choice, dropdwn or other, I have to render
          the question on the UI. The class that calls this doesnt have compile time 
          knowledge of the type of question that is going to be rendered. Each question 
          type has its own rendering function. If this is for choice , I need to access 
          its functions using q. 
      */
      if(q.getOption().getMultiple())
        {...}
  }
 }
Run Code Online (Sandbox Code Playgroud)

if语句说"找不到QuestionOption的getMultiple".OuestionOption有更多的子类,它们具有不同类型的方法,这些方法在子节点中不常见(getMultiple在子节点中不常见)

tec*_*bar 29

注意:虽然这是可能的,但它完全没有被推荐,因为它破坏了继承的原因.最好的办法是让有调整你的应用程序设计 NO父母和孩子之间的依赖关系.父母不应该知道自己的孩子或他们的能力.

但是..你应该能够这样做:

void calculate(Person p) {
    ((Student)p).method();
}
Run Code Online (Sandbox Code Playgroud)

安全的方法是:

void calculate(Person p) {
    if(p instanceof Student) ((Student)p).method();
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*teo 8

父类不应该具有子类的知识.您可以实现一个方法calculate()并在每个子类中覆盖它:

class Person {
    String name;
    void getName(){...}
    void calculate();
}
Run Code Online (Sandbox Code Playgroud)

然后

class Student extends Person{
    String class;
    void getClass(){...}

    @Override
    void calculate() {
        // do something with a Student
    }
}
Run Code Online (Sandbox Code Playgroud)

class Teacher extends Person{
    String experience;
    void getExperience(){...}

    @Override
    void calculate() {
        // do something with a Student
    }

}
Run Code Online (Sandbox Code Playgroud)

顺便说说.你关于抽象类的陈述令人困惑.您可以调用抽象类中定义的方法,但当然只调用子类的实例.

在您的例子可以使Person抽象和使用getName()的实例化的StudentTeacher.