3

I have a class named Student and subclass called AthleteStudent:

public class Student {

    protected String name;
    protected String age;

    public void hello () {
        system.out.println("Hello I'm Student");
    }

}

public class AthleteStudent extends Student  {

    protected String sport;

    public void hello () {
        system.out.println("Hello I'm AthleteStudent");
    }

    public void changeDepartement() {
        .....
    }

}

Now let's take these test cases:

AthleteStudent ats = new AthleteStudent("test", 22, "Karate");
Student std;

std = ats;  // upcasting OK
/* ats and std point to the same object, i.e AthleteStudent */

ats.hello(); /* Hello I'm AthleteStudent => polymorphism OK */
std.hello(); /* Hello I'm AthleteStudent => polymorphism OK */

What I do not understand here is this one:

Even though std references a AthleteStudent I cannot access the method changeDepartement().

std.changeDepartement(); // Doesn't work

Only when we cast this object like this one it works

((AthleteStudent) std).changeDepartement(); // OK 

Why we need to force std to be an AthleteStudent object knowing that it is treated as a AthleteStudent object? With the first example, std.hello() prints the one from AthleteStudent implementation without problems.

Anderson Vieira
  • 8,919
  • 2
  • 37
  • 48
elDiablo
  • 51
  • 4

2 Answers2

8

This is not a loss of polymorphism. This is a lack of duck typing. When the compiler, statically, only knows that it's a Student it wont allow you to call non Student methods. Even though you know that, at run time, it will be available the static typing system of java says no. Other languages have duck typing that wouldn't care. Java isn't one of them.

Community
  • 1
  • 1
candied_orange
  • 7,036
  • 2
  • 28
  • 62
4

std is of type Student, and it may hold refrences to objects that are not an AthleteStudent. Therefore, you can't call std.changeDepartement() without an explicit cast to AthleteStudent.

Eran
  • 387,369
  • 54
  • 702
  • 768