# Object-Oriented Programming/Polymorphism

This lesson introduces polymorphism.

## Objectives and Skills

Objectives and skills for this lesson include:
* Understand polymorphism
** Extending the functionality in a class after inheriting from a base class, overriding methods in the derived class
* Understand encapsulation
** Creating classes that hide their implementation details while still allowing access to the required functionality through the interface, access modifiers

## Readings
#### General

* Medium: Polymorphism explained simply!
* Wikipedia: Polymorphism (computer science)
* OnlineTutorialsPoint: Types of Polymorphism and Advantages

#### Java

* TutorialsPoint: Java - Polymorphism

#### Python

* Python: Polymorphism in Python

## Multimedia
#### General

* YouTube: Polymorphism
* YouTube: 4.7 Introduction to Polymorphism - The Nature of Code

#### Java

* YouTube: Polymorphism in Java

#### Python

* YouTube: Polymorphism - Object Oriented Python

## Examples

* Square (Polygon)
* + area: float {read only}
* + Square(side: float)
* Rectangle (Polygon)
* + area: float {read only}
* + Rectangle(length: float, width: float)
* Triangle (Polygon)
* + area: float {read only}
* + Triangle(side1: float, side2: float, side3: float)
* Polygon
* + perimeter: float {read only}
* + Polygon(sides: [float]) - validate_side(side: float)
* C#
* Java
* JavaScript
* Python3

## Activities

* Enhance the inheritance program from the previous lesson to demonstrate polymorphism. Update the UML class diagrams if necessary. Add a main program that uses each class and demonstrates that each subclass is an instance of more than one class.
* Show property and method results when the subclass is referenced as the base class and when it is referenced as a subclass.
* Update program, class, and method documentation consistent with the documentation standards for your selected programming language.
* Include updated unit tests to your submission.

## Lesson Summary

* Polymorphism is the ability of an object to take on many forms. When an object is assigned to a class reference and when a method of the object is called, the method in the object’s class is executed. Not the method of the reference class (if the reference is a parent class).
* The most commonly recognized major classes of polymorphism are ad-hoc polymorphism, parametric polymorphism, and subtyping.
* Parametric polymorphism allows a function or a data type to be written generically so that it can handle values uniformly without depending on their type. Parametric polymorphism is a way to make a language more expressive while still maintaining full static type-safety.
* Ad-hoc polymorphism refers to polymorphic functions that can be applied to arguments of different types but behave differently depending on the type of the argument to which they are applied (also known as function overloading or operator overloading).
* Function (method) overloading is the ability to create multiple functions of the same name with different implementations. The specific implementation that is called is based on the context of the call.
* Operator overloading, similar to function overloading, is where operators have different implementations depending on their arguments.
* Subtyping allows a function to be written to take an object of a certain type T, but also work correctly if passed an object that belongs to another type S that is a subtype of T.
* Polymorphism can be distinguished by when the implementation is selected: statically (at compile time) or dynamically (at runtime).
* Method overriding is a language feature of polymorphism that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its superclasses or parent classes. The implementation in the subclass overrides the implementation in the superclass by providing a method that has same name, same parameters or signature, and same return type as the method in the parent class.
* Static polymorphism executes faster, because there is no dynamic dispatch overhead, but requires additional compiler support. Dynamic polymorphism is more flexible but slower.

## Key Terms
### ad-hoc polymorphism

    Polymorphic functions that can be applied to arguments of different types but behave differently depending on the type of the argument to which they are applied.

### compile-time polymorphism

    The type of polymorphism that is implemented when the compiler compiles the program.

### parametric polymorphism

    When one or more types are not specified by name but by abstract symbols that can represent any type.

### polymorphism

    The provision of a single interface to entities of different types or the use of a single symbol to represent multiple different types.

### polytypism

    A more general function than a polymorphic function. Although one can provide fixed ad-hoc cases for specific data types, an ad-hoc combinator is absent.

### run-time polymorphism

    A type of polymorphism that is implemented dynamically when a program being executed.

### subtyping

    Allows a function to be written to take an object of a certain type T, but also work correctly if passed an object that belongs to a type S that is a subtype of T according to the Liskov substitution principle.

## See Also

* hws.edu: Inheritance, Polymorphism, and Abstract Classes