Object Oriented Programming Pillars

We have already discussed OOP in our first lecture of this course.

Today we will talk about below 4 pillars of OOP
  1. Abstraction
  2. Encapsulation
  3. Inheritance
  4. Polymorphism
Abstraction

Abstraction is a concept aiming to hide relevant data about an object and expose a high-level mechanism for using it, which in turn increase efficiency and reduce complexity.

For example, In Test Automation we use IWebDriver object for communication with the browser, we can open the URL and close the browser using available methods. Here we are not aware of how the communication with the browser is actually done. 

In Simple terms, IWebDriver object hides all the internal details and gives us methods for using it 
Below sample code


IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl("https://www.google.com/");
driver.Close();

Its ok, if you do not understand the code for now. We will talk about IWebdDriver in coming lectures
Here GoToUrl and Close are mechanisms for using the IWebDriver object.

Well, tell me how did it increase efficiency or reduced complexity ?? 

Imagine for opening the browser and browsing the Url, there can be multiple things going under the hood. Selenium uses browser API's for accessing the browser, here we don't need to know what those API's are and how many calls are involved in that process.

IWebDriver has provided us with GoToUrl method which we can use for this purpose and we don't need to know the internals of IWebDriver, which in turn reduces complexity and increases efficiency

Encapsulation

Object-oriented programming produces cohesive pieces of code(classes) that solves given problem once and for all, so that programmers can use those classes without having to learn about the internal implementations

We bind data and functions together in class and keep both safes from outside interference and misuse is called encapsulation

Encapsulation can be achieved using data hiding

Data hiding

A technique to hide internal object details, it protects the data

"Abstraction and encapsulation are complementary concepts: abstraction focuses on the observable behaviour of an object... encapsulation focuses upon the implementation that gives rise to this behaviour... encapsulation is most often achieved through information hiding, which is the process of hiding all of the secrets of object that do not contribute to its essential characteristics." - Grady Booch in Object Oriented Analysis and Design

Inheritance

Here child class inherits the behaviour of a parent class.
A class whose members are inherited is called the base class and one that inherits the members of the base class is called the derived class.

C# support only single inheritance. That is, a class can only inherit from a single class.

class Class1
   {
       protected int value = 10;
   }
 
   class Class2 : Class1
   {
       public void PrintValue()
       {
           Console.Write(this.value);
       }
 
   }

Here Class1 is BaseClass and Class2 are inheriting from Class1 and called the derived class.

Class2 now can access the value member of Class1 as it is protected and is visible in Derived classes

Below are some access modifiers and their scope

  1. Public-Type or member can be accessed by code in same assembly or another assembly
  2. Private-Type or member can be accessed by code in the same class
  3. Protected-Type or member can be accessed by code in the same class or in the derived class
  4. Internal- Type or member can be accessed by code in same assemble but not from another assembly

Derived classes can also override inherited members by providing alternate implementation, only if they are marked with a virtual keyword, check below code

 class Class1
   {
       public virtual void Method1()
       {
           Console.WriteLine("Base Class: Method1");
       }
   }
   class Class2 : Class1
   {
       public override void Method1()
       {
           Console.WriteLine("Derived Class:Method1");
       }
   }
   class Program
   {
       static void Main(string[] args)
       {
           Class1 class1 = new Class1();
           class1.Method1();
 
           Class2 class2 = new Class2();
           class2.Method1();
 
           Class1 cl = new Class2();
           cl.Method1();
 
           Console.Read();
       }
   }

Output:-

Base Class: Method1
Derived Class:Method1
Derived Class:Method1

Inheritance is used to express "Is a" relationship between base class and one or more derived classes

Inheritance reduces code redundancy and provides code reusability. It also supports code extensibility by overriding the base class functionality with the child classes.

Polymorphism

Polymorphism means one name many forms.
For example, water exists as ice or steam. So they are polymorphic to water.

Two Types of Polymorphism
  1. Static or compile time polymorphism
  2. Dynamic or runtime polymorphism
In Static polymorphism, the decision to call which method is decided at compile time only
Compile time polymorphism can be achieved by method overloading 

Runtime polymorphism is achived by method overriding.
An object may be treated as a type of another object, provided the first object is derived from the second one. So the first object is polymorphic to the second object.
The base class will have virtual methods which can be overridden in a derived class.
At runtime, CLR checks the type of object and invokes that override of the virtual method.
Thus you can call a method on a base class and cause the derived class's version of the method to be executed.

Check below post for more details on Method overloading and overriding

A simple example would be a Shape class, it can have a virtual method to calculate the area.
Rectangle, Triangle can derive from Shape class ie they are polymorphic to Shape class.

public class Shape
   {
       public virtual void PrintArea()
       {
           Console.WriteLine("Shape Class PrintArea Method Called");
       }
   }
 
   public class Rectange : Shape
   {
       public override void PrintArea()
       {
           Console.WriteLine("Rectange Class PrintArea Method Called");
       }
   }
 
   public class Trinagle : Shape
   {
       public override void PrintArea()
       {
           Console.WriteLine("Triangle Class PrintArea Method Called");
       }
   }
   class Program
   {
       static void Main(string[] args)
       {
           //Rectangle polymorphic to Shape
           Shape rectangle = new Rectange();
           rectangle.PrintArea();
 
           //Triangle polymorphic to Shape
           Shape triangle = new Trinagle();
           triangle.PrintArea();
 
           Console.Read();
 
       }
   }


Output:-
Rectange Class PrintArea Method Called
Triangle Class PrintArea Method Called

You can see Shape can take any derived type(Rectangle or Triangle).

That's cool however show me how does it help me ??

You can work with a group of items in a uniform way, which in turn simplifies the coding.
If you have a requirement is where you need to calculate the area of several triangles, rectangles and other similar types.

One way to solve this is to create a Shape class as shown above and create a separate class for each shape(triangle, rectangle etc) and have their own PrintArea implementation.

Add all the shapes to an Array or List and iterate them and call the PrintArea method, that simplifies the coding, check below code.

public class Shape
    {
        public virtual void PrintArea()
        {
            Console.WriteLine("Shape Class PrintArea Method Called");
        }
    }
 
    public class Rectange : Shape
    {
        public override void PrintArea()
        {
            Console.WriteLine("Rectange Class PrintArea Method Called");
        }
    }
 
    public class Trinagle : Shape
    {
        public override void PrintArea()
        {
            Console.WriteLine("Triangle Class PrintArea Method Called");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            List<Shape> ShapeList = new List<Shape>();
            ShapeList.Add(new Shape());
            ShapeList.Add(new Rectange());
            ShapeList.Add(new Trinagle());
 
            foreach (var shape in ShapeList)
            {
                shape.PrintArea();
            }
            Console.Read();
        }
    }


Output:-

Shape Class PrintArea Method Called
Rectange Class PrintArea Method Called
Triangle Class PrintArea Method Called






Comments

Popular posts from this blog

Specflow -Part3(Working with tables using Specflow.Assist.Dynamic)

Specflow -Part4(Specflow Scenario Outline and Feature Background )

Specflow -Part6(Specflow Hooks)