Intro to OOP


Definition of Object-Oriented Programming (OOP)


OOP is a programming paradigm that organizes software design around objects rather than focusing on functions or logic.

An object is a data entity that consists of attributes (data fields) and behaviors (methods).

Attributes (data fields)

Represent properties of the object.

Example:

class Car
{
    // Attributes (data fields, properties)
    public string Brand { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
}

// Creating an object
Car myCar = new Car();
myCar.Brand = "Toyota";
myCar.Model = "Camry";
myCar.Year = 2023;

// Accessing attributes
Console.WriteLine($"Car: {myCar.Brand} {myCar.Model}, Year: {myCar.Year}");

Explanation:

Metaphor:
Attributes are like the features of a car (e.g., brand, model, year). Each car object has its own set of features, just like different cars on the road.

Behavior (methods)

Define actions the object can perform.

Example:

class Car
{
    // Attributes (data fields, properties)
    public string Brand { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }

    // Behavior (Method)
    public void Drive()
    {
        Console.WriteLine($"{Brand} {Model} is driving.");
    }
}

// Creating an object and calling a method
Car myCar = new Car { Brand = "Honda", Model = "Civic", Year = 2022 };
myCar.Drive();

Explanation:

Metaphor:
Behaviors are like the actions a car can perform (e.g., driving, honking). Each car object can perform these actions, just like real cars on the road.


Key OOP Concepts


Classes

A class is a template (scheme) for creating objects. It defines the attributes (data) and methods (behaviors) that the objects created from the class will have.

Example:

class Person
{
    // Attributes (data fields)
    public string Name { get; set; }
    public int Age { get; set; }

    // Behavior (method)
    public void Greet()
    {
        Console.WriteLine($"Hello, my name is {Name} and I am {Age} years old.");
    }
}

// Creating an object
Person person1 = new Person { Name = "Alice", Age = 30 };
person1.Greet();

Explanation:

Objects

An object is an instance of a class that contains specific data and behaviors.

Example:

class Dog
{
    public string Breed { get; set; }
    public string Color { get; set; }

    public void Bark()
    {
        Console.WriteLine($"The {Color} {Breed} is barking.");
    }
}

// Creating objects
Dog dog1 = new Dog { Breed = "Labrador", Color = "Black" };
Dog dog2 = new Dog { Breed = "Beagle", Color = "Brown" };

dog1.Bark();
dog2.Bark();

Explanation:

Inheritance

Inheritance allows a class to acquire the properties and methods of another class.

Example:

class Animal
{
    public void Eat()
    {
        Console.WriteLine("This animal is eating.");
    }
}

// `:` denotes inheritance. Dog <- Animal (Dog inherits from Animal)
class Dog : Animal
{
    public void Bark()
    {
        Console.WriteLine("The dog is barking.");
    }
}

// Using inheritance
Dog myDog = new Dog();
myDog.Eat();  // Inherited method
myDog.Bark();

Explanation:

Encapsulation

Encapsulation is the bundling of data (attributes) and methods (behaviors) within a single unit, restricting direct access to certain parts.

Example:

class BankAccount
{
    private double balance;  // Private attribute

    public void Deposit(double amount)
    {
        balance += amount;
    }

    public double GetBalance()
    {
        return balance;
    }
}

// Using encapsulation
BankAccount account = new BankAccount();
account.Deposit(1000);
Console.WriteLine($"Balance: {account.GetBalance()}");

// Direct access to balance is restricted!
account.balance = 5000;  // Error: 'BankAccount.balance' is inaccessible due to its protection level

Explanation:

Polymorphism

Polymorphism allows methods to have different implementations based on the object that invokes them.

Example:

class Shape
{
    // `virtual` keyword allows overriding in subclasses
    public virtual void Draw()
    {
        Console.WriteLine("Drawing a shape.");
    }
}

class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing a circle.");
    }
}

class Square : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing a square.");
    }
}

// Using polymorphism
Shape shape1 = new Circle();
Shape shape2 = new Square();
Shape shape3 = new Shape();

shape1.Draw(); // Output: Drawing a circle.
shape2.Draw(); // Output: Drawing a square.
shape3.Draw(); // Output: Drawing a shape.

Explanation:

Metaphor:
Polymorphism is like a like ordering a coffee at a café. The same command ("coffee, please") can result in different outcomes based on the type of coffee (espresso, latte, cappuccino) you want receive.

Abstraction

Abstraction hides complex implementation details and only shows essential features to the user.

Example:

abstract class Appliance
{
    // `abstract` keyword
    public abstract void TurnOn();
}

class WashingMachine : Appliance
{
    public override void TurnOn()
    {
        Console.WriteLine("Washing machine is now running.");
    }
}

// Using abstraction
Appliance myAppliance = new WashingMachine();
myAppliance.TurnOn();

Explanation:

Metaphor:
Using abstraction is like driving a car. You know how to steer, accelerate, and brake, but you DO NOT need to understand how the engine, transmission, or braking system works internally. The car abstracts these complexities, providing a simple interface (steering wheel, pedals, dashboard) to the driver.

Key Differences Between Abstraction and Polymorphism

Aspect Abstraction Polymorphism
Focus Hiding complex details Multiple behaviors under a common interface
Purpose Defines "what" should be done Defines "how" objects behave differently
Keyword abstract classes, interface virtual, override
Implementation Abstract classes, Interfaces Method Overriding, Method Overloading
Example Appliance with a general TurnOn() method Different shapes having their own Draw()
Metaphor Car dashboard (hides internal complexity) Universal remote (same action, different results)

When to Use Abstraction vs. Polymorphism

  1. Use Abstraction when:

    • You want to provide a simple, unified interface for complex systems (e.g., using interfaces or abstract classes).
    • Example: Creating an Animal class with an abstract MakeSound() method, which forces subclasses to implement their own sounds.
  2. Use Polymorphism when:

    • You want the same interface to represent different behaviors depending on the specific object.
    • Example: Allowing different types of PaymentProcessor (CreditCard, PayPal) to process payments differently but under the same interface.

Explanation and Insights

Why OOP Matters

Metaphors to Understand OOP

  1. Classes and Objects: A class is like a cookie cutter, and an object is the cookie made from it. Each cookie (object) follows the same shape but can have different ingredients (attributes).
  2. Encapsulation: Think of encapsulation as a capsule pill, where medicine (data) is safely enclosed and only released in controlled ways.
  3. Inheritance: Similar to how children inherit traits from their parents, subclasses inherit properties and behaviors from their parent classes.
  4. Polymorphism: A universal remote control can operate multiple devices (TV, AC, speakers), but each responds differently to the same command.
  5. Abstraction: When driving a car, you don't need to understand the engine's internal workings. You interact with the car through a simplified interface (steering wheel, pedals).