Giao diện
📐 Abstract Classes — Lớp trừu tượng
Abstract class định nghĩa interface mà derived classes phải implement. Không thể tạo object từ abstract class.
Pure Virtual Functions
cpp
class Shape {
public:
// Pure virtual — không có implementation
virtual double area() const = 0; // "= 0" làm nó pure
virtual void draw() const = 0;
// Virtual destructor (không pure)
virtual ~Shape() = default;
};
int main() {
// ❌ Error: cannot instantiate abstract class
// Shape s;
// ✅ Nhưng có thể dùng pointer/reference
Shape* ptr = nullptr;
}Abstract vs Concrete Classes
| Type | Pure Virtual? | Can Instantiate? |
|---|---|---|
| Abstract | Có ít nhất 1 | ❌ No |
| Concrete | Không có | ✅ Yes |
cpp
// Abstract — có pure virtual
class Drawable {
public:
virtual void draw() const = 0;
};
// Abstract — kế thừa nhưng chưa implement hết
class Shape : public Drawable {
// Vẫn abstract vì chưa implement draw()
};
// Concrete — implement tất cả pure virtuals
class Circle : public Shape {
public:
void draw() const override { // ✅ Bắt buộc implement
std::cout << "Drawing Circle\n";
}
};Interface Pattern (Pure Abstract Class)
C++ không có interface keyword như Java/C#, nhưng ta có thể mô phỏng:
cpp
// Interface = Pure abstract class (chỉ có pure virtuals)
class ILogger {
public:
virtual void log(const std::string& message) = 0;
virtual void setLevel(int level) = 0;
virtual ~ILogger() = default;
};
class ISerializable {
public:
virtual std::string serialize() const = 0;
virtual void deserialize(const std::string& data) = 0;
virtual ~ISerializable() = default;
};
// Concrete class implementing interfaces
class FileLogger : public ILogger {
public:
void log(const std::string& message) override {
std::cout << "[FILE] " << message << std::endl;
}
void setLevel(int level) override {
// Implementation
}
};
class ConsoleLogger : public ILogger {
public:
void log(const std::string& message) override {
std::cout << "[CONSOLE] " << message << std::endl;
}
void setLevel(int level) override {
// Implementation
}
};Naming Convention
cpp
// Prefixed with 'I' để biết là interface
class IObserver { };
class ISubject { };
class IRepository { };
// Hoặc suffix với 'Interface' / 'Base'
class LoggerInterface { };
class RepositoryBase { };Dependency Injection với Interfaces
cpp
#include <iostream>
#include <memory>
// Interface
class IDatabase {
public:
virtual void save(const std::string& data) = 0;
virtual std::string load(int id) = 0;
virtual ~IDatabase() = default;
};
// Concrete implementations
class MySQLDatabase : public IDatabase {
public:
void save(const std::string& data) override {
std::cout << "[MySQL] Saving: " << data << std::endl;
}
std::string load(int id) override {
return "[MySQL] Data for id " + std::to_string(id);
}
};
class MongoDatabase : public IDatabase {
public:
void save(const std::string& data) override {
std::cout << "[MongoDB] Saving: " << data << std::endl;
}
std::string load(int id) override {
return "[MongoDB] Data for id " + std::to_string(id);
}
};
// Service depends on INTERFACE, not concrete class
class UserService {
std::unique_ptr<IDatabase> db_;
public:
// Inject dependency
explicit UserService(std::unique_ptr<IDatabase> db)
: db_(std::move(db)) {}
void createUser(const std::string& name) {
db_->save("User: " + name);
}
void getUser(int id) {
std::cout << db_->load(id) << std::endl;
}
};
int main() {
// Dễ dàng swap implementations!
auto mysqlService = UserService(std::make_unique<MySQLDatabase>());
mysqlService.createUser("Alice");
auto mongoService = UserService(std::make_unique<MongoDatabase>());
mongoService.createUser("Bob");
return 0;
}Abstract Class với Partial Implementation
cpp
class Document {
protected:
std::string content_;
public:
// Concrete method — shared implementation
void setContent(const std::string& content) {
content_ = content;
}
std::string getContent() const {
return content_;
}
// Pure virtual — must be implemented by derived
virtual void save(const std::string& path) = 0;
virtual void load(const std::string& path) = 0;
virtual ~Document() = default;
};
class PDFDocument : public Document {
public:
void save(const std::string& path) override {
std::cout << "Saving PDF to " << path << std::endl;
}
void load(const std::string& path) override {
std::cout << "Loading PDF from " << path << std::endl;
}
};
class WordDocument : public Document {
public:
void save(const std::string& path) override {
std::cout << "Saving Word to " << path << std::endl;
}
void load(const std::string& path) override {
std::cout << "Loading Word from " << path << std::endl;
}
};Template Method Pattern
cpp
class Game {
public:
// Template method — defines algorithm skeleton
void play() {
initialize();
while (!isGameOver()) {
processInput();
update();
render();
}
cleanup();
}
protected:
// Hook methods — can be overridden
virtual void initialize() { }
virtual void cleanup() { }
// Pure virtual — MUST be implemented
virtual void processInput() = 0;
virtual void update() = 0;
virtual void render() = 0;
virtual bool isGameOver() const = 0;
public:
virtual ~Game() = default;
};
class ChessGame : public Game {
protected:
void initialize() override {
std::cout << "Setting up chess board...\n";
}
void processInput() override {
std::cout << "Getting move...\n";
}
void update() override {
std::cout << "Updating game state...\n";
}
void render() override {
std::cout << "Drawing board...\n";
}
bool isGameOver() const override {
return false; // Simplified
}
};Khi nào dùng Abstract Class vs Interface?
| Use Case | Recommendation |
|---|---|
| Define contract only | Pure interface (all pure virtual) |
| Share some implementation | Abstract class with mix |
| Multiple "is-a" relationships | Multiple interfaces |
| Single hierarchy | Abstract base class |
📚 Tổng kết
| Concept | Key Takeaway |
|---|---|
Pure virtual (= 0) | Method không có implementation |
| Abstract class | Có ít nhất 1 pure virtual, không instantiate được |
| Interface | Pure abstract class (chỉ pure virtuals) |
| Dependency Injection | Depend on abstractions, not concretions |
| Template Method | Define skeleton, defer steps to subclasses |
➡️ Tiếp theo
Tiếp theo: RPG Class System — Áp dụng Inheritance & Polymorphism vào game project.