Skip to content

Instantly share code, notes, and snippets.

@kenpower
Created January 28, 2026 10:46
Show Gist options
  • Select an option

  • Save kenpower/e2111b3160e3ae486020f5783af685e5 to your computer and use it in GitHub Desktop.

Select an option

Save kenpower/e2111b3160e3ae486020f5783af685e5 to your computer and use it in GitHub Desktop.
Using interfaces for polymorphisim
#include <iostream>
#include <vector>
#include <string>
// Interface - defines what all enemies must do
class IEnemy {
public:
virtual ~IEnemy() {} // Virtual destructor for cleanup
virtual void takeDamage(int damage) = 0; // Pure virtual = must implement
virtual void update() = 0;
virtual bool isAlive() const = 0;
};
// Concrete enemy types
class Zombie : public IEnemy {
private:
int health = 50;
public:
void takeDamage(int damage) override {
health -= damage;
std::cout << "Zombie takes " << damage << " damage! ";
std::cout << "Health: " << health << "\n";
}
void update() override {
std::cout << "Zombie shambles forward...\n";
}
bool isAlive() const override {
return health > 0;
}
};
class Robot : public IEnemy {
private:
int armor = 100;
public:
void takeDamage(int damage) override {
int reducedDamage = damage / 2; // Robots have armor!
armor -= reducedDamage;
std::cout << "Robot deflects damage! Takes " << reducedDamage << ". ";
std::cout << "Armor: " << armor << "\n";
}
void update() override {
std::cout << "Robot scanning for targets...\n";
}
bool isAlive() const override {
return armor > 0;
}
};
// Game code - works with ANY enemy type
void attackEnemy(IEnemy* enemy, int damage) {
enemy->takeDamage(damage);
}
int main() {
// Create different enemy types
std::vector<IEnemy*> enemies;
enemies.push_back(new Zombie());
enemies.push_back(new Robot());
// Attack all enemies the same way!
std::cout << "=== ATTACKING ALL ENEMIES ===\n";
for (IEnemy* enemy : enemies) {
attackEnemy(enemy, 20);
}
// Update all enemies
std::cout << "\n=== UPDATING ALL ENEMIES ===\n";
for (IEnemy* enemy : enemies) {
if (enemy->isAlive()) {
enemy->update();
}
}
// Cleanup
for (IEnemy* enemy : enemies) {
delete enemy;
}
return 0;
}

Why This is Useful

  1. Polymorphism: The attackEnemy function works with ANY enemy type

  2. Easy to extend: Want to add a Dragon? Just implement IEnemy

  3. Cleaner code: Game systems don't need to know specific enemy types

Without interfaces, you'd need separate code for each enemy type, making your game harder to maintain and extend

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment