Reputation: 23
I have these classes
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";}
}
and then in main class I have this
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);
}
}
Why I get this:
Student joining an online lecture
Joining an online lecture
Student joining an online lecture
instead of this:
Joining an online lecture
Teacher joining an online lecture
Joining an online lecture
If I pass an OnlineLecture instance, why is the code behaving like it's a Lecture instance? Teacher class overrided join(OnlineLecture lec) but the one from the parent class is still getting called.
Upvotes: 0
Views: 79
Reputation: 61870
Only class Lecture
defines addAttendant(Person p)
. So the this
in
public void addAttendant(Person p) {
p.join(this);
}
will always be a Lecture
.
And since Student
overrides join(Lecture lec)
, this overridden method gets called while lec3.addAttendant(p1);
since p1
is a Student
and lec3
is a Lecture
too.
Teacher
only overrides join(OnlineLecture lec)
but not join(Lecture lec)
. And lec3.addAttendant(p3);
calls Lecture.addAttendant(Person p)
where p
== p3
is a Teacher
but this
in p.join(this);
is a Lecture
but not a OnlineLecture
. That's why Teacher.join(OnlineLecture lec)
cannot be called since this
is not a OnlineLecture
but a Lecture
. So Person.join(Lecture lec)
gets called.
Not really clear what shall be achieved using that complex inheritance and nested method calling. So this is only the description of what is going on.
Upvotes: 1
Reputation: 2265
It is due to the join()
signature being more strongly typed in Person
than Student
As Student
only override for Lecture
in
public void join(Lecture lec){System.out.println("Student joining "+lec);}
The method used comes from parent class Person
public void join(OnlineLecture lec){System.out.println("Joining "+lec);}
As a solution, override correctly join
in Student
class with the given signature
public void join(OnlineLecture lec)
Upvotes: 1