Argument(s)
Overloaded Method : Must change.
Must not change.
Return type
Overloaded Method :Can change.
Overridden Method :Can't change except for covariant returns.
Exceptions
Overloaded Method :Can change.
Overridden Method :Can reduce or climinate. Must not throw new or broader checked exceptions.
Access
Overloaded Method :Can change.
Overridden Method :Must not make more restrictive (can be less restrictive).
Invocation
Overloaded Method :Reference type determines which overloaded version (based on declared argument types) is selected. Happens at compile time. The actual method that's invoked is still a virtual method invocation that happens at runtime, but the compiler will already know the signature of the method to be invoked. So at runtime, the argument match will already have been nailed down, just not the class in which the method lives.
Overridden Method :Object type (in other words, the type of the actual instance on the heap) determines which method is selected. Happens at runtime.
Welcome Message
Hi, welcome to my website. This is a place where you can get all the questions, puzzles, algorithms asked in interviews and their solutions. Feel free to contact me if you have any queries / suggestions and please leave your valuable comments.. Thanks for visiting -Pragya.
Top Navigation Menu
Showing posts with label Polymorphism. Show all posts
Showing posts with label Polymorphism. Show all posts
January 18, 2010
Polymorphism in Overloaded and Overridden Methods
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.
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.
Labels:
java,
Overloading,
Overriding,
Polymorphism
All about Overloading
The rules are simple:
Overloaded methods MUST change the argument list.
Overloaded methods CAN change the return type.
Overloaded methods CAN change the access modifier.
Overloaded methods CAN declare new or broader checked exceptions.
A method can be overloaded in the same class or in a subclass. In other words, if class A defines a dostuff(int i) method, the subclass B could define a dostuff (String s) method without overriding the superclass version that takes an int. So two methods with the same name but in different classes can still be considered overloaded, if the subclass inherits one version of the method and then declares another overloaded version in its class definition.
Overloaded methods MUST change the argument list.
Overloaded methods CAN change the return type.
Overloaded methods CAN change the access modifier.
Overloaded methods CAN declare new or broader checked exceptions.
A method can be overloaded in the same class or in a subclass. In other words, if class A defines a dostuff(int i) method, the subclass B could define a dostuff (String s) method without overriding the superclass version that takes an int. So two methods with the same name but in different classes can still be considered overloaded, if the subclass inherits one version of the method and then declares another overloaded version in its class definition.
Labels:
java,
Overloading,
Polymorphism
Very Important concept about overriding
If a method is overridden but you use a polymorphic (supertype) reference to refer to the subtype object with the overriding method, the compiler assumes you're calling the supertype version of the method. If the supertype version declares a checked exception, but the overriding subtype method does not, the compiler still thinks you are calling a method that declares an exception (more in Chapter 5). Let's take a look at an example:
class Animal {
public void eat() throws Exception {
// throws an Exception
}
}
class Dog2 extends Animal {
public void eat() { // no Exceptions }
public static void main(String [] arga) {
Animal a = new Dog2();
Dog2 d = new Dog2();
d.eat(); // ok
a.eat(); // compiler error -
// unreported exception
}
}
This code will not compile because of the Exception declared on the Animal eat() method. This happens even though, at runtime, the eat() method used would be the Dog version, which does not declare the exception.
class Animal {
public void eat() throws Exception {
// throws an Exception
}
}
class Dog2 extends Animal {
public void eat() { // no Exceptions }
public static void main(String [] arga) {
Animal a = new Dog2();
Dog2 d = new Dog2();
d.eat(); // ok
a.eat(); // compiler error -
// unreported exception
}
}
This code will not compile because of the Exception declared on the Animal eat() method. This happens even though, at runtime, the eat() method used would be the Dog version, which does not declare the exception.
Labels:
java,
Overriding,
Polymorphism
All about overriding
The rules for overriding a method are as follows:
The argument list must exactly match that of the overridden method. If they don't match, you can end up with an overloaded method you didn't intend.
The return type must be the same as, or a subtype of, the return type declared in the original overridden method in the superclass. (More on this in a few pages when we discuss covariant returns.)
The access level can't be more restrictive than the overridden method's.
The access level CAN be less restrictive than that of the overridden method.
Instance methods can be overridden only if they are inherited by the subclass. A subclass within the same package as the instance's superclass can override any superclass method that is not marked private or final. A subclass in a different package can override only those non-final methods marked public or protected (since protected methods are inherited by the subclass).
The overriding method CAN throw any unchecked (runtime) exception, regardless of whether the overridden method declares the exception. (More in Chapter 5.)
The overriding method must NOT throw checked exceptions that are new or broader than those declared by the overridden method. For example, a method that declares a FileNotFoundException cannot be overridden by a method that declares a SQLException, Exception, or any other non-runtime exception unless it's a subclass of FileNotFoundException.
The overriding method can throw narrower or fewer exceptions. Just because an overridden method "takes risks" doesn't mean that the overriding subclass' exception takes the same risks. Bottom line: an overriding method doesn't have to declare any exceptions that it will never throw, regardless of what the overridden method declares.
You cannot override a method marked final.
You cannot override a method marked static. We'll look at an example in a few pages when we discuss static methods in more detail.
If a method can't be inherited, you cannot override it. Remember that overriding implies that you're reimplementing a method you inherited! For example, the following code is not legal, and even if you added an eat() method to Horse, it wouldn't be an override of Animal's eat() method.
public class TestAnimals {
public static void main (String [] args) {
Horse h = new Horse();
h.eat(); // Not legal because Horse didn't inherit eat()
}
}
class Animal {
private void eat() {
System.out.println("Generic Animal Eating Generically");
}
}
class Horse extends Animal { }
The argument list must exactly match that of the overridden method. If they don't match, you can end up with an overloaded method you didn't intend.
The return type must be the same as, or a subtype of, the return type declared in the original overridden method in the superclass. (More on this in a few pages when we discuss covariant returns.)
The access level can't be more restrictive than the overridden method's.
The access level CAN be less restrictive than that of the overridden method.
Instance methods can be overridden only if they are inherited by the subclass. A subclass within the same package as the instance's superclass can override any superclass method that is not marked private or final. A subclass in a different package can override only those non-final methods marked public or protected (since protected methods are inherited by the subclass).
The overriding method CAN throw any unchecked (runtime) exception, regardless of whether the overridden method declares the exception. (More in Chapter 5.)
The overriding method must NOT throw checked exceptions that are new or broader than those declared by the overridden method. For example, a method that declares a FileNotFoundException cannot be overridden by a method that declares a SQLException, Exception, or any other non-runtime exception unless it's a subclass of FileNotFoundException.
The overriding method can throw narrower or fewer exceptions. Just because an overridden method "takes risks" doesn't mean that the overriding subclass' exception takes the same risks. Bottom line: an overriding method doesn't have to declare any exceptions that it will never throw, regardless of what the overridden method declares.
You cannot override a method marked final.
You cannot override a method marked static. We'll look at an example in a few pages when we discuss static methods in more detail.
If a method can't be inherited, you cannot override it. Remember that overriding implies that you're reimplementing a method you inherited! For example, the following code is not legal, and even if you added an eat() method to Horse, it wouldn't be an override of Animal's eat() method.
public class TestAnimals {
public static void main (String [] args) {
Horse h = new Horse();
h.eat(); // Not legal because Horse didn't inherit eat()
}
}
class Animal {
private void eat() {
System.out.println("Generic Animal Eating Generically");
}
}
class Horse extends Animal { }
Labels:
java,
Overriding,
Polymorphism
Subscribe to:
Posts (Atom)