Polymorphic method invocations apply to instance methods. You can always the refer to a and a more general reference variable type (a superclass or interface), but at runtime, The only things this is are dynamically selected based on the actual object (rather than the reference type) are instance me Thods. Not static methods. Not variables. Only overridden instance methods are dynamically invoked in the real object ' s type.
1. Overridden Methods
(1) Example of using polymorphism looks like this:
Class Animal {public
void Eat () {
System.out.println (' Generic Animal eating generically ');
}
Class Horse extends Animal {public
void Eat () {
System.out.println ("Horse eating hay, oats," + "and horse treats ");
}
public void, Buck () {}
} public
class Testanimals {public
static void Main (String [] args) {
Animal a = new Animal ();
Animal B = new Horse (); Animal ref, but a horse object
a.eat (); Runs the Animal version of Eat ()
b.eat (); Runs the horse version of Eat ()
// B.buck (); Can ' t invoke Buck ();
Animal class doesn ' t have this method
}
}
bis an
AnimalReference, so at compile time, the compiler knows
b.eat ()is OK because
AnimalHas
Eat ()Method. But
bActually is a
HorseObject, so the JVM dynamically calls the
horse eat ()Method at runtime.
(2) Rules for overriding a
The overriding method cannot have a to restrictive access modifier than the method being overridden (for example, your CA N ' t override a method marked public and make it protected).
Let's modify the polymorphic example we saw earlier in:
Class Animal {public
void Eat () {
System.out.println (' Generic Animal eating generically ');
}
Class Horse extends Animal {
private void eat () { //whoa!-it ' s private!
System.out.println ("Horse eating hay, oats," + "and horse Treats");
}
public void Buck () {}
} public
class TestAnimals2 {public
static void Main (String [] args) {
Animal A = new Animal ();
Animal B = new Horse (); Animal ref, but a horse object
a.eat (); Runs the Animal version of Eat ()
b.eat (); Runs the horse version of Eat ()
}
}
This code does not compile:
If This is the code compiled (which it doesn ' t), the following would fail at runtime:
Animal B = new Horse (); Animal ref, but a horse
b.eat (); Object, so far good
//meltdown at runtime!
The rules for overriding a method are as follows:
(1) The argument list must exactly match that is the overridden method. If they don ' t match, you can end up with a overloaded method for you didn ' t intend.
(2) The return type must is the same as, or a subtype of, the return type declared in the original The superclass. (covariant returns)
(3) The access level can ' t is more restrictive than the overridden method ' s. (But CAN be less restrictive)
( 4) The overriding method CAN throw any unchecked (runtime) exception, regardless of whether to the overridden method Declares the exception.
(5) The overriding method must not throw checked exceptions this are new or broader than those declared by the Ove Rridden method. For example, a and that declares a filenotfoundexception cannot is overridden by a to that declares a SQLException, Exception, or any of the other non-runtime Exception unless it ' s a subclass of FileNotFoundException.
(6) The overriding method can throw narrower or fewer or no exceptions.
(7) cannot override a method marked final or static.
(8) Static methods can ' t be overridden! But They can be redefined in a subclass.
2. Overloaded Methods
The rules are simple:
(1) Overloaded methods must change the argument list.
(2) Overloaded methods CAN change the return type.
(3) Overloaded methods CAN change the access modifier.
(4) Overloaded methods CAN declare new or broader checked exceptions.
(5) A method can is overloaded in the same class or in A subclass.
3. Differences Between overloaded and overridden Methods
4. Some examples
(1) Pitfall: "Overriding" Private methods
public class Privateoverride {
private void F () {System.out.println ("Private f ()");}
public static void Main (string[] args) {
privateoverride po = new Derived ();
PO.F ();
}
Class Derived extends Privateoverride {public
void F () {System.out.println (' public f () ');}
Output
(2) Behavior of polymorphic methods inside constructors
public class Callinsideconstructor {public
callinsideconstructor () {
f1 ()
}
public void F1 () {
System.out.println ("Inside F1 ()");
}
public static void Main (string[] args) {
new Callinsideconstructor ();
}
}
Output
The following code is strange:
Class Glyph {
void Draw () {System.out.println ("Glyph.draw ()");}
Glyph () {
System.out.println ("Glyph () before Draw ()");
Draw (); It calls the overriding method in subclass Roundglyph
System.out.println ("Glyph () after draw ()");
}
Class Roundglyph extends Glyph {
private int radius = 1;
Roundglyph (int r) {
radius = R;
System.out.println ("roundglyph.roundglyph (), radius =" + radius);
}
void Draw () {
System.out.println ("Roundglyph.draw (), radius =" + radius);
}
public class Polyconstructors {public
static void Main (string[] args) {
new roundglyph (5);
}
}
Output
If you call a dynamically bound method inside a constructor, the overridden definition for this is also used.
However, the effect of this call can is rather unexpected because the overridden method would be called before the object I s fully constructed.
Constructor "Initializes" the state of the object and isn't used for "creating" the object as the name deceptively sugges Ts. When JVM loads a class, it entire definition is injected into the memory. When a draw () was called in the superclass constructor, the runtime looks up the polymorphic definition of TheDraw ()method and finds this there is a overridden draw () method available and thus calls the Subclas S(roundglyph) Draw () implementation. The "point" to "note" The entire class definition is always available in memory and calling a object method has no Conne Ction to whether the object was fully initialized or not.