【问题标题】:Java subclass method is getting ignoredJava子类方法被忽略
【发布时间】:2022-02-02 10:38:41
【问题描述】:

我有这些课程

abstract class Person{
public void join(Lecture lec){System.out.println("Joining "+lec);}
public void join(OnlineLecture lec){System.out.println("Joining "+lec);}
}
class Student extends Person{
public void join(Lecture lec){System.out.println("Student joining "+lec);}
}
class Teacher extends Person{
public void join(OnlineLecture lec){System.out.println("Teacher joining "+lec);}
}
class Lecture{
public void addAttendant(Person p){p.join(this);}
public String toString(){return "a lecture";}
}
class OnlineLecture extends Lecture{
public String toString(){return "an online lecture";}
}

然后在主课我有这个

public class Main{
public static void main(String[] args){
Person p1=new Student();
Person p3=new Teacher();
Student p4=new Student();
OnlineLecture lec3=new OnlineLecture();
lec3.addAttendant(p1);
lec3.addAttendant(p3);
lec3.addAttendant(p4);
}
}


为什么我会得到这个:

Student joining an online lecture
Joining an online lecture
Student joining an online lecture

而不是这个:

Joining an online lecture
Teacher joining an online lecture
Joining an online lecture

如果我传递了一个 OnlineLecture 实例,为什么代码表现得像一个 Lecture 实例?教师类覆盖了 join(OnlineLecture lec),但仍调用父类的。

【问题讨论】:

    标签: java inheritance types type-conversion extends


    【解决方案1】:

    只有类 Lecture 定义 addAttendant(Person p)。所以this in

    public void addAttendant(Person p) {
     p.join(this);
    }
    

    将永远是Lecture

    由于Student 覆盖join(Lecture lec),因此在lec3.addAttendant(p1); 时调用此被覆盖的方法,因为p1Student,而lec3 也是Lecture

    Teacher 仅覆盖 join(OnlineLecture lec) 而不是 join(Lecture lec)。而lec3.addAttendant(p3); 调用Lecture.addAttendant(Person p) 其中p == p3Teacherp.join(this); 中的thisLecture 而不是OnlineLecture。这就是为什么不能调用Teacher.join(OnlineLecture lec) 的原因,因为this 不是OnlineLecture,而是Lecture。所以Person.join(Lecture lec) 被调用了。

    不太清楚使用这种复杂的继承和嵌套方法调用应该实现什么。所以这只是对正在发生的事情的描述。

    【讨论】:

    • 好的,你的答案的第一行就是我所缺少的。现在很清楚了。谢谢
    【解决方案2】:

    这是因为join() 签名在Person 中的输入比在Student 中输入的强度更大
    由于Student 仅覆盖Lecture in

      public void join(Lecture lec){System.out.println("Student joining "+lec);}
    

    使用的方法来自父类Person

      public void join(OnlineLecture lec){System.out.println("Joining "+lec);}
    

    作为一种解决方案,使用给定签名正确覆盖 Student 类中的 join

    public void join(OnlineLecture lec)
    

    【讨论】:

    • 父方法打印 Joining + lec 。那么为什么在第一行我得到“学生加入”+ lec,如果父方法是被调用的方法? Teacher() 也覆盖了 join(OnlineLecture lec) 但仍会调用父方法。
    猜你喜欢
    • 1970-01-01
    • 2016-04-18
    • 1970-01-01
    • 1970-01-01
    • 2015-08-20
    • 1970-01-01
    • 2018-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多