Object-Oriented Basics: Classes and Encapsulation
The Toy Factory Analogy
Imagine you own a toy factory. Each toy has:
- A blueprint (the class)
- The actual toy made from that blueprint (the object)
- Secret recipes only factory workers can see (encapsulation)
- Labels on the box telling customers what the toy does (properties)
Let’s build your factory together!
Classes and Objects
What is a Class?
A class is like a cookie cutter. It defines the shape, but it’s not the cookie itself.
class Dog
{
public string Name;
public int Age;
}
What is an Object?
An object is the actual cookie you cut out using the cutter!
Dog myDog = new Dog();
myDog.Name = "Buddy";
myDog.Age = 3;
Think of it this way:
- Class = Recipe for chocolate cake
- Object = The actual cake you bake and eat
You can make many cakes from one recipe. Same with classes and objects!
Constructors
The Birth Certificate of Objects
A constructor is a special method that runs when you create an object. It’s like the “Welcome to the world!” moment.
class Dog
{
public string Name;
// Constructor
public Dog(string name)
{
Name = name;
}
}
// Creating a dog with a name
Dog buddy = new Dog("Buddy");
Default Constructor
If you don’t write a constructor, C# gives you a free one that does nothing:
class Cat
{
public string Name;
}
Cat myCat = new Cat(); // Uses default constructor
Multiple Constructors
You can have many ways to create objects:
class Dog
{
public string Name;
public int Age;
public Dog()
{
Name = "Unknown";
Age = 0;
}
public Dog(string name, int age)
{
Name = name;
Age = age;
}
}
Object Initialization Order
The Assembly Line
When you create an object, things happen in a specific order. Think of it like assembling a toy:
graph TD A[1. Memory Allocated] --> B[2. Fields Set to Default] B --> C[3. Field Initializers Run] C --> D[4. Constructor Runs] D --> E[5. Object Ready!]
Example in Action
class Robot
{
public int Battery = 100; // Step 3: Field initializer
public string Name;
public Robot(string name) // Step 4: Constructor
{
Name = name;
}
}
When you write new Robot("Zappy"):
- Memory is set aside
- Fields get default values (0, null, etc.)
Battery = 100runs- Constructor sets
Name = "Zappy" - Your robot is ready!
Fields and Readonly
Fields: The Toy’s Parts
A field is a variable that lives inside a class. It stores data about the object.
class Car
{
public string Color; // Field
public int Speed; // Field
}
Readonly: The Permanent Parts
Sometimes you want a field that never changes after creation. Like a toy’s serial number!
class Car
{
public readonly string SerialNumber;
public Car(string serial)
{
SerialNumber = serial; // Set once
}
}
Car myCar = new Car("ABC123");
// myCar.SerialNumber = "XYZ"; // ERROR! Can't change!
Readonly fields can only be set:
- Where they’re declared
- In the constructor
Properties
The Smart Labels
Properties are like smart labels on your toy box. They control how you read or change values.
class BankAccount
{
private decimal balance;
public decimal Balance
{
get { return balance; }
set
{
if (value >= 0)
balance = value;
}
}
}
Auto-Properties: The Shortcut
When you don’t need special logic:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
This creates a hidden field automatically!
Read-Only Properties
class Circle
{
public double Radius { get; set; }
// Only get, no set
public double Area
{
get { return 3.14 * Radius * Radius; }
}
}
Access Modifiers
The Security Guards
Access modifiers control who can see and use your class members.
| Modifier | Who Can Access? |
|---|---|
public |
Everyone, anywhere |
private |
Only the same class |
protected |
Same class + child classes |
internal |
Same project only |
Real Example
class BankVault
{
public string BankName; // Anyone can see
private string SecretCode; // Only vault knows
protected decimal TotalMoney; // Vault + inheritors
internal string BranchId; // Same project only
}
The Golden Rule
Default is private! If you forget to write a modifier, it’s private.
class Mystery
{
string secret; // This is PRIVATE by default
}
Encapsulation
The Protective Box
Encapsulation means hiding the messy details and only showing what’s needed. Like a TV remote: you press buttons, but you don’t see the circuits inside!
Why Encapsulate?
- Protection: Stop accidental changes
- Simplicity: Users see only what they need
- Flexibility: Change internals without breaking users
Before Encapsulation (Dangerous!)
class Player
{
public int Health; // Anyone can set to -1000!
}
Player p = new Player();
p.Health = -1000; // OOPS! Invalid health!
After Encapsulation (Safe!)
class Player
{
private int health;
public int Health
{
get { return health; }
set
{
if (value < 0) health = 0;
else if (value > 100) health = 100;
else health = value;
}
}
}
Player p = new Player();
p.Health = -1000; // Sets to 0, not -1000!
Shallow vs Deep Copy
The Photocopier Problem
When you copy an object, do you get a true independent copy or just a reference to the same thing?
Shallow Copy: Sharing the Same Toy
class Toy
{
public string Name;
}
class Box
{
public Toy FavoriteToy;
}
Box box1 = new Box();
box1.FavoriteToy = new Toy { Name = "Teddy" };
// Shallow copy
Box box2 = box1;
box2.FavoriteToy.Name = "Robot";
// SURPRISE! box1.FavoriteToy.Name is also "Robot"!
Both boxes point to the same toy!
graph LR A[box1] --> C[FavoriteToy: Robot] B[box2] --> C
Deep Copy: Your Own Toy
With a deep copy, you get your own separate toy:
Box box1 = new Box();
box1.FavoriteToy = new Toy { Name = "Teddy" };
// Deep copy - create new toy
Box box2 = new Box();
box2.FavoriteToy = new Toy
{
Name = box1.FavoriteToy.Name
};
box2.FavoriteToy.Name = "Robot";
// box1.FavoriteToy.Name is still "Teddy"!
graph LR A[box1] --> C[FavoriteToy: Teddy] B[box2] --> D[FavoriteToy: Robot]
Quick Reference
| Type | What Happens | Independence |
|---|---|---|
| Shallow | Copies references | Objects are shared |
| Deep | Copies everything | Objects are independent |
Putting It All Together
Here’s a complete example using everything we learned:
class BankAccount
{
// Private field (encapsulation)
private decimal balance;
// Readonly field
public readonly string AccountNumber;
// Property with validation
public decimal Balance
{
get { return balance; }
private set
{
if (value >= 0)
balance = value;
}
}
// Constructor
public BankAccount(string accountNum)
{
AccountNumber = accountNum;
Balance = 0;
}
// Public method
public void Deposit(decimal amount)
{
if (amount > 0)
Balance += amount;
}
}
What we used:
- Class:
BankAccountis the blueprint - Constructor: Sets up the account
- Fields:
balancestores money - Readonly:
AccountNumbernever changes - Properties:
Balancewith validation - Encapsulation:
balanceis private - Access Modifiers: Public methods, private data
Key Takeaways
- Classes are blueprints, objects are the real things
- Constructors set up new objects
- Initialization follows a specific order
- Readonly fields lock after construction
- Properties are smart field wrappers
- Access modifiers control visibility
- Encapsulation protects your data
- Deep copy = independence, Shallow copy = sharing
You now have the power to build safe, organized, professional C# code!