Basics of OOP’s in C#

What is Object-Oriented Programming?

Object-Oriented Programming (OOPs) has revolutionized the world of software development. OOPs support modular, efficient, and scalable program architecture by organizing code into reusable objects. OOPs, have many applications, from desktop apps to online development. One of the primary benefits of OOPs is the ability to improve code reusability and maintainability. OOPs help developers design robust, adaptable, and easily expandable systems through encapsulation, inheritance, and polymorphism

Procedural programming is about writing methods that perform operations on the data, while object-oriented programming is about creating objects that contain both data and methods.

Usages of OOPs

  1. Modularity through Breakdown: By breaking complicated systems down into smaller, self-contained pieces, OOP excels at modularity, improving the reuse and maintainability of code.
  2. OOP facilitates DRY (“Don’t Repeat Yourself”) programming in C#, which makes the code simpler to maintain, modify, and debug.
  3. Effective Collaboration: The ability for numerous developers to work on specific components at the same time, thanks to modular architecture, increases productivity and accelerates development.
  4. Clearer Code Structure: Component-based approaches provide code that is understandable and easy to test.
  5. Data Encapsulation: OOP protects data and methods from outside intervention and fosters security by encapsulating them within objects

What is Class and Object?

Class is an example of a type of data structure. It contains Constants, and fields are examples of data members, and methods, properties, events, indexers, operators, instance constructors, finalizers, and static constructors are examples of function members.

  • A “class” is a template that specifies the variables and methods of a certain type of object.
  • The blueprint for a class is an object.
  • Ex: In real life, a smartwatch offers features like weight and color, as well as modes like calling options, health monitoring, and games.
  • Samsung Smart Watches and the iWatch are thus the objects of smartwatches.
public class SmartWatch
{
    public WatchColor Color { get; set; }
    public WatchShape Shape { get; set; }
    public decimal Weight { get; set; }

    public void Tracking()
    {
        Console.WriteLine("It has feature of Tracking");
    }

    public void Games()
    {
        Console.WriteLine("It has feature of Games");
    }
}

 

SmartWatch iWatch=new SmartWatch();
iWatch.Tracking();

Here, SmartWatch is a class, and iWatch is an object for the SmartWatch.

The four pillars of object-oriented programming (AEIP)

  • Abstraction
  • Encapsulation
  • Inheritance
  • Polymorphism

Abstraction  in C#

Abstraction is an important part of object-oriented programming. It means that only the required information is visible to the user, and the rest of the information is hidden.

Abstraction can be implemented using abstract classes in C#. Abstract classes are base classes with partial implementation. These classes contain abstract methods that are inherited by other classes that provide more functionality.

Some of the salient points about abstract classes are as follows.

  • The abstract class is created using the keyword abstract, and some of the methods of the abstract class also contain the keyword abstract.
  • No object can be created of the abstract class, i.e.it cannot be instantiated.
  • The abstract methods in the abstract class are implemented only in the derived classes.
  • If all the methods in the abstract class contain the keyword abstract, then that class is known as a pure Abstract class.
abstract class Shape
{
    public abstract double Area();
}
class Circle : Shape
{
    private readonly double radius;
    public Circle(double r)
    {
        radius = r;
    }
    public override double Area()
    {
        return (3.14 * radius * radius);
    }
}
class Square : Shape
{
    private readonly double side;
    public Square(double s)
    {
        side = s;
    }
    public override double Area()
    {
        return (side * side);
    }
}

static void Main(string[] args)
 { 
     Shape c = new Circle(5.0);
     Console.WriteLine("Area of Circle = {0}", c.Area());
     Shape s = new Square(2.5);
     Console.WriteLine("Area of Square = {0}", s.Area());
 
     Console.ReadKey();
 }

Output::
----------------------
Area of Circle = 78.5
Area of Square = 6.25

The abstract class shape contains the abstract method area(). The code snippet for this is given as follows:

abstract class Shape
{
  public abstract double Area();
}

The class Circle inherits from Shape. It has a private data member radius. The parameterized constructor assigns a value to the radius. The function area() calculates the area of the circle and returns that value. The code snippet for this is given as follows:

class Circle : Shape
{
  private readonly double radius;
  public Circle(double r)
  {
    radius = r;
  }
  public override double Area()
  {
    return (3.14 * radius * radius);
  }
}

The class Square inherits from Shape. It has a private data member side. The parameterized constructor assigns a value to the side. The function area() calculates the area of the square and returns that value. The code snippet for this is given as follows:

class Square : Shape
{
  private readonly double side;
  public Square(double s)
  {
    side = s;
  }
  public override double Area()
  {
    return (side * side);
  }
}

The function main() contains the objects c and s for classes Circle and Square, respectively. Then the areas of the circle and square are printed using the function area(). The code snippet for this is given as follows:

