Encapsulation

Protecting Your Data Like a Bank Vault

Intermediate 20 min read Lesson 5 of 11

Keeping Your Data Safe

In previous lessons, we learned about classes, data, methods, and constructors. Now let's learn how to protect your data using Encapsulation!

Think of it like this:
  • Encapsulation = Keeping your data private and safe
  • Like a bank vault - you can only access it through proper channels
  • Like a car - you use the steering wheel, not the engine directly

Why is encapsulation important? It protects your data from being changed incorrectly. It makes your code safer, easier to maintain, and more professional.

Step 1: What is Encapsulation?

Encapsulation means hiding the internal details of a class and only showing what's necessary.

Without Encapsulation (BAD)
public class Person
{
    public int Age;  // Anyone can change this!
}

// ❌ Problem: Anyone can set bad data
Person p = new Person();
p.Age = -5;  // This is wrong but allowed!
Problem: Data is not protected. Anyone can put bad values!
With Encapsulation (GOOD)
public class Person
{
    private int age;  // ✅ Hidden!
    
    public int Age  // ✅ Controlled access
    {
        get { return age; }
        set 
        { 
            if (value > 0 && value < 120) 
                age = value; 
        }
    }
}
Solution: Data is protected! Only valid values are allowed.

Step 2: Access Modifiers - Who Can See What?

Access modifiers control who can see and use different parts of your class.

public

✅ Anyone can see it

public string Name;
Like your name - everyone knows it
private

✅ Only this class can see it

private string password;
Like your password - only you know it
protected

✅ Class and children can see it

protected string baseData;
Like family secrets - only family knows
Golden Rule: Make things private by default. Only make them public if you really need to!

Step 3: Private Fields - The Data Storage

Private fields store your data safely where nobody else can touch them.

Private Fields Example
public class Student
{
    // ✅ Private - only this class can see
    private string name;
    private int age;
    private double gpa;
    
    // ✅ Public - everyone can see
    public string StudentId;
}
Why Use Private Fields?
  • Protection - Nobody can change your data directly
  • Safety - Prevents bad data from getting in
  • Control - You decide how data is accessed
// ❌ Cannot access private fields
Student s = new Student();
// s.name = "John";  // ERROR! Private!

// ✅ Can access public fields
s.StudentId = "S123";  // Works!

Step 4: Public Properties - The Controlled Door

Public properties are like a door with a security guard - they control access to your private data.

Property with Validation
public class Product
{
    private decimal price;  // Hidden data
    
    // Public property with validation
    public decimal Price
    {
        get { return price; }
        set 
        { 
            if (value >= 0)  // ✅ Check!
                price = value; 
        }
    }
}
Using Properties
Product p = new Product();

// ✅ Property validates the data
p.Price = 25.50m;  // Works!
p.Price = -10.00m; // ❌ Ignored (price stays 25.50)

Console.WriteLine(p.Price);  // 25.50
Benefits:
  • Validation - Check data before saving
  • Protection - Keep data safe
  • Flexibility - Change how data works later

Step 5: Different Access Levels

You can control who can read and who can write each property.

Read-Only

Everyone can read, only the class can change

public class BankAccount
{
    private decimal balance;
    
    // ✅ Everyone can read the balance
    public decimal Balance
    {
        get { return balance; }
        private set { balance = value; }  // Only class can change
    }
}
Init-Only (C# 9+)

Set only when created, never change again

public class Person
{
    // ✅ Can be set when created
    public int Id { get; init; }
    public string Name { get; set; }
}

// Usage
Person p = new Person { Id = 1, Name = "John" };
// p.Id = 2;  // ❌ ERROR! Cannot change after creation

Step 6: Private Methods - Internal Helpers

Private methods are helper methods that only your class can use.

Private Method Example
public class Calculator
{
    // ✅ Public - everyone can use
    public int Add(int a, int b)
    {
        return InternalAdd(a, b);  // Calls private method
    }
    
    // ✅ Private - only this class can use
    private int InternalAdd(int a, int b)
    {
        return a + b + 1;  // Internal logic
    }
}
Why Private Methods?
  • Hide complexity - Keep internal logic hidden
  • Organize code - Break big tasks into small parts
  • Reuse - Use the same helper in multiple places
Example: A CalculateDiscount() method that only the class needs to use.

Real-World Example: Employee Management

Let's build a complete Employee class with encapsulation:

Employee.cs
using System;

public class Employee
{
    // ✅ Private fields - hidden data
    private string name;
    private decimal salary;
    private int yearsOfService;
    
    // ✅ Public properties - controlled access
    public string Name
    {
        get { return name; }
        set 
        { 
            if (!string.IsNullOrWhiteSpace(value))
                name = value; 
        }
    }
    
    public decimal Salary
    {
        get { return salary; }
        private set  // ✅ Only class can change salary
        { 
            if (value >= 0) salary = value; 
        }
    }
    
    public int YearsOfService
    {
        get { return yearsOfService; }
        private set { yearsOfService = value; }
    }
    
    // ✅ Read-only property
    public string EmployeeLevel
    {
        get 
        {
            if (yearsOfService < 2) return "Junior";
            if (yearsOfService < 5) return "Mid";
            return "Senior";
        }
    }
    
    // Constructor
    public Employee(string name, decimal salary, int years)
    {
        Name = name;
        Salary = salary;
        YearsOfService = years;
    }
    
    // ✅ Public methods - what the employee can do
    public void GiveRaise(decimal percentage)
    {
        if (percentage > 0)
            Salary += Salary * (percentage / 100);
    }
    
    public void DisplayInfo()
    {
        Console.WriteLine($"Name: {Name}");
        Console.WriteLine($"Salary: ${Salary}");
        Console.WriteLine($"Level: {EmployeeLevel}");
    }
}
Program.cs
using System;

class Program
{
    static void Main()
    {
        // Create employee
        Employee emp = new Employee("John Doe", 50000.00m, 3);
        
        // ✅ Can read public data
        Console.WriteLine($"Name: {emp.Name}");
        Console.WriteLine($"Level: {emp.EmployeeLevel}");
        
        // ✅ Can change through public methods
        emp.GiveRaise(10);  // 10% raise
        
        emp.DisplayInfo();
        
        // ❌ Cannot access private data directly
        // emp.salary = 60000;  // ERROR! Private
        // emp.yearsOfService = 5;  // ERROR! Private
    }
}
What encapsulation does:
  • Private fields - Data is hidden and safe
  • Public properties - Controlled access with validation
  • Private setters - Only the class can change certain data
  • Read-only properties - Calculate values when needed
  • Public methods - Safe ways to change data

What You Learned Today

Encapsulation

Protecting your data

Private

Hidden data & methods

Public

Controlled access

Validation

Keep data correct

Exercise: Create a Course Class

Your Task:

Create a Course class with proper encapsulation:

Requirements:
  1. Private fields:
    • courseName (string)
    • maxStudents (int)
    • currentStudents (int)
  2. Public properties:
    • CourseName - cannot be empty
    • MaxStudents - must be 1-50
    • CurrentStudents - read-only
    • SeatsAvailable - read-only (calculated)
More Requirements:
  1. Public methods:
    • AddStudent() - increases currentStudents
    • RemoveStudent() - decreases currentStudents
    • DisplayInfo() - shows course details
  2. Validation:
    • Can't add more than MaxStudents
    • Can't remove if no students
💡 Use the Employee class as reference!
Test Your Knowledge - Take Quiz