Reputation: 841
I came accross the following code:
class Animal{
public void eat() throws Exception {}
}
class Dog extends Animal{
public void eat(){} //no exception thrown
public static void main(String[] args){
Animal a = new Dog();
Dog d = new Dog();
d.eat(); //ok
a.eat(); //does not compile!..(1)
}
}
Here, (1) does not compile even though at runtime Dog's eat() method will be called. Why does this happen? What is the reason that Java supports this? Shouldn't this be filed as a bug?
Upvotes: 3
Views: 129
Reputation: 2614
First thing that you are not following the rules of Method Overriding. if Base class method is throwing any Exception then child class method must throw equal or Low Level Exception. now this code will work fine because its following the method overriding rules. Also @Elliot is saying right thing, compiler doesn't aware of dog object(as Animal is referring) at compile time. it will resolve only at Run Time.
class Animal{
public void eat() throws Exception {}
}
class Test extends Animal{
public void eat()throws Exception{}
public static void main(String[] args)throws Exception{
Animal a = new Test();
Test d = new Test();
d.eat();
a.eat();
}
}
Upvotes: 3
Reputation: 30276
Animal a = new Dog();
in OOP (Object Oriented Programming)
, this is called polymorphism
. And in Java (and mostly in OOP support language such as C#), this behavior is compile checking. That means compiler at compile time just knows a is a animal, and cannot know a is a dog until runtime.
For example:
Animal a = new Dog();
a.bark(); // cannot. because compiler doesn't know a is a dog until runtime
((Dog)a).bark(); // yes. we say to compiler: a **must** be a dog
Another example is:
Animal a = new Cat();
// yes. can compile. we force compiler to know this animal is a dog.
//but will run-time exception because in fact this is a cat
((Dog)a).bark();
Hope this help :)
Upvotes: 3
Reputation: 201447
Because you're using an Animal
reference to refer to a Dog
. And the signature of Animal.eat
includes the Exception
. The compiler knows that a Dog
is a kind of Animal
, but once you use an Animal
reference it doesn't know that it's a Dog
until runtime.
To put it another way, all Dog
(s) are Animal
(s) but not all Animal
(s) are Dog
(s).
Edit
You could have added a cast
((Dog) a).eat(); //would compile
At runtime, that will fail if a
isn't in fact a Dog
.
Upvotes: 7