OOPS Concepts in C# with Real Examples

Object-oriented programming (OOP) principles are the foundation of modern software development, and C# is a language that fully embraces these concepts. OOP deploys a set of rules and best practices to create more modular applications that are easier to test and simpler to maintain. In C#, these principles help developers tackle complex problems by breaking them down into smaller, more manageable pieces using objects.

Object-Oriented Programming System (OOPS) in C# is a programming paradigm centered around objects rather than actions. Key concepts include Encapsulation, which protects data with methods; Inheritance, allowing new classes to adopt properties of existing ones; Polymorphism, enabling objects to be treated as their parent class; and Abstraction, simplifying complex reality by modeling classes appropriate to the problem. These principles together provide a structured approach to building robust and scalable software applications in C#.

Through concrete examples in C#, this article sheds light on how these OOP principles are applied in real-world scenarios. Understanding how to effectively use OOP principles in C# can lead to the creation of more efficient, scalable, and robust applications.

Principles of OOPs in C#

Object-oriented programming (OOP) in C# is founded on four main principles that enhance software design and maintainability.

Encapsulation: Encapsulation is about bundling data and methods that operate on the data within a single unit, called a class. It restricts direct access to some of an object’s components, which is a form of data protection. In C#, this is achieved through access modifiers such as public, private, and protected.

Example: A class BankAccount may have private fields for accountNumber and balance, with public methods to Deposit() and Withdraw().

Abstraction: This principle involves hiding complex reality while exposing only the necessary parts. In C#, abstraction is implemented through interfaces and abstract classes.

Example: An interface IPlayable might define a method Play(). Various classes like VideoPlayer and MusicPlayer can implement IPlayable and provide their own Play() method implementation.

Inheritance: Inheritance allows a new class to take on properties and methods of an existing class. The new class is called a subclass or derived class. C# supports single inheritance, where a class can inherit from only one base class.

Example: A base class Vehicle may have a method Move(). A subclass Car inherits from Vehicle and can use the Move() method or override it with its own implementation.

Polymorphism: It allows for using a single action in different ways. Polymorphism in C# can be static, implemented with method overloading, or dynamic, using method overriding.

Example: A Shape class may have a method Draw(). Subclasses like Circle and Rectangle can override Draw() to implement shape-specific drawing logic.

Understanding Encapsulation in C# with Examples

Encapsulation is a fundamental concept in object-oriented programming, and C# utilizes this principle to protect the data and functions from outside interference and misuse. It involves bundling the data (variables) with the methods (functions) that operate on that data into a single unit, known as a class. Encapsulation hides the internal states of an object from the outside world, only allowing access through methods that are exposed publicly.

To provide an example, consider a BankAccount class:

public class BankAccount
{
    private double balance; // Private variable

    public BankAccount(double initialBalance) // Constructor
    {
        balance = initialBalance;
    }

    public void Deposit(double amount) // Public method
    {
        if (amount > 0)
        {
            balance += amount;
        }
    }

    public bool Withdraw(double amount) // Public method
    {
        if (amount > 0 && balance >= amount)
        {
            balance -= amount;
            return true;
        }
        return false;
    }

    public double GetBalance() // Public method
    {
        return balance;
    }
}

In the BankAccount Example:

  • The balance variable is private, meaning it cannot be accessed directly from outside the class.
  • Public methods Deposit, Withdraw, and GetBalance provide a controlled way to modify and access the balance.

Key points:

  • Private Members: The balance variable is accessible only within the BankAccount class.
  • Public Methods: Deposit, Withdraw, and GetBalance allow controlled interaction with the private data.
  • Data Protection: Encapsulation ensures that the balance cannot be modified arbitrarily, safeguarding against unauthorized access and changes.

In C#, encapsulation promotes maintainability, flexibility, and a modular approach to software design. It allows developers to change the internal implementation without affecting other parts of the code that rely on the class methods.

Implementing Inheritance in C# with Examples

Inheritance in C# allows a class to inherit properties, methods, and other members from another class. Known as the base class or superclass, it provides a reusable foundation that can be built upon by derived classes, also called subclasses.

Example of a Simple Inheritance Hierarchy:

class Vehicle         // Base class
{
    public string Make;
    public void Start() { /* Code to start a vehicle */ }
    public void Stop() { /* Code to stop a vehicle */ }
}

class Car : Vehicle  // Derived class
{
    public int NumberOfDoors;
}

In this example, Car inherits from Vehicle. This means that Car obtains the Make, Start(), and Stop() members from Vehicle. With inheritance, Car can use and potentially override these inherited members.

Creating Instances and Using Inherited Members:

To see inheritance in action, create an instance of Car and use its members:

Car myCar = new Car();
myCar.Make = "Toyota";  // Setting inherited property
myCar.NumberOfDoors = 4;
myCar.Start();          // Calling inherited method

Here, myCar has access to both the property Make and methods Start() and Stop() from the Vehicle class, alongside its property, NumberOfDoors.

Key Points of Inheritance in C#:

  • Inheritance supports reusability and extension of code.
  • A derived class inherits from a single base class (single inheritance).
  • Derived classes can further be used as base classes, forming a hierarchy.
  • The keyword : is used to inherit from a base class.
  • Access modifiers (public, protected, private) control accessibility of inherited members.

Polymorphism in C# with example

