How does polymorphism work with overloaded methods? From what we just looked at, it doesn't appear that polymorphism matters when a method is overloaded. If you pass an Animal reference, the overloaded method that takes an Animal will be invoked, even if the actual object passed is a Horse. Once the Horse masquerading as Animal gets in to the method, however, the Horse object is still a Horse despite being passed into a method expecting an Animal. So it's true that polymorphism doesn't determine which overloaded version is called; polymorphism does come into play when the decision is about which overridden version of a method is called. But sometimes, a method is both overloaded and overridden. Imagine the Animal and Horse classes look like this:
public class Animal {
public void eat () {
System.out.println("Generic Animal Eating Generically"};
}
}
public class Horse extends Animal {
public void eat() {
System.out.println("Horse eating hay ");
}
public void eat(String s) {
System, out .println ("Horse eating " + s) ;
}
}
Notice that the Horse class has both overloaded and overridden the eat() method. Table 2-2 shows which version of the three eat() methods will run depending on how they are invoked.
Table 2-2: Examples of Illegal Overrides Method Invocation Code
Result
Animal a = new Animal(); a.eat();
Generic Animal Eating Generically
Horse h = new Horse(); h.eat();
Horse eating hay
Animal ah = new Horse (); ah.eat();
Horse eating hay
Polymorphism works—the actual object type (Horse), not the reference type (Animal), is used to determine which eat() is called.
Horse he = new Horse(); he.eat("Apples") ;
Horse eating Apples
The overloaded eat(String s) method is invoked.
Animal a2 = new Animal(); a2.eat ("treats");
Compier error! Compiler sees that Animal class doesn't have an eat() method that takes a String.
Animal ah2 = new Horse(); ah2.eat("Carrots");
Compiler error! Compiler still looks only at the reference, and sees that Animal doesn't have an eat() method that takes a String. Compiler doesn't care that the actual object might be a Horse at runtime.
Exam Watch
Don't be fooled by a method that's overloaded but not overridden by a subclass. It's perfectly legal to do the following:
public class Foo {
void doStufff() { }
}
class Bar extends Foo {
void doStuff(String s) { }
}
The Bar class has two dostuff () methods: the no-arg version it inherits from Foo (and does not override), and the overloaded dostuff (string s) defined in the Bar class. Code with a reference to a Foo can invoke only the no-arg version, but code with a reference to a Bar can invoke either of the overloaded versions.
No comments:
Post a Comment