Object-Oriented Programming
Lesson 7 โข Intermediate Track
What You'll Learn
- Understand what OOP is and why C# is built around it
- Create classes (blueprints) and objects (instances) with fields and methods
- Write constructors to initialise objects with meaningful data
- Apply encapsulation to protect data with private fields and public methods
- Use properties (get/set) including auto-properties, validation, and computed properties
- Distinguish between static and instance members and know when to use each
๐ก Real-World Analogy
A class is like an architectural blueprint for a house. It defines what rooms exist, where doors go, and how plumbing works โ but it's not a house you can live in. An object is an actual house built from that blueprint. You can build hundreds of houses from one blueprint, each with different paint colours (field values), but they all share the same structure (methods and properties). Encapsulation is like the walls โ you can use the light switches (public methods) but you can't touch the electrical wiring directly (private fields).
Understanding OOP in C#
Object-Oriented Programming (OOP) is a programming paradigm that organises code around objects โ units that bundle data (what something is) and behaviour (what something does). Instead of writing long procedural scripts, you model your program as interacting objects, just like the real world.
C# is fundamentally an OOP language โ everything lives inside a class. The four pillars of OOP are:
- ๐ Encapsulation โ Hide internal data, expose controlled access (this lesson)
- ๐งฌ Inheritance โ Create specialised classes from general ones (next lesson)
- ๐ญ Polymorphism โ Same method name, different behaviour depending on the object
- ๐จ Abstraction โ Define "what" without specifying "how" (interfaces & abstract classes)
In this lesson, you'll master the first pillar โ encapsulation โ along with classes, objects, constructors, properties, and static members. These are the building blocks you'll use in every C# project from now on.
๐ Access Modifiers Quick Reference
| Modifier | Access Level | Use When |
|---|---|---|
| public | Accessible from anywhere | Methods and properties that other code needs to call |
| private | Only inside the same class | Internal data and helper methods (default for fields) |
| protected | Same class + derived classes | Data that subclasses need but external code shouldn't touch |
| internal | Same assembly (project) | Classes/methods shared within a project but hidden from external consumers |
1. Classes and Objects
A class defines the blueprint โ what fields (data) and methods (behaviour) an object will have. An object is a specific instance created from that blueprint with its own unique data. You create objects with the new keyword.
Classes & Objects
Create a Car class with fields, constructor, and methods.
using System;
// A class is a blueprint
class Car
{
// Fields (data the object holds)
public string Brand;
public string Model;
public int Year;
// Constructor โ runs when you create an object
public Car(string brand, string model, int year)
{
Brand = brand;
Model = model;
Year = year;
}
// Method โ something the object can do
public void StartEngine()
{
Console.WriteLine($"{Brand} {Model} ({Year}) โ engine started! ๏ฟฝ
...2. Encapsulation โ Protecting Data
Encapsulation means making fields private and providing public methods to interact with them. This prevents invalid data (like a negative bank balance) and lets you change the internal implementation without breaking code that uses the class.
Encapsulation
Build a BankAccount with private balance and public methods.
using System;
class BankAccount
{
// Private field โ cannot be accessed from outside
private double balance;
public string Owner { get; }
public BankAccount(string owner, double initialBalance)
{
Owner = owner;
balance = initialBalance;
}
// Public methods control how the private data is modified
public void Deposit(double amount)
{
if (amount <= 0)
{
Console.WriteLine("โ Deposit must be positive.");
r
...3. Properties โ The C# Way
Properties are C#'s elegant alternative to Java-style getters and setters. Auto-properties (public string Name { get; set; }) handle simple cases. For validation, use a full property with a backing field. Computed properties use => to calculate values on the fly.
Properties (get/set)
Auto-properties, validation setters, and computed properties.
using System;
class Student
{
// Auto-implemented property (most common)
public string Name { get; set; }
// Property with validation in the setter
private int age;
public int Age
{
get => age;
set
{
if (value < 0 || value > 150)
throw new ArgumentException("Age must be 0โ150");
age = value;
}
}
// Read-only property (set only in constructor)
public string StudentId { get; }
// Com
...4. Static vs Instance Members
Instance members belong to each object (every car has its own brand). Static members belong to the class itself and are shared across all objects (like counting how many cars exist). You access static members on the class name: Counter.GetTotalCount().
Static vs Instance
Compare static (shared) and instance (per-object) members.
using System;
class Counter
{
// Static field โ shared by ALL instances
private static int totalCount = 0;
// Instance field โ unique per object
public string Label { get; }
public Counter(string label)
{
Label = label;
totalCount++; // Incremented every time an object is created
}
// Static method โ called on the CLASS, not on objects
public static int GetTotalCount() => totalCount;
// Instance method
public void Display()
{
...Pro Tips
- ๐ก Default to private fields, public properties: This is the standard C# convention. Never expose fields as public unless there's a strong reason.
- ๐ก Use auto-properties for simple data:
public string Name { get; set; }is cleaner than writing a full backing field when no validation is needed. - ๐ก Prefer init-only setters for immutable data: In C# 9+,
public string Id { get; init; }allows setting only during construction. - ๐ก Use records for data-carrier classes:
record Person(string Name, int Age);auto-generates equality, ToString, and deconstruction.
Common Mistakes
- Making everything public โ This defeats encapsulation. If external code can modify
balancedirectly, your validation logic is useless. - Confusing class and object โ
Caris the class (blueprint).new Car("Toyota", "Camry", 2023)creates an object (instance). You can't callCar.StartEngine()unless it's static. - Forgetting constructors โ Without a constructor, fields get default values (0, null, false). Objects end up in invalid states. Always initialise with constructors.
- Using static when you mean instance โ Static members are shared. If each player has their own score, score should be an instance field, not static.
- Not using properties โ Exposing raw public fields (
public string name;) instead of properties means you can't add validation later without breaking all calling code. - Property naming conventions โ Properties use PascalCase (
FirstName), private fields use camelCase or underscore (_firstNameorfirstName).
๐ Lesson Complete
- โ
A class is a blueprint; an object is an instance created with
new - โ Constructors initialise objects with meaningful data when they're created
- โ Encapsulation = private fields + public methods/properties for controlled access
- โ Properties (get/set) are the C# way to expose data โ use auto-properties for simple cases
- โ Static members belong to the class; instance members belong to each object
- โ
Access modifiers:
public,private,protected,internal - โ Next lesson: Inheritance & Polymorphism โ extending classes and overriding behaviour
Sign up for free to track which lessons you've completed and get learning reminders.