Ad hoc polymorphism is a specific type of polymorphism that differs from general polymorphism in how it handles multiple implementations or behaviors based on input types. Here's a breakdown of the key distinctions:
- Ad hoc Polymorphism:
- Definition: Ad hoc polymorphism refers to the ability of a function to operate on different types through function overloading or operator overloading. The behavior of the function or operator changes based on the specific types of its arguments, but the implementation is chosen at compile-time based on the provided argument types.
- Key Mechanism: It is implemented through method overloading or operator overloading.
- Examples:
- Nature: It is not true polymorphism in the sense that the behavior is defined for specific types (hence the term "ad hoc"), rather than being a general property across all types.
- General Polymorphism (Subtype Polymorphism):
- Definition: General polymorphism refers to the ability of a function to work with different types of objects through a common interface, typically achieved through inheritance or interfaces in object-oriented programming. The specific implementation is determined at runtime, based on the actual type of the object.
- Key Mechanism: It is implemented through inheritance and method overriding.
- Examples:
Here, `makeSound()` is polymorphic because the method invoked depends on the actual object type at runtime (`Dog`).
Nature: General polymorphism allows the same function or method to work with multiple types through dynamic dispatch, providing flexibility in design.
Key Differences:
- Ad hoc polymorphism involves *compile-time* selection of function implementations based on the types of arguments (via function or operator overloading).
- General polymorphism (or subtype polymorphism) involves *runtime* selection of method implementations based on the actual object type (via inheritance and dynamic dispatch).
In summary, ad hoc polymorphism is more rigid, working with specific types, whereas general polymorphism (or subtype polymorphism) allows for more flexible and dynamic behavior across a range of types.
In object-oriented programming, polymorphism refers to a programming language's ability to process objects differently depending on their data type or class. Furthermore, it is the ability to redefine methods for derived classes. Example: Given a base class shape, polymorphism enables the programmer to define different area methods for any number of derived classes, such as circles, rectangles and triangles. No matter what shape an object is, applying the area method to it will return the correct results. Polymorphism is considered to be a requirement of any true object-oriented programming language (OOPL).
Polymorphism is supported by C++ both at compile time and at run time. As discussed in earlier modules,
compile-time polymorphism is achieved by overloading functions and operators.
Run-time polymorphism is accomplished by using inheritance and virtual functions, and these are the topics of this module.
A virtual function is a member function that is declared within a base class and redefined by a derived class. To create a virtual function, precede the function's declaration in the base class with the keyword virtual. When a class containing a virtual function is inherited, the derived class redefines the virtual function to fit its own needs. In essence, virtual functions implement the one interface, multiple methods philosophy that underlies polymorphism. The virtual function within the base class defines the form of the interface to that function. Each redefinition of the virtual function by a derived class implements its operation as it relates specifically to the derived class. That is, the redefinition creates a specific method. When accessed "normally," virtual functions behave just like any other type of class member function. However, what makes virtual functions important and capable of supporting run-time polymorphism is how they behave when accessed via a pointer. A base-class pointer can be used to point to an object of any class derived from that base. When a base pointer points to a derived object that contains a virtual function, C++ determines which version of that function to call based upon the type of object pointed to by the pointer. And this determination is made at run time. Thus, when different objects are pointed to, different versions of the virtual function are executed. The same effect applies to base-class references.