# OOP

* Following are the four pillars of OOP principle,
  * Encapsulation
  * Abstraction
  * Polymorphism
  * Inheritance

## Encapsulation

* Encapsulation is a language construct that facilitates the bundling of data with the methods operating on that data.
*   Encapsulation doesn't guarantee data protection, cohesive design or information hiding.

    #### Information Hiding

    * Information hiding is a design principle that strives to shield client classes from the internal workings of a class.
    * Encapsulation facilitates, but does not guarantee, information hiding.
    * Read more about [relation between information hiding and encapsulation](https://www.infoworld.com/article/2075271/encapsulation-is-not-information-hiding.html).

## Abstraction

* Abstraction is preserving information that is relevant in a given context, and forgetting information that is irrelevant in that context.

## Polymorphism

*   The provision of a single interface to entities of different types or the use of a single symbol to represent multiple different types is known as polymorphism.

    #### Types of polymorphism

    * Major classes of polymorphism
      * `Ad hoc polymorphism`
        * Polymorphic functions that can be applied to arguments of different types, but that behave differently depending on the type of the argument to which they are applied.
      * `Parametric polymorphism`
        * 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.
      * `Subtype polymorphism`
        * 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)_.
        * This type relation is sometimes written `S <: T`. Conversely, T is said to be a supertype of S—written `T :> S`. Subtype polymorphism is _usually_ resolved dynamically.
      * `Coercion polymorphism`
        * Implicit type conversion by compiler aka _type juggling_ is also a type of polymorphism.
    * Polymorphism can be distinguished by when the implementation is selected.
      * Static polymorphism typically occurs in ad hoc and parametric polymorphsim.
      * Dynamic poymorphism usually occurs in subtype polymorphism. But subtype polymorphism can be achieved through static polymorphism as well.

## Inheritance

* The mechanism of basing an object or class upon another object (prototype-based inheritance) or class (class-based inheritance), retaining similar implementation.
* Also defined as deriving new classes (sub classes) from existing ones such as super class or base class and then forming them into a hierarchy of classes.
* Inheritance only reuses implementation and establishes a syntactic relationship, not necessarily a semantic relationship _(inheritance does not ensure behavioral subtyping)_.
* The inheritance hierarchy of an object is fixed at instantiation when the object's type is selected and does not change with time.
* Types of inheritance
  * Single
  * Multiple
  * Multilevel
  * Hierarchical
  * Hybrid

## Subtyping

* Subtyping enables a given type to be substituted for another type or abstraction, and is said to establish an **is-a** relationship between the subtype and some existing abstraction, either implicitly or explicitly, depending on language support.
*   Subtyping refers to compatibility of interfaces.

    #### Important readings

    * [Implementation Inheritance v/s Interface Implementation](https://www.linkedin.com/pulse/why-prefer-interface-inheritance-implementation-adrain-pinto)
    * [Inheritance v/s subtyping](https://www.cmi.ac.in/~madhavan/courses/pl2006/lecturenotes/lecture-notes/node28.html)
    * [Implementation inheritance is evil](http://whats-in-a-game.com/implementation-inheritance-is-evil/)

##
