sygede
sygede

Reputation: 41

casting a subclass object as superclass

I have some question about upcast/downcast.

I created an abstract super class Animal, subclass Dog and subclass BigDog. and I also give abstract method in Animal, and override it in Dog and BigDog.

abstract public class Animal {
    abstract public void greeting();
}

public class Dog extends Animal {
   @Override
   public void greeting() {
      System.out.println("Woof!");
   }
}

public class BigDog extends Dog {
   @Override
   public void greeting() {
      System.out.println("Woow!");
   }
}

now my test code:

public class TestAnimal {
   public static void main(String[] args) {

      Animal animal2 = new Dog();
      Animal animal3 = new BigDog();

      // Downcast
      Dog dog2 = (Dog) animal2;               //cast Animal class to Dog class, legit
      BigDog bigDog2 = (BigDog) animal3;      //cast Animal to BigDog, legit;
      Dog dog3 = (Dog) animal3;               //Animal Class contains BigDog cast into Dog?
      dog2.greeting();
      dog3.greeting();                    //in which class the method is called?
   }
}

I understand the relationship between superclass/subclass and how cast works. My question is, however, can you cast a superclass into a specific subclass, knowing there's a class in between? for example, if I have an Animal class object contains a BigDog object, can I cast the object to Dog? what if there are methods in BigDog that do not exist in Dog?

in short, you can certainly say a superclass object is a subclass object, but why can you invert?


On second thought,

I'm guessing this: I'm asking JVM cast an Animal class reference to Dog and link the new Dog reference to the BigDog object, rather than really casting the BigDog object.

So I can invoke all Dog and Animal methods on that Dog reference (to BigDog), but none of the BigDog methods, unless it was overridden in BigDog.

What Java checks when invoking a method is: if the reference (DOG) has the reference, and if the object(BigDog) has an override. if not, Dog method is called, otherwise, BigDog method is called.

Can anyone confirm my guess?

Upvotes: 2

Views: 2780

Answers (4)

extraneon
extraneon

Reputation: 23950

You can always cast to a specific subclass, unless the compiler is smart enough to know for certain that your cast is impossible.

The best way to cast to a subclass is to check if it can be done:

  if ( doggy instanceof BigDog ) {
      doSomethingWithBigdog( (BigDog) doggy );
  } else if ( doggy instanceof SmallDog ) {
      doSomethingWithSmalldog( (SmallDog) doggy );     
  } else {
     // Neither a big dog nor a small dog
  }

  ...

  private void doSomethingWithBigdog( BigDog dog ) {
    ...
  }

  private void doSomethingWithSmalldog( SmallDog dog ) {
    ...
  }

Keep in mind that casting is evil. Sometimes necessary, but often (not always) it can be designed away by implementing methods on the base class, or by not assigning a Dog to an Animal variable but to keep it a Dog.

Upvotes: 2

Pawel
Pawel

Reputation: 1467

First correct the source code, so it will compile. The proper usage of the methods: dog2.greeting(); and dog3.greeting(); or add method public void greeting(Animal animal);.


dog3.greeting(); - invoking method greeting() for dog3. dog3 has the same reference as animal3. animal3 has reference of BigDog so method greeting() is invoked to the class BigDog and the output is Woow!


When you inherit Dog from class Animal, then class Dog have all methods from class Animal.

Upvotes: 0

codeMan
codeMan

Reputation: 5758

There is no method whose signature will match with these method calls :

dog2.greeting(dog3);
dog3.greeting(dog2); 

so, Its pretty much a compilation failure.

You need to know about Dynamic Method Dispatch.

here are few links 1,2,3 go through them.

Upvotes: 0

Prabhaker A
Prabhaker A

Reputation: 8473

If I have an Animal class object contains a BigDog object, can I cast the object to Dog? what if there are methods in BigDog that do not exist in Dog?.

Simply you will get compiler error.Since you can't call a method that is not declared in parent and declared in child class using parent reference

Upvotes: 0

Related Questions