C# Class and Object: Blueprint vs Product
Class and Object: The Lightbulb Moment
When learning OOP, the hardest part for me was the beginning. What is a Class, what is an Object, what's the difference? Everyone said "Class is a blueprint" but I couldn't quite understand what that meant.
Until one day while baking a cake in the kitchen, it clicked: Class is the cake mold, Object is the cakes that come out of that mold!
The Cake Mold Analogy
Think about it: You have a heart-shaped cake mold in your hand.
- Mold (Class): Defines how the cake will look. Shape, size are predetermined.
- Cakes (Objects): The concrete products that come out of that mold. Each one is a separate cake.
You can't eat the mold, but you can eat the cakes that come from it. You can make as many cakes as you want from the same mold, and each cake is independent.
// This is a Class - The cake mold
public class Cake
{
public string Flavor { get; set; }
public string Color { get; set; }
public int Slices { get; set; }
}
// These are Objects - Cakes from the mold
Cake chocolateCake = new Cake();
chocolateCake.Flavor = "Chocolate";
chocolateCake.Color = "Brown";
chocolateCake.Slices = 8;
Cake bananaCake = new Cake();
bananaCake.Flavor = "Banana";
bananaCake.Color = "Yellow";
bananaCake.Slices = 6;chocolateCake and bananaCake came from the same mold (Class) but are completely different products (Objects). Eating a slice from one doesn't affect the other.
What is a Class?
A class is a template that defines what something will be like. It contains:
- Properties: The characteristics of that thing. Color, size, name, etc.
- Methods: The actions that thing can perform. Start, stop, calculate, etc.
public class Car
{
// Properties - Car's characteristics
public string Brand { get; set; }
public string Model { get; set; }
public string Color { get; set; }
public int Speed { get; set; }
public bool IsEngineRunning { get; set; }
// Methods - Car's behaviors
public void StartEngine()
{
IsEngineRunning = true;
Console.WriteLine($"{Brand} {Model} engine started!");
}
public void StopEngine()
{
IsEngineRunning = false;
Speed = 0;
Console.WriteLine($"{Brand} {Model} engine stopped.");
}
public void Accelerate(int amount)
{
if (IsEngineRunning)
{
Speed += amount;
Console.WriteLine($"{Brand} accelerated! Current speed: {Speed} km/h");
}
else
{
Console.WriteLine("You must start the engine first!");
}
}
}This Car class doesn't do anything by itself. It just says "a car would be like this." To create real cars, we need to create instances.
What is an Object?
An object is a concrete instance created from a class. Each object occupies its own space in memory and holds its own values.
// Creating instances (Objects)
Car myCar = new Car();
myCar.Brand = "Toyota";
myCar.Model = "Corolla";
myCar.Color = "White";
Car dadsCar = new Car();
dadsCar.Brand = "Ford";
dadsCar.Model = "Focus";
dadsCar.Color = "Blue";
// Each car operates independently
myCar.StartEngine();
myCar.Accelerate(50);
dadsCar.StartEngine();
dadsCar.Accelerate(30);
// Output:
// Toyota Corolla engine started!
// Toyota accelerated! Current speed: 50 km/h
// Ford Focus engine started!
// Ford accelerated! Current speed: 30 km/hMy car accelerating doesn't affect dad's car. They both derived from the same "Car" class but are now independent objects.
Property vs Field: Small But Important Difference
In C#, there are two terms: Field and Property. They get confused at first, but the difference matters.
public class Student
{
// Field - Direct variable
public string name; // ❌ Not recommended
// Property - Controlled access with Get/Set
public string Name { get; set; } // ✅ Preferred
// Property with backing field - Full control
private int _age;
public int Age
{
get { return _age; }
set
{
if (value >= 0 && value <= 150)
_age = value;
else
Console.WriteLine("Invalid age!");
}
}
}The advantage of using Property: You can validate when a value is assigned or read. In the example above, ridiculous values like -5 or 200 cannot be assigned as age.
Methods: Objects' Abilities
A method is an action an object can perform. It can take parameters and return values.
public class Calculator
{
// Method with parameters
public int Add(int a, int b)
{
return a + b;
}
// Multiple parameters
public double Average(double x, double y, double z)
{
return (x + y + z) / 3;
}
// Method without parameters
public void Greet()
{
Console.WriteLine("Hello, calculator is ready!");
}
// void - Returns nothing
public void PrintResult(int result)
{
Console.WriteLine($"Result: {result}");
}
}
// Usage
Calculator calc = new Calculator();
calc.Greet();
int sum = calc.Add(5, 3);
calc.PrintResult(sum);
double avg = calc.Average(80, 90, 70);
Console.WriteLine($"Average: {avg}");Real-World Example: Library System
Let's combine everything we've learned. Let's design a simple library management system:
public class Book
{
public string Title { get; set; }
public string Author { get; set; }
public string ISBN { get; set; }
public int PageCount { get; set; }
public bool IsBorrowed { get; set; }
public void DisplayInfo()
{
Console.WriteLine($"📖 {Title}");
Console.WriteLine($" Author: {Author}");
Console.WriteLine($" ISBN: {ISBN}");
Console.WriteLine($" Pages: {PageCount}");
Console.WriteLine($" Status: {(IsBorrowed ? "Borrowed" : "Available")}");
}
}
public class Member
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string MemberID { get; set; }
public List<Book> BorrowedBooks { get; set; }
public Member()
{
BorrowedBooks = new List<Book>();
}
public bool BorrowBook(Book book)
{
if (!book.IsBorrowed)
{
book.IsBorrowed = true;
BorrowedBooks.Add(book);
Console.WriteLine($"✅ {FirstName} {LastName} borrowed '{book.Title}'.");
return true;
}
Console.WriteLine($"❌ '{book.Title}' is currently borrowed.");
return false;
}
public void ReturnBook(Book book)
{
if (BorrowedBooks.Contains(book))
{
book.IsBorrowed = false;
BorrowedBooks.Remove(book);
Console.WriteLine($"📚 '{book.Title}' has been returned.");
}
}
public void ShowBorrowedList()
{
Console.WriteLine($"\nBooks borrowed by {FirstName} {LastName}:");
if (BorrowedBooks.Count == 0)
{
Console.WriteLine(" No borrowed books.");
return;
}
foreach (var book in BorrowedBooks)
{
Console.WriteLine($" - {book.Title}");
}
}
}Now let's use these classes:
// Create books
Book book1 = new Book
{
Title = "Crime and Punishment",
Author = "Fyodor Dostoevsky",
ISBN = "978-123-456",
PageCount = 671
};
Book book2 = new Book
{
Title = "1984",
Author = "George Orwell",
ISBN = "978-789-012",
PageCount = 352
};
// Create members
Member john = new Member
{
FirstName = "John",
LastName = "Smith",
MemberID = "M001"
};
Member emma = new Member
{
FirstName = "Emma",
LastName = "Johnson",
MemberID = "M002"
};
// Operations
book1.DisplayInfo();
Console.WriteLine();
john.BorrowBook(book1); // John borrows
emma.BorrowBook(book1); // Emma can't - already borrowed
emma.BorrowBook(book2); // Emma borrows another book
john.ShowBorrowedList();
emma.ShowBorrowedList();
john.ReturnBook(book1); // John returns
emma.BorrowBook(book1); // Now Emma can borrow itObject Initializer Syntax
C# has a nice syntax for quickly assigning properties when creating objects:
// Long way
Book book1 = new Book();
book1.Title = "Crime and Punishment";
book1.Author = "Dostoevsky";
book1.PageCount = 671;
// Object Initializer - Short and clean
Book book2 = new Book
{
Title = "Crime and Punishment",
Author = "Dostoevsky",
PageCount = 671
};
// Can even write in one line (for small objects)
Book book3 = new Book { Title = "1984", Author = "Orwell" };The 'this' Keyword
this means "the current object." It's especially useful when parameter names are the same as property names:
public class Player
{
public string Name { get; set; }
public int Score { get; set; }
// Parameter name same as property name
public void SetInfo(string Name, int Score)
{
this.Name = Name; // this.Name = class property
this.Score = Score; // Name = parameter
}
// Method chaining with this (Fluent API)
public Player SetName(string name)
{
this.Name = name;
return this; // Return self
}
public Player SetScore(int score)
{
this.Score = score;
return this;
}
}
// Fluent API usage
Player player = new Player()
.SetName("Sarah")
.SetScore(100);Summary: Class vs Object
| Class | Object |
|---|---|
| Blueprint, template | Concrete instance |
| Doesn't occupy memory | Occupies memory |
| Definition | Usage |
| One | Unlimited |
| Cake mold | Cake |
Next Step: Constructor
We understood Class and Object concepts. But if you noticed, assigning properties one by one after creating an object can be tedious.
In the next post, we'll learn the Constructor concept. We'll explore this special method that runs automatically when an object is created and assigns initial values.
Until then, write lots of classes and create objects! Practice is the best teacher. 🚀
This is the second post of the OOP with C# series. In the previous post, we introduced OOP, and in the next post, we'll cover the Constructor topic.