-2

I have three classes.

Person <-- Student <-- GradStudent, where <-- means extends (ie, GradStudent extends Student, Student extends Person)

Person person = new Student(); // this is perfectly legal

GradStudent gradStudent = (GradStudent) person;
System.out.println(gradStudent); // java.lang.ClassCastException here

Why? Our person variable is a Student, and we could do Student s = new GradStudent(), and so why is this not working?

Similarly if I do

Student student = new Student();
GradStudent aGradStudent = (GradStudent) student;
System.out.println(aGradStudent); // same error here

Why can we do Student s = new GradStudent(), but we cannot do Student student = new Student(), and THEN GradStudent aGradeStudent = (GradStudent) student

K Split X
  • 3,405
  • 7
  • 24
  • 49
  • Upcasting is always allowed in Java and it's implicit and also because a sub-class it's different from a sub-type which respect the substitution principle. – simo-r Oct 07 '17 at 16:34

1 Answers1

1

This is because it's not safe to say that every instance of Person or Student is also an instance of GradStudent. But every instance of GradStudent or Student is also an instance of Person.
You can always abstract to a higher level of the hierarchy, but not in the other direction.

bkis
  • 2,530
  • 1
  • 17
  • 31
  • What I dont understand is that how is casting any different from just declaring `Student student = new GradStudent()`? – K Split X Oct 07 '17 at 16:35
  • Because this is a declaration which has static type Student and dynamic type GradStudent which is upcasted. See dynamic dispatch in Java for more details. – simo-r Oct 07 '17 at 16:41
  • 1
    In this context it's not: You can do `Student student = new GradStudent();` **and** could cast `Student student = (Student) gradStudent;`. But the latter wouldn't make sense, because you don't need that cast. Every `GradStudent` **is** a `Student`. There's nothing to cast. – bkis Oct 07 '17 at 16:42