← Назад к вопросам

Какие основные принципы ООП?

1.0 Junior🔥 131 комментариев
#ООП и проектирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Основные принципы объектно-ориентированного программирования (ООП)

Объектно-ориентированное программирование — парадигма, в основе которой лежит концепция объектов, содержащих состояние (поля/атрибуты) и поведение (методы). Четыре основных принципа ООП образуют фундамент для написания масштабируемого и поддерживаемого кода на C++.

1. Инкапсуляция (Encapsulation)

Инкапсуляция — скрытие внутренних деталей реализации и предоставление интерфейса для взаимодействия с объектом через методы.

#include <iostream>
#include <string>

class BankAccount {
private:  // Скрытые детали реализации
    double balance;
    std::string account_number;
    
    bool validate_amount(double amount) {
        return amount > 0 && amount <= balance;
    }
public:   // Публичный интерфейс
    BankAccount(const std::string& acc_num, double initial_balance)
        : account_number(acc_num), balance(initial_balance) {}
    
    bool withdraw(double amount) {
        if (validate_amount(amount)) {
            balance -= amount;
            return true;
        }
        return false;
    }
    
    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }
    
    double get_balance() const {
        return balance;
    }
};

int main() {
    BankAccount account("12345", 1000);
    account.deposit(500);
    account.withdraw(200);
    std::cout << "Balance: " << account.get_balance() << std::endl;
    
    // account.balance = -5000;  // ОШИБКА! private
    // Эта инкапсуляция предотвращает некорректное изменение состояния
    return 0;
}

Преимущества:

  • Контроль доступа к критичным данным
  • Валидация данных при записи
  • Возможность изменить реализацию без влияния на клиентский код
  • Предотвращение неконтролируемых изменений состояния

2. Наследование (Inheritance)

Наследование — механизм создания новых классов на основе существующих, позволяя переиспользовать код и выстраивать иерархии типов.

#include <iostream>
#include <cmath>

class Shape {  // Базовый класс
public:
    virtual ~Shape() = default;
    virtual double area() const = 0;        // Чистая виртуальная функция
    virtual void print_info() const = 0;
    virtual std::string get_type() const { return "Unknown"; }
};

class Circle : public Shape {  // Наследует от Shape
private:
    double radius;
public:
    Circle(double r) : radius(r) {}
    
    double area() const override {
        return M_PI * radius * radius;
    }
    
    void print_info() const override {
        std::cout << "Circle with radius: " << radius << std::endl;
    }
    
    std::string get_type() const override {
        return "Circle";
    }
};

class Rectangle : public Shape {  // Наследует от Shape
private:
    double width, height;
public:
    Rectangle(double w, double h) : width(w), height(h) {}
    
    double area() const override {
        return width * height;
    }
    
    void print_info() const override {
        std::cout << "Rectangle: " << width << "x" << height << std::endl;
    }
    
    std::string get_type() const override {
        return "Rectangle";
    }
};

int main() {
    // Полиморфизм через базовый класс
    Shape* shapes[] = {
        new Circle(5),
        new Rectangle(3, 4)
    };
    
    for (Shape* shape : shapes) {
        shape->print_info();
        std::cout << "Area: " << shape->area() << std::endl;
    }
    
    for (Shape* shape : shapes) delete shape;
    return 0;
}

Виды наследования:

  • public: Сохраняет public/protected члены
  • protected: Превращает public в protected
  • private: Скрывает все члены базового класса

3. Полиморфизм (Polymorphism)

Полиморфизм — способность объекта принимать много форм. В C++ реализуется через виртуальные функции и динамическое связывание.

#include <iostream>
#include <vector>
#include <memory>

class Animal {
public:
    virtual ~Animal() = default;
    virtual void speak() const = 0;  // Чистая виртуальная функция
};

class Dog : public Animal {
public:
    void speak() const override {
        std::cout << "Woof!" << std::endl;
    }
};

class Cat : public Animal {
public:
    void speak() const override {
        std::cout << "Meow!" << std::endl;
    }
};

class Bird : public Animal {
public:
    void speak() const override {
        std::cout << "Tweet!" << std::endl;
    }
};

void make_sound(const Animal& animal) {
    // Полиморфный вызов — реальный тип определяется в runtime
    animal.speak();
}

int main() {
    std::vector<std::unique_ptr<Animal>> animals;
    animals.push_back(std::make_unique<Dog>());
    animals.push_back(std::make_unique<Cat>());
    animals.push_back(std::make_unique<Bird>());
    
    for (auto& animal : animals) {
        make_sound(*animal);  // Каждый говорит по-своему
    }
    
    return 0;
}

