Fiorenzo
Fiorenzo

Reputation: 23

Java subclass method is getting ignored

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

Answers (2)

Axel Richter
Axel Richter

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

IQbrod
IQbrod

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

Related Questions