Interface - lucyberryhub/WPF.Tutorial GitHub Wiki

🍒 Cherry-Tastic Interfaces: Learn the Berry Sweet Way! 🍓✨

Hello, my lovely berry friends! It’s Lucy Berry here, and today we’re going to learn all about interfaces in C#. Don’t worry, it’s super easy—like making a smoothie with cherries, strawberries, and a splash of magic! 🥤✨


💖 What’s an Interface? 🍒

An interface is like a menu at a berry café! 🌸 Imagine a cherry smoothie menu that says:

  • Must have cherries 🍒
  • Must have ice 🧊
  • Must have sweetness 🍬

It doesn’t tell you how to make it, but it says, "Hey, any smoothie maker needs to include these things to call itself a ‘Cherry Smoothie Maker’!" 💡

So, in coding terms:

  • Interfaces define what must exist (like properties and methods).
  • Classes define how these things work.

🌟 Why Use Interfaces? 🍓

  1. Berry Consistency: All classes that follow an interface will have the same structure—no missing cherries! 🍒
  2. Berry Flexibility: You can write one method to handle all smoothies, no matter who makes them. 🥤
  3. Berry Clean Code: Your code stays as fresh as a basket of strawberries! 🍓

🌈 Let’s Make Some Cherry Magic! 🍒✨

1️⃣ Step 1: Define Your Interface 🍓

Here’s our cherry-themed interface! Every berry dessert maker must follow this recipe:
✨ Must have an Id (Berry ID).
✨ Must have a Name (Dessert name).
✨ Must have some Toppings (Yum!).

public interface ICherryDessert
{
    int BerryId { get; set; } // Unique berry ID 🍒
    string DessertName { get; set; } // Name of the dessert 🎂
    string Toppings { get; set; } // Toppings for extra yum 🍓
}

2️⃣ Step 2: Create a Cherrylicious Class 🍒

Now, let’s create a class called CherryPie. It’s a dessert that follows the ICherryDessert contract.

public class CherryPie : ICherryDessert
{
    public int BerryId { get; set; } // ID for this sweet pie 🍒
    public string DessertName { get; set; } // Name: Cherry Pie 🥧
    public string Toppings { get; set; } // Toppings like whipped cream 🍦

    public void Serve()
    {
        Console.WriteLine($"Serving {DessertName} with {Toppings}!");
    }
}

3️⃣ Step 3: Add Another Berrylicious Interface 🍓

What if we have another kind of dessert, like a Berry Sundae?
We’ll make another interface called IBerryIceCream.

public interface IBerryIceCream
{
    int BerryId { get; set; } // Unique ID for sundaes too 🍧
    string Flavor { get; set; } // Flavor of the ice cream 🍨
    bool HasCherryOnTop { get; set; } // Is there a cherry? 🍒
}

Here’s a class that implements it:

public class BerrySundae : IBerryIceCream
{
    public int BerryId { get; set; }
    public string Flavor { get; set; }
    public bool HasCherryOnTop { get; set; }

    public void Serve()
    {
        Console.WriteLine($"Serving {Flavor} sundae{(HasCherryOnTop ? " with a cherry on top!" : " without a cherry. 😢")}");
    }
}

4️⃣ Step 4: A Method to Handle All Desserts 🍰

Let’s make a ServeDessert method that can handle any dessert, whether it’s a pie or a sundae. 🎉

public void ServeDessert<T>(T dessert) where T : class
{
    if (dessert is ICherryDessert cherryDessert)
    {
        Console.WriteLine($"🍒 Preparing {cherryDessert.DessertName} with {cherryDessert.Toppings}!");
    }
    else if (dessert is IBerryIceCream berryIceCream)
    {
        Console.WriteLine($"🍨 Preparing {berryIceCream.Flavor} sundae{(berryIceCream.HasCherryOnTop ? " with a cherry!" : ".")}");
    }
    else
    {
        Console.WriteLine("🚫 Unknown dessert! No cherries for you! 😭");
    }
}

🏁 Full Cherry-Tastic Code Example 🍒✨

Here’s everything put together:

using System;

public interface ICherryDessert
{
    int BerryId { get; set; }
    string DessertName { get; set; }
    string Toppings { get; set; }
}

public interface IBerryIceCream
{
    int BerryId { get; set; }
    string Flavor { get; set; }
    bool HasCherryOnTop { get; set; }
}

public class CherryPie : ICherryDessert
{
    public int BerryId { get; set; }
    public string DessertName { get; set; }
    public string Toppings { get; set; }

    public void Serve()
    {
        Console.WriteLine($"Serving {DessertName} with {Toppings}!");
    }
}

public class BerrySundae : IBerryIceCream
{
    public int BerryId { get; set; }
    public string Flavor { get; set; }
    public bool HasCherryOnTop { get; set; }

    public void Serve()
    {
        Console.WriteLine($"Serving {Flavor} sundae{(HasCherryOnTop ? " with a cherry on top!" : ".")}");
    }
}

class Program
{
    public static void ServeDessert<T>(T dessert) where T : class
    {
        if (dessert is ICherryDessert cherryDessert)
        {
            Console.WriteLine($"🍒 Preparing {cherryDessert.DessertName} with {cherryDessert.Toppings}!");
        }
        else if (dessert is IBerryIceCream berryIceCream)
        {
            Console.WriteLine($"🍨 Preparing {berryIceCream.Flavor} sundae{(berryIceCream.HasCherryOnTop ? " with a cherry!" : ".")}");
        }
        else
        {
            Console.WriteLine("🚫 Unknown dessert! No cherries for you! 😭");
        }
    }

    static void Main()
    {
        var pie = new CherryPie
        {
            BerryId = 1,
            DessertName = "Cherry Pie",
            Toppings = "whipped cream"
        };

        var sundae = new BerrySundae
        {
            BerryId = 2,
            Flavor = "Strawberry",
            HasCherryOnTop = true
        };

        ServeDessert(pie);
        ServeDessert(sundae);
    }
}

🌸 Final Thoughts

Interfaces are your berry best friend for keeping your code cute, clean, and consistent! 🍓✨
Now go sprinkle some cherries and enjoy coding like a berry pro! 🍒💻💖