Виды полиморфизма:

  • Виртуальные функции: Динамический полиморфизм (runtime)
  • Шаблоны/Templates: Статический полиморфизм (compile-time)
  • Перегрузка операторов: Parametric полиморфизм

4. Абстракция (Abstraction)

Абстракция — выделение существенных характеристик объекта и скрытие несущественных деталей.

#include <iostream>
#include <vector>

// Абстрактный интерфейс
class PaymentProcessor {
public:
    virtual ~PaymentProcessor() = default;
    virtual bool process_payment(double amount) = 0;
    virtual bool refund(double amount) = 0;
};

// Конкретная реализация 1
class CreditCardProcessor : public PaymentProcessor {
private:
    std::string card_number;
    void validate_card() { /* ... */ }
    void encrypt_card() { /* ... */ }
public:
    CreditCardProcessor(const std::string& card) : card_number(card) {}
    
    bool process_payment(double amount) override {
        validate_card();
        encrypt_card();
        // Детали интеграции с платёжной системой скрыты
        std::cout << "Processing credit card payment: $" << amount << std::endl;
        return true;
    }
    
    bool refund(double amount) override {
        std::cout << "Refunding to credit card: $" << amount << std::endl;
        return true;
    }
};

// Конкретная реализация 2
class PayPalProcessor : public PaymentProcessor {
private:
    std::string email;
public:
    PayPalProcessor(const std::string& e) : email(e) {}
    
    bool process_payment(double amount) override {
        std::cout << "Processing PayPal payment for " << email
                  << ": $" << amount << std::endl;
        return true;
    }
    
    bool refund(double amount) override {
        std::cout << "Refunding via PayPal: $" << amount << std::endl;
        return true;
    }
};

// Клиентский код работает с абстракцией, не знает деталей реализации
class OnlineStore {
private:
    PaymentProcessor* processor;
public:
    OnlineStore(PaymentProcessor* p) : processor(p) {}
    
    bool checkout(double total) {
        return processor->process_payment(total);
    }
    
    bool process_return(double amount) {
        return processor->refund(amount);
    }
};

int main() {
    CreditCardProcessor cc("4111-1111-1111-1111");
    PayPalProcessor pp("user@paypal.com");
    
    OnlineStore store1(&cc);
    OnlineStore store2(&pp);
    
    store1.checkout(99.99);   // Обрабатывает кредитной картой
    store2.checkout(49.99);   // Обрабатывает через PayPal
    
    // Клиентский код не зависит от конкретной реализации платежа
    return 0;
}

Интеграция принципов: Пример

#include <iostream>
#include <vector>
#include <memory>

// Абстракция и полиморфизм
class DatabaseConnection {
public:
    virtual ~DatabaseConnection() = default;
    virtual bool connect() = 0;
    virtual bool disconnect() = 0;
    virtual bool execute_query(const std::string& query) = 0;
};

// Инкапсуляция
class MySQLConnection : public DatabaseConnection {
private:  // Скрытая реализация
    std::string host, user, password;
    bool connected;
    
    void initialize_connection() { /* ... */ }
public:
    MySQLConnection(const std::string& h, const std::string& u, const std::string& p)
        : host(h), user(u), password(p), connected(false) {}
    
    bool connect() override {
        initialize_connection();
        connected = true;
        std::cout << "Connected to MySQL" << std::endl;
        return true;
    }
    
    bool disconnect() override {
        connected = false;
        return true;
    }
    
    bool execute_query(const std::string& query) override {
        if (!connected) return false;
        std::cout << "Executing: " << query << std::endl;
        return true;
    }
};

// Наследование и инкапсуляция
class UserRepository {
private:
    std::unique_ptr<DatabaseConnection> db;
public:
    UserRepository(std::unique_ptr<DatabaseConnection> database)
        : db(std::move(database)) {}
    
    bool save_user(const std::string& name) {
        return db->execute_query("INSERT INTO users (name) VALUES ('" + name + "')");
    }
};

int main() {
    auto db = std::make_unique<MySQLConnection>("localhost", "root", "password");
    db->connect();
    
    UserRepository repo(std::move(db));
    repo.save_user("John Doe");
    
    return 0;
}

Заключение

Четыре принципа ООП в C++:

ПринципНазначениеМеханизм
ИнкапсуляцияСкрыть внутренние деталиprivate/public/protected
НаследованиеПереиспользовать код: public/protected/private
ПолиморфизмРазные поведения одного интерфейсаvirtual функции
АбстракцияРаботать с интерфейсом, скрыть реализациюЧистые виртуальные функции

Применение этих принципов делает код более масштабируемым, тестируемым и поддерживаемым.

Какие основные принципы ООП? | PrepBro