<aside> Inheritance and Polymorphism are fundamental concepts in Object-Oriented Programming that enable code reuse, flexibility, and better organization of complex systems.

</aside>

🔄 Inheritance

Inheritance allows a class to include properties and methods from another class, promoting code reuse and establishing relationships between classes.

<aside> Key Terms: • Superclass/Base Class: The class being inherited from • Subclass/Derived Class: The class that inherits • 'protected' members: Accessible by derived classes • 'virtual' methods: Can be overridden by derived classes • 'abstract' classes: Cannot be instantiated directly with 'new'

</aside>

🔑 Abstract Classes

Abstract classes are used when designing the most fundamental parts of a class hierarchy. An abstract class is different from a concrete class because you cannot create an object directly from it - you cannot use the 'new' keyword. Instead, you must create subclasses that inherit from the abstract class.

🐾 Simple Animal Example

/// <summary>
/// Represents a generic animal with basic properties and behaviors.
/// </summary>
public class Animal
{
    /// <summary>
    /// The name of the animal.
    /// This property is marked as <c>protected</c>, meaning it can only be accessed
    /// within this class and by derived classes (e.g., subclasses like <see cref="Dog"/>).
    /// </summary>
    protected string Name { get; set; }

    /// <summary>
    /// The age of the animal.
    /// Like <see cref="Name"/>, this property is <c>protected</c>, so it is not accessible
    /// outside this class or its subclasses.
    /// </summary>
    protected int Age { get; set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="Animal"/> class.
    /// </summary>
    /// <param name="name">The name of the animal.</param>
    /// <param name="age">The age of the animal.</param>
    public Animal(string name, int age)
    {
        Name = name; // Assign the name of the animal.
        Age = age;   // Assign the age of the animal.
    }

    /// <summary>
    /// Produces a sound that the animal makes.
    /// This method can be overridden by subclasses to provide specific sounds.
    /// </summary>
    /// <returns>A string representing the sound made by the animal.</returns>
    public virtual string MakeSound()
    {
        return "Some sound"; // Default sound for a generic animal.
    }
}

/// <summary>
/// Represents a dog, which is a specific type of animal.
/// </summary>
public class Dog : Animal
{
    /// <summary>
    /// The breed of the dog.
    /// This property is <c>public</c>, meaning it can be accessed from anywhere.
    /// </summary>
    public string Breed { get; set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="Dog"/> class.
    /// </summary>
    /// <param name="name">The name of the dog.</param>
    /// <param name="age">The age of the dog.</param>
    /// <param name="breed">The breed of the dog.</param>
    public Dog(string name, int age, string breed) 
        : base(name, age) // Call the base class constructor to initialize Name and Age.
    {
        Breed = breed; // Assign the breed of the dog.
    }

    /// <summary>
    /// Produces the sound that a dog makes.
    /// Overrides the <see cref="Animal.MakeSound"/> method to provide a dog-specific sound.
    /// </summary>
    /// <returns>A string representing the sound "Woof!".</returns>
    public override string MakeSound()
    {
        return "Woof!"; // Specific sound for a dog.
    }

    /// <summary>
    /// Simulates the dog fetching a ball.
    /// </summary>
    /// <returns>A string indicating that the dog is fetching the ball.</returns>
    public string Fetch()
    {
        // Use the protected property Name from the base class to personalize the message.
        return $"{Name} is fetching the ball!";
    }
}

<aside> Important Notes: • You CANNOT do this: Animal a = new Animal(); // Error: Cannot create instance of abstract class • You CAN do this: Animal a = new Giraffe(); // Valid: Creating a Giraffe and treating it as an Animal

</aside>

🔄 Polymorphism

Polymorphism allows objects of different types to be treated as objects of a common base type, while maintaining their specific behaviors.

Types of Polymorphism:

📐 Shape Example

public abstract class Shape
{
    public abstract double CalculateArea();
}

public class Circle : Shape
{
    public double Radius { get; set; }

    public Circle(double radius)
    {
        Radius = radius;
    }

    public override double CalculateArea()
    {
        return Math.PI * Radius * Radius;
    }
}