Abstraction & Interfaces 🎯
Show Only What's Important (It's Easier Than You Think!)
Hey There! Ready to Learn About Abstraction? 🎭
Abstraction and Interfaces might sound complicated, but they're actually super useful! They help you hide the complicated stuff and show only what's important.
- ✅ Explain abstraction like a pro (but in simple words)
- ✅ Create abstract classes (the "must follow" rules)
- ✅ Use interfaces (the "I promise to do this" contracts)
- ✅ Know when to use abstract vs interface
- ✅ Build flexible, clean code
Part 1: What is Abstraction? (The Easy Way)
🎮 The Remote Control Analogy
Think about your TV remote:
- 📺 You see buttons (the interface)
- 📺 You don't see the circuits inside
- 📺 You don't need to know how it works
- 📺 Just press the button and it works
You only see what's important - the buttons!
💻 Code Time!
Abstract Class:
public abstract class RemoteControl
{
// You MUST implement these
public abstract void VolumeUp();
public abstract void VolumeDown();
}
Child Class - TV Remote:
public class TVRemote : RemoteControl
{
public override void VolumeUp()
{
// TV specific code
}
}
Part 2: Abstract Classes - The "Must Follow" Rules
📝 Abstract Class Rules
public abstract class Vehicle
{
// ✅ MUST be implemented by children
public abstract void Start();
public abstract void Stop();
// ✅ Already implemented - children get this for free
public void Honk()
{
Console.WriteLine("Beep beep!");
}
}
📌 Abstract methods = NO body (just the rule)
✅ Child MUST Implement
public class Car : Vehicle
{
public override void Start() // ✅ Must do this!
{
Console.WriteLine("🚗 Car engine starts...");
}
public override void Stop() // ✅ Must do this!
{
Console.WriteLine("🛑 Car stops...");
}
}
Vehicle v = new Vehicle(); ❌ (Error!)
Vehicle v = new Car(); ✅ (Works!)
🤔 When to Use Abstract Classes?
- ✅ When classes share common code
- ✅ When classes are related (is-a relationship)
- ✅ When you want to enforce rules for children
- ✅ When you have some implemented methods to share
Part 3: Interfaces - The "I Promise" Contract
📝 Interface (The Contract)
public interface IPlayable
{
void Play(); // No implementation
void Pause(); // Just the rule
}
📌 Interfaces have NO code - just rules!
📌 Methods are public by default
✅ Class MUST Implement
public class MusicPlayer : IPlayable
{
public void Play() // ✅ Must implement!
{
Console.WriteLine("🎵 Playing music...");
}
public void Pause() // ✅ Must implement!
{
Console.WriteLine("⏸️ Music paused...");
}
}
✅ A Class Can Implement MANY Interfaces
public interface IPlayable { void Play(); }
public interface IRecordable { void Record(); }
// ✅ One class, TWO interfaces!
public class SmartDevice : IPlayable, IRecordable
{
public void Play() { }
public void Record() { }
}
🤔 When to Use Interfaces?
- ✅ When classes are unrelated but share behavior
- ✅ When you want to define capabilities ("can do")
- ✅ When you need multiple capabilities (can do many things)
- ✅ When creating plugins or extensions
Part 4: Abstract Class vs Interface - Which One to Use?
| Feature | Abstract Class | Interface |
|---|---|---|
| What it is | Partial blueprint (has some code) | Complete contract (no code) |
| Can have code | ✅ Yes (methods with bodies) | ❌ No (just method names) |
| Can have fields | ✅ Yes | ❌ No (just properties) |
| Inheritance | One parent only | Many interfaces |
| Relationship | "IS A" (is a type of) | "CAN DO" (has ability) |
Use Abstract Class When:
- ✅ Classes share common code
- ✅ Classes are related (Animal → Dog, Cat)
- ✅ You want to share implementation
- ✅ You need fields or constructors
Use Interface When:
- ✅ Classes are unrelated but share behavior
- ✅ You just need capabilities (Fly, Swim)
- ✅ You need multiple behaviors
- ✅ You're building plugins or APIs
💡 Quick Rule of Thumb
If you can say "IS A" → Use Abstract Class (Dog IS A Animal)
If you can say "CAN DO" → Use Interface (Dog CAN RUN, Dog CAN SWIM)
Part 5: Real-World Example - Game Characters 🎮
Let's build a Game Character System using abstraction and interfaces!
// 🔥 Interfaces - Capabilities
public interface IAttack
{
void Attack();
}
public interface IDefend
{
void Defend();
}
public interface IHeal
{
void Heal();
}
// 🎯 Abstract Class - Base Character
public abstract class Character
{
public string Name { get; set; }
public int Health { get; set; }
public Character(string name, int health)
{
Name = name;
Health = health;
}
// ✅ MUST be implemented
public abstract void DisplayInfo();
}
// 🦸 Warrior - Implements multiple interfaces
public class Warrior : Character, IAttack, IDefend
{
public Warrior(string name) : base(name, 100) { }
public override void DisplayInfo()
{
Console.WriteLine($"⚔️ Warrior: {Name} (HP: {Health})");
}
public void Attack() =>
Console.WriteLine($"⚔️ {Name} swings sword!");
public void Defend() =>
Console.WriteLine($"🛡️ {Name} raises shield!");
}
"> // 🧙 Mage - Different set of capabilities
public class Mage : Character, IAttack, IHeal
{
public Mage(string name) : base(name, 80) { }
public override void DisplayInfo()
{
Console.WriteLine($"🔮 Mage: {Name} (HP: {Health})");
}
public void Attack() =>
Console.WriteLine($"🔮 {Name} casts fireball!");
public void Heal() =>
Console.WriteLine($"💚 {Name} casts healing spell!");
}
// Program.cs - Using the System
class Program
{
static void Main()
{
Console.WriteLine("⚔️ GAME CHARACTER SYSTEM\n");
// Create characters
Warrior warrior = new Warrior("Conan");
Mage mage = new Mage("Merlin");
// Display info
warrior.DisplayInfo();
mage.DisplayInfo();
Console.WriteLine();
// Use capabilities (Interfaces)
warrior.Attack(); // Swings sword
warrior.Defend(); // Raises shield
mage.Attack(); // Casts fireball
mage.Heal(); // Healing spell
}
}
- ✅ Abstract Class - Character (common code)
- ✅ Interfaces - Attack, Defend, Heal (capabilities)
- ✅ Multiple Interfaces - Warrior has Attack + Defend
- ✅ Different Capabilities - Mage has Attack + Heal
Part 6: Default Interface Methods (C# 8+)
📝 Interface with Default Methods
public interface ILogger
{
// ✅ Must be implemented
void Log(string message);
// ✅ Default implementation
void LogError(string error)
{
Console.WriteLine($"ERROR: {error}");
}
}
✅ Using Default Methods
public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
// No need to implement LogError!
// It gets the default version for free
}
- ✅ Add new methods without breaking existing code
- ✅ Provide default behavior for common cases
- ✅ Upgrade interfaces safely
Part 7: Let's Practice! 🎮
Different devices (Lights, Thermostat, Security Camera) all have common features but work differently.
🏠 About This Application
This is a Smart Home System like:
- 💡 Philips Hue - Smart lights
- 🌡️ Nest - Smart thermostat
- 📹 Ring - Security cameras
Each device has common features but different implementations:
- ✅ All devices have a Name and Status
- ✅ All devices can TurnOn() and TurnOff()
- ✅ Lights can AdjustBrightness()
- ✅ Thermostat can SetTemperature()
- ✅ Camera can StartRecording()
Your Mission:
-
Interface: IDevice
- Methods: TurnOn(), TurnOff()
- Property: Status (string)
-
Abstract Class: SmartDevice
- Properties: Name, Status
- Implement IDevice
- Virtual: DisplayInfo()
-
Derived: Light
- Property: Brightness (int)
- Method: AdjustBrightness()
-
Derived: Thermostat
- Property: Temperature (int)
- Method: SetTemperature()
-
Derived: SecurityCamera
- Property: IsRecording (bool)
- Method: StartRecording()
💡 How This Uses Abstraction:
- ✅ Interface - Defines what devices CAN DO
- ✅ Abstract Class - Provides common code
- ✅ Override - Each device behaves differently
- ✅ Polymorphism - Treat all devices as IDevice
// ===== SMART HOME SYSTEM =====
// This shows abstraction and interfaces in action
// Interface - What devices CAN DO
public interface IDevice
{
void TurnOn();
void TurnOff();
string Status { get; }
}
// Abstract Class - Common code for all devices
public abstract class SmartDevice : IDevice
{
public string Name { get; set; }
public string Status { get; protected set; }
public SmartDevice(string name)
{
Name = name;
Status = "Off";
}
public virtual void TurnOn()
{
Status = "On";
Console.WriteLine($"🟢 {Name} turned ON");
}
public virtual void TurnOff()
{
Status = "Off";
Console.WriteLine($"🔴 {Name} turned OFF");
}
public virtual void DisplayInfo()
{
Console.WriteLine($"📱 {Name}: {Status}");
}
}
// Light - Can adjust brightness
public class Light : SmartDevice
{
public int Brightness { get; private set; }
public Light(string name) : base(name)
{
Brightness = 50;
}
public void AdjustBrightness(int level)
{
Brightness = Math.Clamp(level, 0, 100);
Console.WriteLine($"💡 {Name} brightness: {Brightness}%");
}
public override void DisplayInfo()
{
Console.WriteLine($"💡 {Name}: {Status} (Brightness: {Brightness}%)");
}
}
// Thermostat - Can set temperature
public class Thermostat : SmartDevice
{
public int Temperature { get; private set; }
public Thermostat(string name) : base(name)
{
Temperature = 21;
}
public void SetTemperature(int temp)
{
Temperature = temp;
Console.WriteLine($"🌡️ {Name} temperature set to {Temperature}°C");
}
public override void DisplayInfo()
{
Console.WriteLine($"🌡️ {Name}: {Status} (Temperature: {Temperature}°C)");
}
}
// SecurityCamera - Can record
public class SecurityCamera : SmartDevice
{
public bool IsRecording { get; private set; }
public SecurityCamera(string name) : base(name)
{
IsRecording = false;
}
public void StartRecording()
{
IsRecording = true;
Console.WriteLine($"📹 {Name} started recording!");
}
public void StopRecording()
{
IsRecording = false;
Console.WriteLine($"📹 {Name} stopped recording!");
}
public override void DisplayInfo()
{
Console.WriteLine($"📹 {Name}: {Status} (Recording: {(IsRecording ? "Yes" : "No")})");
}
}
// Program.cs - Smart Home System
class Program
{
static void Main()
{
Console.WriteLine("🏠 SMART HOME SYSTEM");
Console.WriteLine("═══════════════════════════════════\n");
// Create devices
Light light = new Light("Living Room Light");
Thermostat thermostat = new Thermostat("Main Thermostat");
SecurityCamera camera = new SecurityCamera("Front Door Camera");
// Control devices
Console.WriteLine("📋 DEVICE CONTROL:\n");
light.TurnOn();
light.AdjustBrightness(75);
light.DisplayInfo();
Console.WriteLine();
thermostat.TurnOn();
thermostat.SetTemperature(24);
thermostat.DisplayInfo();
Console.WriteLine();
camera.TurnOn();
camera.StartRecording();
camera.DisplayInfo();
Console.WriteLine();
Console.WriteLine("🔄 POLYMORPHISM DEMONSTRATION:");
// Treat all as IDevice
IDevice[] devices = { light, thermostat, camera };
foreach (var device in devices)
{
Console.WriteLine($"Device: {device.Status}");
}
}
}