Polymorphism in object-oriented programming

From Wikipedia, the free encyclopedia
Jump to: navigation, search

Subtype polymorphism, almost universally called polymorphism in the context of object-oriented programming, is the ability to create a variable, a function, or an object that has more than one form. The word derives from the Greek "πολυμορφισμός" meaning "having multiple forms". In principle, polymorphism can however arise in other computing contexts and it shares important similarities to the concept of degeneracy in biology.

The purpose of polymorphism is to implement a style of programming called message-passing in the literature[citation needed], in which objects of various types define a common interface of operations for users. In strongly typed languages, polymorphism usually means that type A somehow derives from type B, or type C implements an interface that represents type B. In weakly typed languages types are implicitly polymorphic.

Operator overloading of the numeric operators (+, -, *, and /) allows polymorphic treatment of the various numerical types: integer, unsigned integer, float, decimal, etc.; each of which have different ranges, bit patterns, and representations. Another common example is the use of the "+" operator which allows similar or polymorphic treatment of numbers (addition), strings (concatenation), and lists (attachment). This is a lesser used feature of polymorphism.

The primary usage of polymorphism in industry (object-oriented programming theory) is the ability of objects belonging to different types to respond to method, field, or property calls of the same name, each one according to an appropriate type-specific behavior. The programmer (and the program) does not have to know the exact type of the object in advance, and so the exact behavior is determined at run-time (this is called late binding or dynamic binding).

The different objects involved only need to present a compatible interface to the clients' (calling routines). That is, there must be public or internal methods, fields, events, and properties with the same name and the same parameter sets in all the superclasses, subclasses and interfaces. In principle, the object types may be unrelated, but since they share a common interface, they are often implemented as subclasses of the same superclass. Though it is not required, it is understood that the different methods will also produce similar results (for example, returning values of the same type).

(Subtype) polymorphism is not the same as method overloading or method overriding [1], (that is known instead as ad-hoc polymorphism [2]). Polymorphism is only concerned with the application of specific implementations to an interface or a more generic base class. Method overloading refers to methods that have the same name but different signatures inside the same class. Method overriding is where a subclass replaces the implementation of one or more of its parent's methods. Neither method overloading nor method overriding are by themselves implementations of polymorphism.[3]

Contents

[edit] Examples

Java
// from file Animal.java
package org.wikipedia.examples;
 
public interface Animal {
        public String name();
        public String talk();
}
 
// from file Cat.java
package org.wikipedia.examples;
 
public class Cat implements Animal {
        private String name;
 
        public Cat(final String name) {
                this.name = name;
        }
 
        public String name() {
                return name;
        }
 
        public String talk() {
                return "Meow!";
        }
}
 
// from file Dog.java
package org.wikipedia.examples;
 
public class Dog implements Animal {
        private String name;
 
        public Dog(final String name) {
                this.name = name;
        }
 
        public String name() {
                return name;
        }
 
        public String talk() {
                return "Woof! Woof!";
        }
}
 
// from file PolymorphismExample.java
package org.wikipedia.examples;
 
import java.util.*;
 
public class PolymorphismExample {
 
        public static void main(String[] args) {
                Collection<Animal> animals = new ArrayList<Animal>();
                animals.add(new Cat("Missy"));
                animals.add(new Dog("Lassie"));
 
                for (Animal a : animals) {
                        System.out.println(a.name() + " says: " + a.talk());
                }
        }
 
}
 
// When you run this, the output is:
// Missy says: Meow!
// Lassie says: Woof! Woof!


Python
class Animal:
    def __init__(self, name):    # Constructor of the class
        self.name = name
    def talk(self):              # Abstract method, defined by convention only
        raise NotImplementedError("Subclass must implement abstract method")
 
class Cat(Animal):
    def talk(self):
        return 'Meow!'
 
class Dog(Animal):
    def talk(self):
        return 'Woof! Woof!'
 
animals = [Cat('Missy'),
           Cat('Mr. Mistoffelees'),
           Dog('Lassie')]
 
for animal in animals:
    print animal.name + ': ' + animal.talk()
 
# prints the following:
#
# Missy: Meow!
# Mr. Mistoffelees: Meow!
# Lassie: Woof! Woof!

[edit] Parametric Polymorphism

In computer science, the term polymorphism has several different but related meanings; one of these, known as parametric polymorphism in type system theory and functional programming languages, is known as generic programming in the Object Oriented Programming Community and is supported by many languages including C++, C# and Java.

Generics allow compile-time type-safety and other benefits and/or disadvantages depending on the language's implementation.

C++ implements parametric polymorphism through templates. The use of templates requires the compiler to generate a separate instance of the templated class or function for every permutation of type parameters used with it, which can lead to code bloat and difficulty debugging. A benefit C++ templates have over Java and C# is that they allow for template metaprogramming, which is a way of pre-evaluating some of the code at compile-time rather than run-time. However, since C++ allows templates to be specialized so they behave differently when used with different types, parametricity is not enforced.

Java parametric polymorphism is called generics and implemented through type erasure. This design decision was made to ensure backwards compatibility and ensure that Java generics are interoperable with non-generic code.

C# parametric polymorphism is called generics and implemented by reification, making C# the only language of the three which supports parametric polymorphism as a first class member of the language. This design choice is leveraged to provide additional functionality, such as allowing reflection with preservation of generic types, as well as alleviating some of the limitations of erasure (such as being unable to create generic arrays). This also means that there is no performance hit from runtime casts and normally expensive boxing conversions. When primitive and value types are used as generic arguments, they get specialized implementations, allowing for efficient generic collections and methods.

[edit] See also

[edit] References

  1. ^ Sierra, Kathy; Bert Bates (2005). Head First Java, 2nd Ed.. O'Reilly Media, Inc.. ISBN 0596009208. 
  2. ^ "On Understanding Types, Data Abstraction, and Polymorphism"
  3. ^ Stroustrup, Bjarne (2000). The C++ Programming Language Special Edition. O'Reilly Media, Inc.. ISBN 0-201-70073-5. 

[edit] External links

Personal tools
Namespaces
Variants
Actions
Navigation
Interaction
Toolbox
Print/export
Languages