C# Programming Fundamentals
Object-Oriented Programming Concepts
Classes and Objects
Object-Oriented Programming, or OOP, is a way of thinking about code that models the real world. Instead of just writing lists of instructions, we create digital objects that have properties and behaviors, just like things in real life.
The two most fundamental concepts in OOP are the class and the object. A class is a blueprint. It defines the properties and behaviors that a certain type of object will have. An object is an actual instance created from that blueprint. For example, you can have a blueprint for a car (class Car), but you need to actually build one (object) to drive it.
// This is the blueprint for a car.
// It doesn't represent a specific car, just what any car will have.
public class Car
{
// Properties (data)
public string Color;
public string Model;
// Method (behavior)
public void StartEngine()
{
Console.WriteLine("The " + Model + " engine starts!");
}
}
The Car class defines that any car we create will have a Color and a Model, and will be able to StartEngine(). Now, let's use this blueprint to create some actual car objects.
// Create a new object (instance) from the Car class
Car myCar = new Car();
// Set the properties for this specific car
myCar.Color = "Red";
myCar.Model = "Mustang";
// Call its method
myCar.StartEngine(); // Output: The Mustang engine starts!
// Create another, separate object
Car neighborsCar = new Car();
neighborsCar.Color = "Blue";
neighborsCar.Model = "Civic";
neighborsCar.StartEngine(); // Output: The Civic engine starts!
Each object, myCar and neighborsCar, is a unique instance of the Car class. They share the same structure but hold their own separate data.
Encapsulation
Encapsulation is the principle of bundling data and the methods that operate on that data together within a class. More importantly, it's about controlling access to that data.
You don't want other parts of your program to randomly change an object's internal state. Think of it like a car's dashboard. You can see the speed, but you can't just reach in and set the speedometer to 100 mph. You have to use the gas pedal, which changes the speed in a controlled way.
In C#, we achieve this using access modifiers like public and private.
public: The member can be accessed from any code.private: The member can only be accessed by code within the same class.
Let's update our Car class. A car's fuelLevel shouldn't be set directly; it should only decrease when the car drives. We'll make fuelLevel private and provide a public method to interact with it.
public class Car
{
// This property is private. It can only be changed from inside the Car class.
private double fuelLevel = 100.0; // Starts with a full tank
// This method is public, so other code can call it.
public void Drive()
{
if (fuelLevel > 0)
{
Console.WriteLine("Driving...");
fuelLevel -= 5.0; // Decrease fuel in a controlled way
}
else
{
Console.WriteLine("Out of fuel!");
}
}
// A public method to check the fuel level without being able to change it.
public void CheckFuel()
{
Console.WriteLine("Fuel level: " + fuelLevel);
}
}
Now, code outside the Car class cannot write myCar.fuelLevel = -50;. It can only call the Drive() method, which ensures the fuel level changes logically. This makes our code safer and easier to manage.
Inheritance
Inheritance allows you to create a new class that reuses, extends, and modifies the behavior defined in another class. It creates an "is-a" relationship.
The class being inherited from is called the base class (or parent class). The class that inherits is called the derived class (or child class).
Imagine we have a general Vehicle class. A Car is a Vehicle, and a Truck is a Vehicle. Both share common properties like Speed and methods like Move(), but they might have unique features as well.
// The base class
public class Vehicle
{
public int Speed { get; set; }
public void Move()
{
Console.WriteLine("The vehicle is moving.");
}
}
// The derived class
// The colon : indicates that Car inherits from Vehicle
public class Car : Vehicle
{
public int NumberOfDoors { get; set; }
}
// Another derived class
public class Truck : Vehicle
{
public double CargoCapacity { get; set; }
}
Because Car and Truck inherit from Vehicle, they automatically get the Speed property and the Move() method without us having to write that code again.
Car myCar = new Car();
myCar.Speed = 60;
myCar.Move(); // This method comes from the Vehicle class!
Truck myTruck = new Truck();
myTruck.Speed = 45;
myTruck.Move(); // This method also comes from the Vehicle class!
Inheritance is a powerful tool for code reuse and for creating logical hierarchies in your programs.
Polymorphism
Polymorphism, which means "many forms," allows objects of different classes to be treated as objects of a common base class. More practically, it lets a derived class provide its own specific implementation of a method that is already defined in its base class. This is called method overriding.
Let's go back to our Vehicle example. The Move() method is a bit generic. A car might move differently from a boat. We can use the virtual keyword in the base class to allow a method to be overridden, and the override keyword in the derived class to provide a new version.
public class Vehicle
{
// 'virtual' allows derived classes to override this method
public virtual void Move()
{
Console.WriteLine("The vehicle is moving.");
}
}
public class Car : Vehicle
{
// 'override' provides a new implementation for this specific class
public override void Move()
{
Console.WriteLine("The car is driving on the road.");
}
}
public class Boat : Vehicle
{
public override void Move()
{
Console.WriteLine("The boat is sailing on the water.");
}
}
Now, even if we treat both a Car and a Boat as a generic Vehicle, calling Move() will execute the correct, specific version.
Vehicle myCar = new Car();
Vehicle myBoat = new Boat();
myCar.Move(); // Output: The car is driving on the road.
myBoat.Move(); // Output: The boat is sailing on the water.
This is extremely powerful. It lets you write flexible code that can work with many different object types without needing to know their specific details. You can just trust that each object knows how to perform the action correctly for itself.
The four principles of object-oriented programming are encapsulation, abstraction, inheritance, and polymorphism.
Time to test your understanding of these core concepts.
In Object-Oriented Programming, what is the fundamental relationship between a class and an object?
Which OOP principle is best described as bundling data and the methods that operate on that data together, and controlling access to them?
These four principles—classes/objects, encapsulation, inheritance, and polymorphism—are the foundation of C# and most modern programming languages. Mastering them is a huge step toward writing clean, robust, and scalable applications.