9.12. The final Classes, Methods, and Variables

 
[Page 311 ( continued )]

9.7. Polymorphism , Dynamic Binding , and Generic Programming

The inheritance relationship enables a subclass to inherit features from its superclass with additional new features. A subclass is a specialization of its superclass; every instance of a subclass is an instance of its superclass, but not vice versa. For example, every circle is an object, but not every object is a circle. Therefore, you can always pass an instance of a subclass to a parameter of its superclass type. Consider the code in Listing 9.5.

Listing 9.5. PolymorphismDemo.java
(This item is displayed on pages 311 - 312 in the print version)
 1    package   chapter9;  2 3   public class   PolymorphismDemo { 4   public static void   main(String[] args) { 5 m(   new   GraduateStudent()); 6 m(   new   Student()); 7 m(   new   Person()); 8 m(   new   Object()); 9 } 10 11   public static void    m(Object x)  { 12 System.out.println(x.toString()); 13 } 14 } 15 16   class    GraduateStudent   extends   Student  { 17 } 18 19   class    Student   extends   Person  { 20   public   String  toString()  { 21   return   "Student"   ; 22 } 23 } 24 

[Page 312]
 25   class    Person   extends   Object  { 26   public   String  toString()  { 27   return   "Person"   ; 28 } 29 } 

It produces the output shown in Figure 9.3. Why? Let us discuss the reason. Method m (line 11) takes a parameter of the Object type. You can invoke m with any object (e.g., new GraduateStudent() , new Student() , new Person() , and new Object() ) in lines 5 “8). An object of a subtype can be used wherever its supertype value is required.

Figure 9.3. An instance of a subclass is also an instance of its superclass.


When the method m(Object x) is executed, the argument x 's toString method is invoked. x may be an instance of GraduateStudent , Student , Person , or Object . Classes GraduateStudent , Student , Person , and Object have their own implementations of the toString method. Which implementation is used will be determined dynamically by the Java Virtual Machine at runtime. This capability is known as dynamic binding . It is also known as polymorphism (from a Greek word meaning "many forms") because one method has many implementations.

Dynamic binding works as follows : Suppose an object o is an instance of classes C 1 , C 2 , ..., C n-1 , and C n , where C 1 is a subclass of C 2 , C 2 is a subclass of C 3 , ..., and C n-1 is a subclass of C n , as shown in Figure 9.4. That is, C n is the most general class, and C 1 is the most specific class. In Java, C n is the Object class. If o invokes a method p , the JVM searches the implementation for the method p in C 1 , C 2 , ..., C n-1 , and C n , in this order, until it is found. Once an implementation is found, the search stops and the first-found implementation is invoked. For example, when m(new GraduateStudent()) is invoked in line 5, the toString method defined in the Student class is used.


[Page 313]
Figure 9.4. The method to be invoked is dynamically bound at runtime.
(This item is displayed on page 312 in the print version)


Note

Matching a method signature and binding a method implementation are two separate issues. The declared type of the reference variable decides which method to match at compile time. The compiler finds a matching method according to parameter type, number of parameters, and order of the parameters at compile time. A method may be implemented in several subclasses. The Java Virtual Machine dynamically binds the implementation of the method at runtime, decided by the actual class of the object referenced by the variable.


Note

Dynamic binding enables new classes to be loaded on the fly without recompilation. There is no need for developers to create, and for users to install, major new software versions. New features can be incorporated transparently as needed. For example, suppose you have placed the classes Test , GraduateStudent , Student , Person in four separate files. If you change Graduate-Student as follows:

   class    GraduateStudent   extends   Student  {   public   String  toString()  {   return   "Graduate Student"   ; } } 

You have a new version of GraduateStudent with a new toString method, but you don't have to recompile the classes Test , Student , and Person . When you run Test , the JVM dynamically binds the new toString method for the object of GraduateStudent when executing m(new GraduateStudent()) .


Polymorphism allows methods to be used generically for a wide range of object arguments. This is known as generic programming . If a method's parameter type is a superclass (e.g., Object ), you may pass an object to this method of any of the parameter's subclasses (e.g., Student or String ). When an object (e.g., a Student object or a String object) is used in the method, the particular implementation of the method of the object invoked (e.g., toString ) is determined dynamically.

 


Introduction to Java Programming-Comprehensive Version
Introduction to Java Programming-Comprehensive Version (6th Edition)
ISBN: B000ONFLUM
EAN: N/A
Year: 2004
Pages: 503

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net