Encapsulation in C#
Encapsulation is a concept in object-oriented programming that helps to hide the internal details of an object and only exposes what is necessary. Think of it like a capsule that contains medicine; you don’t see the medicine directly, but you can take it to feel better.
The meaning of Encapsulation is to make sure that “sensitive” data is hidden from users. To achieve this, you must:
– declare fields/variables as private
– provide public get and set methods, through properties, to access and update the value of a private field
– Properties
We have learned from the previous chapter that private variables can only be accessed within the same class (an outside class has no access to it). However, sometimes we need to access them – and it can be done with properties.
Here’s a simple example to help you understand encapsulation:
Example:
Imagine you are developing a banking application for a small local bank. The application needs to manage customers’ bank accounts, allowing them to deposit and withdraw money and let them know how much amount they have currently when they deposit or withdraw money.
using System;
class BankAccount
{
private decimal balance;
public decimal Balance
{
get { return balance; }
private set { balance = value; }
}
public BankAccount(decimal initialBalance)
{
if (initialBalance < 0)
Console.WriteLine (“Initial balance cannot be negative”);
balance = initialBalance;
}
public void Deposit(decimal amount)
{
if (amount <= 0)
Console.WriteLine (“Deposit amount must be positive”);
balance += amount;
Console.WriteLine($”Deposited: {amount:C}. New Balance: {balance:C}”);
}
public void Withdraw(decimal amount)
{
if (amount <= 0)
Console.WriteLine (“Withdrawal amount must be positive”);
if (amount > balance)
Console.WriteLine (“Insufficient funds”);
balance -= amount;
Console.WriteLine($”Withdrew: {amount:C}. New Balance: {balance:C}”);
}
}
class Program
{
public static void Main()
{
BankAccount account = new BankAccount(1000);
account.Deposit(500);
account.Withdraw(200);
Console.WriteLine($”Final Balance: {account.Balance:C}”);
Console.ReadLine();
}
}
Explanation:
using System;
class BankAccount
{
Private field for account balance & Public property for accessing the balance
private decimal balance;
public decimal Balance;
{
Getter method & Private setter method to restrict direct
get { return balance; }
private set { balance = value; }
Constructor to initialize the account with an initial balance
public BankAccount(decimal initialBalance)
{
if (initialBalance < 0)
Console.WriteLine (“Initial balance cannot be negative”);
balance = initialBalance;
}
Public method to deposit money
public void Deposit(decimal amount)
{
if (amount <= 0)
Console.WriteLine (“Deposit amount must be positive”);
balance += amount;
Console.WriteLine($”Deposited: {amount:C}. New Balance: {balance:C}”);
}
Public method to withdraw money
public void Withdraw(decimal amount)
{
if (amount <= 0)
Console.WriteLine (“Withdrawal amount must be positive”);
if (amount > balance)
Console.WriteLine(“Insufficient funds”);
balance -= amount;
Console.WriteLine($”Withdrew: {amount:C}. New Balance: {balance:C}”);
}
}
Program class with main method
class Program
{
public static void Main()
{
BankAccount account = new BankAccount(-1000); // Creating a new BankAccount object with an initial balance
account.Deposit(500); // Depositing money
account.Withdraw(200); // Withdrawing money
Console.WriteLine($”Final Balance: {account.Balance:C}”); // Outputting the final balance
Console.ReadLine();
}
}
Task:
1. Basic Encapsulation:
Write a class Person with private fields for FirstName and LastName. Provide public properties with getters and setters to access and modify these fields. Ensure the setters validate that the names are not empty.
2. Read-Only Property:
Create a class Product with private fields for name, price, and stockQuantity. Provide a public property Name that allows only read access (i.e., a getter but no setter). The Price and StockQuantity properties should have both getters and setters.
3. Encapsulation with Methods:
Write a class BankAccount with private fields for accountNumber, balance, and ownerName. Provide public methods to Deposit and Withdraw money. Ensure that the Withdraw method does not allow the balance to go negative.
4. Validation in Setters:
Create a class Student with private fields for studentId, name, and gpa. Implement public properties for these fields with validation logic in the setters (e.g., studentId should be positive, name should not be null or empty, and gpa should be between 0 and 4.0).
5. Private Methods:
Write a class LibraryBook with private fields for title, author, and isCheckedOut. Provide public methods to CheckOut and ReturnBook. Use private methods to update the status of the book.
6. Auto-Implemented Properties:
Create a class Car with auto-implemented properties for Make, Model, and Year. Ensure that the Year property cannot be set to a future year.
7. Encapsulating Collections:
Write a class Inventory that contains a private list of Item objects. Provide public methods to add and remove items, as well as to get a read-only list of items.
8. Encapsulation with Inheritance:
Create a base class Employee with private fields for name and salary. Provide public properties for these fields. Then create a derived class Manager that adds a private field for department. Provide a public property for department.
9. Constructor Initialization:
Write a class Order with private fields for orderId, customerName, and orderTotal. Provide a constructor to initialize these fields and properties to access them. Ensure the fields are initialized with valid values.
10. Computed Properties:
Create a class Rectangle with private fields for width and height. Provide public properties for these fields. Add a read-only property Area that computes and returns the area of the rectangle based on width and height.