Elaborating on Polymorphism

2019-07-13 13:11发布

问题:

I have read many questions on stackoverflow about polymorphism. The question is a question of structuring my ideas because I have read and researched a lot to the point where I have many ideas in mind. I need comments and criticism about my thoughts on polymorphism. I will use Java to demonstrate my ideas.

Polymorphism is a characteristic of having different forms when talking about a certain entity. It could be achieved in the following ways:

  • A derived class inherits from its base class all the visible methods and accordingly could override the behaviour of certain methods. e.g:

    class Shape {
       void draw(){
             System.out.println("I am drawing using a shape object");
       }
    }
    
    class Rectangle extends Shape{
       void draw(){
         // This method is overriden
         System.out.println("I am drawing using a rectangle object");
       }
    }
    

The way polymorphism is achieved here is that if at run-time, draw() was used with an instance of Rectangle the implementation of draw() in the Rectangle class would be invoked.

Since a rectangle is a shape, polymorphism is the fact that draw() took different forms depending on the context where it was being called. This is also known as inheritance polymorphism.

  • Another way to achieve polymorphism is through interfaces.

    interface Vehicle{
         void move();
    }
    
    class Car implements Vehicle{
         void move(){
             System.out.println("The car is moving!");
         }
    }
    
    class Plane implements Vehicle{
         void move(){
             System.out.println("The plane is flying!");
         }
    }
    
    // we declare an object of type Vehicle
    // At compile-time, the concrete implementation of someVehicle is no known  
    // and thus polymorphism is achieved in the sense that someVehicle could
    // either be a Car or a Plane depending on which concrete class is used 
    // to instantiate it at run-time.
    
    Vehicle someVehicle;
    
  • User-defined operator overloading(Not in Java, but in C++)

In Java, an example of operator overloading would be the + operator where depending on the operands, the + performs a certain functionality. If + is being applied to strings, it concatenates them. If it is being applied to integers, it does arithmetic addition.

Now, is method overloading also a way to achieve polymorphism? What did I miss in my understanding of polymorphism?

回答1:

The word Polymorphism means "many forms".

The two examples that you give are definitively valid examples of polymorphism:

  • In the first example you have "many forms" of the "draw" functionality depending on what kind of Shape is the object you call "draw" on

  • In the second one you have "many forms" of the "move" functionality depending on the vehicle

The actual method that will be invoked is decided at run time due to late binding.

In fact, both examples are quite similar and they are both examples of subtyping which is the way you implement polymorphism in Java.

Note that subtyping is needed in Java cause Java is a statically typed language. In dynamically typed languages like Smalltalk, having different implementations of the "draw" method would be enough, even if the objects' classes did not belong to the same class hierarchy.

Now, about method overloading: it's true that if you define several versions of a method receiving different parameter types you'd also have "many forms" of that method.

The difference is that in that case, the decision of which method to call is made at compile-time. That's why many people refer to method overloading as static polymorphism.

However, due to the fact that it's static and that you could basically achieve the same thing by giving different names to the methods and deciding yourself which one to call based on the types you are using, many people would also say that method overloading is not actually polymorphism.

I think it basically depends on the definition of "polymorphism" you want to use, but I hope the above explanation helps clarify the difference.



回答2:

I think you are getting confused with something else happening in java. Operator overloading is a form of polymorphism in other programming languages like C++, however in java their is a distinction between primatives such as ints and booleans (String sort of as well) and everything else which extends the base java.lang.Object. The language designers decided not to have operator overloading for class because it can be very confusing. So you don't have operator polymorphism effectively in Java because you cant define your own operators or override others, except for the toString() method, but that is really an interface in my opinion. I don't think you can say that the + (for strings) operator is an example of operator overloading in java, even with strings, it is the toString() method being called, and that is not really operator overloading in my opinion because operators only have that term when you apply the rules as to which order the operations are performed. If you have only one operator, the + which concatonates strings togther then no rules to order of evalution are ever applied so it is merly a syntax thing. You have operators for +,-,/ for ints and floats but you can't overload them so that is not polymorphism.



回答3:

Polymorphism behaves in the way you have explained, but is not the actual act of implementing new methods that override previously defined methods. Polymorphism is more of an abstract idea. In general:

Polymorphism is the ability of an object to take on many forms. The most common use of polymorphism in OOP occurs when a parent class reference is used to refer to a child class object.

More information can also be found here.