2

Let's say I have a superclass of Animal, and a subclass of Dog.

We can upcast by saying:

Animal a = new Dog();

We CANNOT downcast by saying:

Dog b = new Animal();

So I do understand that an animal does not HAVE to be a dog. But, why would having an animal "blueprint" in a dog container throw an exception? Because Dog inherits methods from Animal, when we take this animal and put it into a dog container, we know Dog inherits/overrides all methods that Animal has, so why does Java not allow this?

Thank you!

Jay Harris
  • 4,201
  • 17
  • 21
rb612
  • 5,280
  • 3
  • 30
  • 68
  • Think about it, when you say animal you can't automatically assume its a dog. but you could the other way around – Jay Harris Apr 27 '15 at 23:51

3 Answers3

7
Dog b = new Animal();
b.Woof();

Animal has no interface/method called Woof(). It does not know how to behave like a dog, but all dogs know how to behave like an animal.

Eric J.
  • 147,927
  • 63
  • 340
  • 553
2

Short answer: because a dog is an animal, but an animal is not necessarily a dog.

Slightly longer answer: if you were able to do that, you could call Dog methods on an Animal object that does not necessarily define those methods.

Robby Cornelissen
  • 91,784
  • 22
  • 134
  • 156
1

Although we know that Dog includes all methods of Animal, we don't know that Animal includes all methods of Dog.

Consider for instance if Dog adds a method bark(). We should be able to call bark() on any object of type Dog; but if we can store an Animal there, we can store any type of Animal, say a Cat. Then we'd find ourselves asking a Cat to bark(), and something would go very wrong.

We can say that a Dog is an Animal, and a Cat is an Animal, but we can't say that an Animal is a Dog, or that a Cat is a Dog. Therefore if our variable "is a Dog", storing an Animal there wouldn't make sense.

IMSoP
  • 89,526
  • 13
  • 117
  • 169