4. Наследование в С++.

Построение иерархии классов. Выделение общей части группы классов. Расщепление классов.

Наследование

Наследование — это один из фундаментальных принципов объектно-ориентированного программирования (ООП), который позволяет создавать новые классы на основе уже существующих. Это упрощает создание сложных систем, повторно используя код и избегая избыточности.

Построение иерархии классов

  1. Базовые и производные классы

    • Базовый класс (суперкласс) предоставляет общие характеристики, которые могут быть унаследованы другими классами.

    • Производный класс (подкласс) расширяет или модифицирует функциональность базового класса.

    class Base {
    public:
        void baseMethod() {
            // Базовая функциональность
        }
    };
    
    class Derived : public Base {
    public:
        void derivedMethod() {
            // Дополнительная функциональность
        }
    };
  2. Типы наследования

    • public: открытое наследование, при котором все public и protected члены базового класса сохраняют свои уровни доступа в производном классе.

    • protected: защищенное наследование, при котором public члены становятся protected в производном классе.

    • private: закрытое наследование, при котором все public и protected члены становятся private в производном классе.

    class PublicDerived : public Base {};
    class ProtectedDerived : protected Base {};
    class PrivateDerived : private Base {};

Выделение общей части группы классов

  1. Абстрагирование общих черт

    • Определение общих характеристик и поведения в базовом классе, которые будут использоваться всеми производными классами.

    • Это способствует повторному использованию кода и упрощает модификацию.

    class Animal {
    public:
        void eat() {
            // Общая функциональность для всех животных
        }
    };
    
    class Dog : public Animal {
    public:
        void bark() {
            // Специфическая функциональность для собак
        }
    };
    
    class Cat : public Animal {
    public:
        void meow() {
            // Специфическая функциональность для кошек
        }
    };
  2. Преимущества выделения общей части

    • Уменьшение дублирования кода: общие методы и свойства определяются один раз в базовом классе.

    • Упрощение поддержки и расширения кода: изменения в базовом классе автоматически применяются к производным классам.

Расщепление классов

  1. Определение расщепления

    • Расщепление (деление) классов предполагает разделение одного класса на несколько специализированных подклассов.

    • Это помогает поддерживать код более организованным и облегчает его понимание.

  2. Пример расщепления классов

    • Рассмотрим класс, который сначала включает в себя множество различных методов и свойств, но затем разбивается на более специализированные классы.

    class ComplexClass {
    public:
        void methodA() {
            // Общий метод
        }
        void methodB() {
            // Метод для конкретного случая
        }
    };
    
    class SimplifiedBase {
    public:
        void methodA() {
            // Общий метод
        }
    };
    
    class SpecializedDerived : public SimplifiedBase {
    public:
        void methodB() {
            // Специализированный метод
        }
    };
  3. Преимущества расщепления классов

    • Улучшение управляемости кода: меньшие, специализированные классы проще понимать и поддерживать.

    • Повышение гибкости: изменения в одном из специализированных классов не влияют на другие.

Неявное преобразование

ВАЖНО! В языке С++ происходит неявное преобразование от указателя объекта производного класса к указателю на объект базового класса. То же самое касается ссылок.

Рассмотрим пример ниже:

class A
{
public:
   A();
   ~A(); // не может быть const, volatile, но может быть virtual.
};

A *p = new B; // с помощью указателя можем подменять базовый класс на производный
B obj &alias = obj; // ссылка на производном приводит ссылки на базовый класс

Last updated