Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Ploymorphism

Posted on 2002-04-29
1
Medium Priority
?
498 Views
Last Modified: 2008-03-03
i came to know that there are 2 types of ploymophism in java language ;

first one the runtime and the other static polymorphism...

please explain me these two types of polymorphism..

better with an example
0
Comment
Question by:yrrm
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
1 Comment
 
LVL 19

Accepted Solution

by:
Jim Cakalic earned 200 total points
ID: 7014826
Dynamic polymorphism is the "classic" form of polymorphism talked about in object-oriented development. It is obtained through the use of abstract base classes and method overriding. Remember that "method overriding" is when a subclass defines and implements a method with the identical signature as its superclass or implements an abstract method or an interface-declared method with a specific signature. With dynamic polymorphism, designers cast their designs in terms of abstract classes and the interfaces they provide and then substitute derived class objects where base class objects are expected. The actual type (class) of the object is used at run time to resolve which method should be called. An excellent example here is java.io.Reader and its implementations. The abstract class java.io.Reader defines a base set of services that can be expected of any reader. Some of these services are defined as abstract methods and others are concrete. Implementations such as FileReader, StringReader, and BufferedReader extend java.io.Reader (or another of its subclasses) and provide specialized implementations of the same methods. Once one of these specialized objects is constructed, clients are able to substitute them anywhere java.io.Reader is used and the JVM will resolve method calls to the subclass at run-time.

    // originally 'in' is a FileReader
    Reader in = new FileReader(filename);
    char[] buf = new char[100];
    in.read(buf);
    in.close();
    // now 'in' is a StringReader with same methods available
    in = new StringReader(new String(buf));
    for (int char = in.read(); char >= 0; char = in.read()) {
    }
    in.close();

I don't think a whole lot more needs to be said about this. The compiler issues invoke instructions based on the type of the 'in' object being a Reader. At run time, the JVM determines the actual class of the 'in' object and finds the read method defined by the most-derived subclass in the inheritance hierarchy for the object. That's "dynamic polymorphism" because it happens at run time.

Static polymorphism, on the other hand, is a compile time binding. In Java, the only way that it can be obtained is by method overloading. A method with the same name can have different signatures. When the compiler encounters code that calls an overloaded method, it determines the type of the object being passed as a parameter to the method based on the nearest declaration of the object reference and selects the appropriate overloaded method. Note that the method is chosen at compile time, not at run time. As such, the binding is static, not dynamic. An example here is the java.io.PrintWriter. It defines a number of overloaded print and println methods. There is a println(String) and a println(Object). When the compiler encounters a PrintWriter.println(ref) method in your code, it determines, based on the nearest declaration of 'ref' whether or not it is a String. If it can determine that it is indeed a String then it issues bytecode to invoke the println(String) otherwise it issues bytecode to invoke the println(Object) method. This can get 'tricky' as the following code reveals:

public class StaticPolymorphism {
    PrintWriter out = new PrintWriter(System.out);

    public void printOnce(Object ref) {
        out.println(ref);
    }

    public void printTwice(String ref) {
        out.println(ref);
        printOnce(ref);
    }

    public static void main(String[] args) {
        String s = "Hello, world!";
        StaticPolymorphism instance = new StaticPolymorphism();
        instance.printTwice(s);
    }
}

Here the call to printTwice takes a String parameter. Within the printTwice method the compiler determines that the nearest declaration of 'ref' is a String from the formal arguments of the method. So the call to out.println(ref) in printTwice calls PrintWriter.println(String). The call to printOnce from printTwice, however, might cause you some confusion. Within printOnce, will the out.println(ref) end up calling PrintWriter.println(String) or PrintWriter.println(Object)? We look at the code and can deduce that in this once scenario a String is being passed. But because printOnce declares that its parameter is an Object, the compiler cannot make the same assumption. The fact of the matter is that the type of 'ref' within printOnce is Object. Therefore the compiler statically binds to the PrintWriter.println(Object) method. The run time type of the object has no effect on which method is called. To prove it, here's the bytecode for printOnce and printTwice:

    public void printOnce(Object obj)
    {
        out.println(obj);
    //    0    0:aload_0        
    //    1    1:getfield        #12  <Field PrintWriter out>
    //    2    4:aload_1        
    //    3    5:invokevirtual   #15  <Method void PrintWriter.println(Object)>
    //    4    8:return          
    }

    public void printTwice(String s)
    {
        out.println(s);
    //    0    0:aload_0        
    //    1    1:getfield        #12  <Field PrintWriter out>
    //    2    4:aload_1        
    //    3    5:invokevirtual   #21  <Method void PrintWriter.println(String)>
        printOnce(s);
    //    4    8:aload_0        
    //    5    9:aload_1        
    //    6   10:invokevirtual   #23  <Method void printOnce(Object)>
    //    7   13:return          
    }

Notice that in printOnce the target of the invokevirtual instruction for out.println(ref) is method #15 in the class of the 'out' object which the comment from the class decompiler identifies as PrintWriter.println(Object). In printTwice, the target of the invokevirtual for out.println(ref) is method #21 in the class of the 'out' object which is identified as PrintWriter.println(String). The compiler determined which overloaded method to call based on the nearest declaration of the object. That's "static polymorphism" because it happens at compile time.

Hope that helps.

Best regards,
Jim Cakalic
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
In this post we will learn different types of Android Layout and some basics of an Android App.
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
Viewers will learn about the regular for loop in Java and how to use it. Definition: Break the for loop down into 3 parts: Syntax when using for loops: Example using a for loop:
Suggested Courses

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question