static void Main(string[] args)
{
  Shape c = new Circle(5.0);
  Console.WriteLine("Area of Circle = {0}", c.Area());
  Shape s = new Square(2.5);
  Console.WriteLine("Area of Square = {0}", s.Area());

  Console.ReadKey();
}

Encapsulation in C#

Encapsulation is the concept of wrapping data into a single unit. It collects data members and member functions into a single unit called class. The purpose of encapsulation is to prevent alteration of data from outside. This data can only be accessed by getter functions of the class.

Advantages of Encapsulation

  • Data Hiding: The user will have no idea about the inner implementation of the class. It will not be visible to the user that how the class is stored values in the variables. He only knows that we are passing the values to accessors, and variables are getting initialized to that value.
  • Increased Flexibility: We can make the variables of the class read-only or write-only, depending on our requirements. If we wish to make the variables read-only, then we have to only use Get Accessor in the code. If we wish to make the variables write-only, then we have to only use Set Accessor.
  • Reusability: Encapsulation also improves the re-usability and is easy to change with new requirements.
  • Testing code is easy: Encapsulated code is easy to test for unit testing.
internal class CSharpBank
{
    private decimal balance;
    private readonly decimal minBalace;

    public decimal Balance { get { return balance; } }

    public CSharpBank(decimal minBalace)
    {
        this.minBalace = minBalace;
    }

    public bool Deposit(decimal amount)
    {
        if (amount >= minBalace)
        {
            balance += amount;
            Console.WriteLine($"Your Balance: {balance}, after depoist of amount Rs.{amount}");
            return true;
        }
        else
            Console.WriteLine($"Your deposit must meet the minimum balance Rs. {minBalace}. ");

        return false;
    }

    public void Withdraw(decimal amount)
    {
        if (balance >= amount)
        {
            balance -= amount;
            Console.WriteLine($"Your Balance: {balance}, after withdraw of amount Rs.{amount}");
        }
        else
        {
            Console.WriteLine("Sorry, Insufficient funds...");
        }
    }

    public void PrintMyBalance()
    {
        Console.WriteLine($"Your Balance: {balance}");
    }
}
// Example of Encapsulation :: 

CSharpBank myAccount = new CSharpBank(minBalace: 1000);
var isDone = myAccount.Deposit(5000);
if (isDone)
{
    myAccount.Withdraw(1200);
    Console.WriteLine($"To Know your Balance call `myAccount.Balance` value is-> {myAccount.Balance}");
}

Inheritance in C#

Inheritance is the process of creating new classes based on an existing class. It allows the developer to create subclasses that will inherit the attributes and behaviors of the parent class. This makes it easy to reuse code, making development faster and more efficient.

Example

public enum WatchColor
{
    Black,
    White,
    Red,
    Blue,
    Yellow,
    YellowGreen,
    Green,
    Orange
}

public enum WatchShape
{ 
    Round,
    Square,
    RoundedSquare
}



public class SmartWatch
{
    public WatchColor Color { get; set; }
    public WatchShape Shape { get; set; }
    public decimal Weight { get; set; }

    public void Tracking()
    {
        Console.WriteLine("It has feature of Tracking");
    }

    public void Games()
    {
        Console.WriteLine("It has feature of Games");
    }
}


public class iWatch : SmartWatch
{ 
    public void MotionSensor()
    {
        Console.WriteLine("It has feature of Games");
    }
    public void Feature1()
    {
        Console.WriteLine("It has feature of Games");
    }
}

public class samsungWatch : SmartWatch
{ 
    public void Feature1()
    {
        Console.WriteLine("It has feature of Games");
    }
}

Polymorphism in C#

Polymorphism is a Greek word meaning “one name many forms.” “Poly” means many, and “morph” means forms. In other words, one object has many forms or has one name with multiple functionalities. Polymorphism allows a class to have multiple implementations with the same name.

Polymorphism

Dynamic or Run Time Polymorphism

Here, Find the area of calculation about shape will be over the rider for each shape.

abstract class Shape
{
    public abstract double Area();
}
class Circle : Shape
{
    private readonly double radius;
    public Circle(double r)
    {
        radius = r;
    }
    public override double Area()
    {
        return (3.14 * radius * radius);
    }
}
class Square : Shape
{
    private readonly double side;
    public Square(double s)
    {
        side = s;
    }
    public override double Area()
    {
        return (side * side);
    }
}
class Triangle : Shape
{
    private readonly double tbase;
    private readonly double theight;
    public Triangle(double b, double h)
    {
        tbase = b;
        theight = h;
    }
    public override double Area()
    {
        return (0.5 * tbase * theight);
    }
}

Static or compile-time polymorphism

The below example gives an explanation of static or compile-time polymorphism.

public class Maths
{
    public void Add(int x, int y, int z)
    {
        Console.WriteLine(x + y + z);
    }

    public void Add(int x, int y)
    {
        Console.WriteLine(x + y);
    }
}

Reference: Sample Code