Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why superclass object cannot be implicitly converted to subclass object in Java?

I have the following code:

class A {
}

class B extends A {
    public void fB(){};
}

According to Java rule:

Case 1:

B b = new B();
A a = b;
((B)a).fB();

Case 2:

A a = new A();
B b = a;

According to Java rule, Case 1 is ok and Case 2 is not ok. Why Case 2 is not ok? And what this line ((B)a).fB(); actually does (I mean what happens inside)?

like image 754
ipkiss Avatar asked Dec 04 '22 17:12

ipkiss


2 Answers

Why case 1 is OK and case 2 is not OK: Because a Dog is an Animal, but not every Animal is a Dog.

class Animal { }
class Dog extends Animal { }
class Cat extends Animal { }

Dog fifi = new Dog();
Cat tommy = new Cat();

// OK because Dogs and Cats are Animals
Animal pet1 = fifi;
Animal pet2 = tommy;

// Not OK because an Animal is not always a Dog
Dog doggy = pet2;

Note that casting does nothing to the object; in particular, it doesn't do any kind conversion of objects. Casting is only telling the compiler "I have this object here, and I know better than you what it is; I want you to treat it as type X and not give me any error messages".

So in a line like this:

Dog doggy = pet2;

the compiler will complain because it cannot be sure that pet2 is actually a Dog; it only knows that it is an Animal - and not all Animals are Dogs. You can do a cast to tell the compiler to not complain about this:

// Tell the compiler that you want it to treat pet2 as a Dog
Dog doggy = (Dog)pet2;

But when you run the program, Java will still check if pet2 is really a Dog, and if it isn't, you get a ClassCastException.

(And the question in your title is exactly the opposite of what you mean, as biziclop noticed).

like image 78
Jesper Avatar answered Dec 07 '22 07:12

Jesper


Ok, think about 2 people: Doctor and Engineer. Doctor can treat, engineer can build. Both are persons.

Now here is your example.

Person p = new Person(); // somebody that does not know to do anything special.
Doctor d = (Doctor)p; // do you think that casting makes person that does not know anything to be a doctor?

Do you want to be treated by person that was "cast" to be a doctor you do you prefer the real Doctor?

I believe that the answer is clear. Each doctor is a person (case 1) but not each person is a doctor because not each person can treat. Exactly the same is relevant for class hierarchy too. Subclass inherits its super class' properties and probably adds its own. Therefore not any instance of superclass can be cast to subclass.

like image 24
AlexR Avatar answered Dec 07 '22 06:12

AlexR