Polymorphism allows methods in C# to work with different data types while still providing a consistent interface. It’s a core concept in object-oriented programming that enables objects to be treated as instances of their parent class rather than their actual class.

Examples:

1. Method Overloading:

  • Compile-time Polymorphism
  • Multiple methods can have the same name with different parameters.
class Calculator {
    public int Add(int a, int b) {
        return a + b;
    }

    public double Add(double a, double b) {
        return a + b;
    }
}

In the example, Add is overloaded with different parameter types, which is decided at compile time.

2. Method Overriding:

  • Run-time Polymorphism
  • Overrides a base class method in a derived class
class Shape {
    public virtual string Draw() {
        return "Drawing a shape";
    }
}

class Circle : Shape {
    public override string Draw() {
        return "Drawing a circle";
    }
}

Here, Draw is overridden to provide specific behavior for a Circle.

3. Interfaces:

  • Define a contract that can be implemented by multiple classes.
interface IDrawable {
    string Draw();
}

class Rectangle : IDrawable {
    public string Draw() {
        return "Drawing a rectangle";
    }
}

Both Circle and Rectangle can implement the IDrawable interface, enabling polymorphism through a common interface.

Practical Use:

In real-world applications, polymorphism simplifies code management and enhances flexibility. It allows developers to use the same method in different contexts. For instance, a graphics program might use polymorphism to treat all shapes as Drawable objects, handling them in a uniform way during rendering. This demonstrates polymorphism’s power in abstraction, code reusability, and maintainability.

Abstraction in C# with Real Examples

Abstraction in C# is achieved through creating classes that serve as blueprints for more specific classes. The key is to define what is common for the objects we are modeling. To illustrate, let’s consider a payment processing system.

In an online store, various payment methods such as CreditCard, PayPal, and BankTransfer can be used. These payment methods share common functionality, which can be abstracted into a base class called Payment:

public abstract class Payment {
    public abstract void ProcessPayment(decimal amount);
}

In this abstract class, ProcessPayment is an abstract method, indicating that any subclass must provide a concrete implementation of this method.

Next, classes inheriting from Payment implement the ProcessPayment method specific to each payment method:

public class CreditCardPayment : Payment {
    public override void ProcessPayment(decimal amount) {
        // Implementation for credit card processing
    }
}

public class PayPalPayment : Payment {
    public override void ProcessPayment(decimal amount) {
        // Implementation for PayPal processing
    }
}

Consumers of these classes don’t need to know the specifics of processing each payment type; they interact with the Payment abstraction. This simplifies the usage:

public void ProcessUserPayment(Payment paymentMethod, decimal amount) {
    paymentMethod.ProcessPayment(amount);
}

By using abstraction, the system’s payment processing is designed to be extensible and maintainable. New payment methods can be integrated without altering the existing infrastructure, demonstrating the power and flexibility of abstraction in object-oriented programming.

Advanced OOPs Concepts in C#

Inheritance allows a class to inherit fields and methods from another class. For example, in a class hierarchy where a Shape class is extended by subclasses like Circle and Square, the subclasses inherit properties like area and perimeter.

public class Shape {
    public double Area() { ... }
}

public class Circle : Shape {
    public double Radius { get; set; }
}

Polymorphism permits methods to do different things based on the object’s class that implements them. It allows one interface to be used for a general class of actions. An example is an IDrawable interface with a Draw method. Both Circle and Square can implement IDrawable but have different drawing behaviors.

public interface IDrawable {
    void Draw();
}

public class Circle : Shape, IDrawable {
    public void Draw() { ... }
}

public class Square : Shape, IDrawable {
    public void Draw() { ... }
}

Encapsulation involves bundling data with methods that operate on that data. It restricts direct access to some of the object’s components, which is a way of data hiding. For example, using private fields and public getters/setters.

public class Account {
    private double balance;

    public double GetBalance() {
        return balance;
    }

    public void SetBalance(double value) {
        if (value >= 0) balance = value;
    }
}

Abstraction lets one focus on what an object does instead of how it does it. It involves creating simple, clear, and easy-to-use interfaces. An Abstract class or an Interface in C# can be used for this purpose.

Abstraction and encapsulation are closely related as abstraction hides complex reality while encapsulation hides the internal state.

Delegates and Events are advanced concepts in C#. A delegate is a type that represents references to methods with a particular parameter list and return type. Events enable a class or object to notify other classes or objects when something of interest occurs.

oops concepts in C#

Conclusion

Object-oriented programming (OOP) concepts in C# form the backbone of robust and scalable application development. These concepts, encapsulated by classes and instantiated through objects, provide a structured approach to coding. C# supports the four fundamental OOP pillars:

  • Encapsulation maintains code safety by restricting access to critical data.
  • Inheritance allows the creation of new classes that reuse, extend, and modify behaviors of existing classes.
  • Polymorphism enables objects to be treated as instances of their parent class rather than their actual class.
  • Abstraction simplifies complex reality by modeling classes appropriate to the problem.

The application of these concepts is demonstrated through numerous real-world scenarios, such as:

  • Managing a database connection through encapsulation,
  • Extending a basic user class into more specialized types using inheritance,
  • Implementing interface methods differently across multiple classes to demonstrate polymorphism,
  • Designing a simple UI control as an abstract class to serve various user interfaces.

You may also like: