C# Encapsulation

Introduction

Encapsulation is one of the four fundamental principles of object-oriented programming (OOP). It refers to the bundling of data (fields or properties) and methods (functions) that operate on the data into a single unit, typically a class. Encapsulation restricts direct access to some of an object’s components, which can help prevent the accidental modification of data.

Encapsulation is achieved by using access modifiers to define the accessibility of class members. It promotes modularity and code reuse, and it helps to protect the integrity of the data.

How Encapsulation Works

Encapsulation in C# is implemented using:

  1. Access Modifiers: public, private, protected, internal, protected internal, and private protected.
  2. Properties: To provide controlled access to private fields.
  3. Methods: To operate on the data encapsulated within the object.

Example of Encapsulation

Let’s consider a simple example where we encapsulate the details of a Person class.

using System;

namespace EncapsulationExample
{
    public class Person
    {
        // Private fields
        private string name;
        private int age;

        // Public properties to access and modify private fields
        public string Name
        {
            get { return name; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    name = value;
                }
                else
                {
                    throw new ArgumentException("Name cannot be null or empty");
                }
            }
        }

        public int Age
        {
            get { return age; }
            set
            {
                if (value > 0)
                {
                    age = value;
                }
                else
                {
                    throw new ArgumentException("Age must be greater than zero");
                }
            }
        }

        // Constructor
        public Person(string name, int age)
        {
            Name = name;
            Age = age;
        }

        // Method to display person details
        public void DisplayInfo()
        {
            Console.WriteLine($"Name: {Name}, Age: {Age}");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Creating an object of the Person class
            Person person = new Person("Alice", 30);

            // Accessing properties
            Console.WriteLine("Person Name: " + person.Name);
            Console.WriteLine("Person Age: " + person.Age);

            // Modifying properties
            person.Age = 35;
            Console.WriteLine("Updated Person Age: " + person.Age);

            // Display person details using method
            person.DisplayInfo();
        }
    }
}

Output

Person Name: Alice
Person Age: 30
Updated Person Age: 35
Name: Alice, Age: 35

Explanation

  1. Private Fields: The name and age fields are declared as private, which means they cannot be accessed directly from outside the class.
  2. Public Properties: The Name and Age properties provide controlled access to the private fields. They include validation logic to ensure the integrity of the data.
  3. Constructor: The constructor initializes the private fields through the properties, ensuring that any validation logic is applied.
  4. Methods: The DisplayInfo method provides a way to output the encapsulated data.

Benefits of Encapsulation

  1. Data Protection: By restricting direct access to fields, encapsulation helps protect the integrity of the data.
  2. Modularity: Encapsulation promotes modularity by keeping related data and methods together in one class.
  3. Code Maintenance: Encapsulated code is easier to maintain and modify because changes to the internal implementation do not affect external code.
  4. Code Reusability: Encapsulation allows classes to be reused without exposing their internal implementation details.

Real-World Example

Consider a banking application where you need to encapsulate the details of a bank account.

using System;

namespace BankingExample
{
    public class BankAccount
    {
        // Private fields
        private string accountNumber;
        private double balance;

        // Public properties to access and modify private fields
        public string AccountNumber
        {
            get { return accountNumber; }
        }

        public double Balance
        {
            get { return balance; }
            private set { balance = value; }
        }

        // Constructor
        public BankAccount(string accountNumber, double initialBalance)
        {
            this.accountNumber = accountNumber;
            Balance = initialBalance;
        }

        // Method to deposit money
        public void Deposit(double amount)
        {
            if (amount > 0)
            {
                Balance += amount;
            }
            else
            {
                throw new ArgumentException("Deposit amount must be positive");
            }
        }

        // Method to withdraw money
        public void Withdraw(double amount)
        {
            if (amount > 0 && amount <= Balance)
            {
                Balance -= amount;
            }
            else
            {
                throw new ArgumentException("Invalid withdrawal amount");
            }
        }

        // Method to display account details
        public void DisplayAccountInfo()
        {
            Console.WriteLine($"Account Number: {AccountNumber}, Balance: {Balance}");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // Creating an object of the BankAccount class
            BankAccount account = new BankAccount("1234567890", 1000);

            // Displaying account information
            account.DisplayAccountInfo();

            // Depositing money
            account.Deposit(500);
            Console.WriteLine("After depositing 500:");
            account.DisplayAccountInfo();

            // Withdrawing money
            account.Withdraw(300);
            Console.WriteLine("After withdrawing 300:");
            account.DisplayAccountInfo();
        }
    }
}

Output

Account Number: 1234567890, Balance: 1000
After depositing 500:
Account Number: 1234567890, Balance: 1500
After withdrawing 300:
Account Number: 1234567890, Balance: 1200

Explanation

  1. Private Fields: The accountNumber and balance fields are private to prevent direct access from outside the class.
  2. Public Properties: The AccountNumber property provides read-only access to the accountNumber field, and the Balance property provides read-only access to the balance field (with the setter being private).
  3. Methods: The Deposit and Withdraw methods provide controlled ways to modify the balance field, ensuring that the operations are valid.

Conclusion

Encapsulation is a key principle in OOP that helps protect the internal state of an object and ensures that it is modified only in a controlled manner. By using access modifiers, properties, and methods, you can achieve encapsulation in C# and build robust, maintainable, and reusable code.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top