воскресенье, 25 декабря 2016 г.

Объектно-ориентированное программирование (ООП) в C++

Объектно-ориентированное программирование (ООП) — подход к программированию, при котором основными концепциями являются понятия объектов и классов.
Класс — это определяемый разработчиком тип данных.
Тип данных характеризуется:

  1. Способом хранения и представления этих данных.


  2. Назначением этих данных (профилем их использование).


  3. Набором действий, которые над этими данными могут производится.

Например, тип int предназначен для хранения целых чисел и подразумевает ряд операция над ними (+,-,*,/,% и пр.).
Класс — это тип, описывающий устройство объектов, их поведение и способ представления.
Объект — сущность обладающая определённым поведением и способом представления, т. е. относящееся к классу (говорят, что объект — это экземпляр класса, если он к нему относится).
Класс можно сравнить с чертежом, согласно которому создаются объекты. Обычно классы разрабатывают таким образом, чтобы их объекты соответствовали объектам предметной области решаемой задачи.
Описание класса начинается со служебного слова class, вслед за которым указывается имя класса. Затем в блоке следует описание класса и после закрывающей скобки блока ставится точка с запятой.
Описание класса состоит из полей и методов.
Поля (или свойства, в рамках C++ это можно считать синонимом) описывают то, какие данные смогут хранить экземпляры класса (т.е. объекты). Конкретные значения сохраняются уже внутри объектов. Поля объявляются в теле класса.
К полям внутри класса можно обращаться непосредственно по именам полей.
Методы класса — это функции, которые смогут применяться к экземплярам класса. Грубо говоря, метод — это функция объявленная внутри класса и предназначенная для работы с его объектами.
Методы объявляются в теле класса. Описываться могут там же, но могут и за пределами класса (внутри класса в таком случае достаточно представить прототип метода, а за пределами класса определять метод поставив перед его именем — имя класса и оператор ::).
Методы и поля входящие в состав класса называются членами класса. При этом методы часто называют функциями-членами класса.
Пример:

class Complex {
  double img;
  double real;
};


В примере описан класс Complex с двумя полями img и real.

Абстракция данных

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

Ключевые черты ООП


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


  2. Наследование — это порождение нового класса-потомка от уже существующего класса-родителя. Класс-родитель называют также супер-классом, а класс-потомок — подклассом. Наследование происходит с передачей всех или некоторых полей и методов от класса-родителя к классу-потомку. В процессе наследования возможно, при необходимости, добавлять новые свойства и методы. Набор классов, связанных отношением наследования, называют иерархией.


  3. Полиморфизм — это явление, при котором функции (методу) с одним и тем же именем соответствует разный программный код (полиморфный код) в зависимости от того, в каком контексте он вызывается (объектами какого класса или с какими параметрами).

Уровни доступа к членам класса

По уровню доступа все члены класса делятся на открытые (public), закрытые (private) и защищённые (protected).
Перед объявлением членов внутри класса ставятся соответствующие ключевые слова. Если такое слово не поставлено, то считается, что член объявлен с уровнем private. В примере выше класса Complex, соответственно, оба поля имеют уровень доступа private.
Члены объявленные как private доступны только внутри класса.
Члены объявленные как protected доступны внутри класса и внутри всех его потомков.
Члены объявленные как public доступны как внутри, так вне класса (в том числе в потомках).


Доступность членов класса в зависимости от уровня доступа


private


protected


public
Внутри класса+++
Внутри потомка класса-++
В несвязанной с классом части программы--+
Методы объявленные в открытой части класса называются его интерфейсом
Пример объявления различных уровней доступа:

class Complex {
  private: // Закрытая часть класса, её элементы доступны только внутри класса
    double img;
  public: // Открытая часть класса, её элементы доступны везде
    double real;
    double getImg() { // Через этот метод мы сможем получить значение закрытого поля
      return img;     // Поле закрытое, но метод открытый
    };
};


Интерфейс класса

Все методы класса, находящиеся в его открытой части (с уровнем доступа public) называют интерфейсом класса
Интерфейс предназначен для взаимодействия класса с остальной программой. Зная методы интерфейса и их назначение можно использовать класс, не вникая в его внутреннее устройство. Соответственно, интерфейс реализует принцип инкапсуляции.

Конструктор и деструктор

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

Конструктор по умолчанию

Конструктор по умолчанию — это конструктор без параметров.
Если он не задан явно и при этом не создано других конструкторов с параметрами, то конструктор по умолчанию создастся автоматически. При этом все свойства нового объекта не будут никак проинициализрованы (получат «мусорные» значения из памяти).
Пример:

class Complex {
    private: // Закрытая часть класса
        double real; // Поле, действительная часть
        double img; // Поле, мнимая часть
    public: // Открытая часть класса
        void printComplex() { // Этот метод мы сможем вызывать за приделами класса
            cout &lt< real &lt< " + " &lt< img &lt< 'i' &lt< endl; // Выводим поля
        }
};

int main() {
    Complex a; // Работает конструктор по умолчанию,
    Complex b; // поля получают мусорные значения
    a.printComplex(); // Выводим первый и второй объекты
    b.printComplex(); // с помощью созданного метода printComplex()
    return 0;
}


В представленном примере отсутствует явно заданный конструктор, поэтому будет создан конструктор по умолчанию. Мы можем явно задать конструктор по умолчанию и обязаны это сделать, когда у нас имеется какой-либо конструктор с параметрами.
Пример класса с двумя конструкторами (первый из них — без параметров):

class Complex {
    private:
        double real; // Действительная часть
        double img; // Мнимая часть
    public:
        Complex() {
            real = 0;
            img = 0;
        }
        Complex(double a, double b) {
            real = a;
            img = b;
        }
        void printComplex() {
            cout &lt< real &lt< " + " &lt< img &lt< 'i' &lt< endl;
        }
};

int main() {
    Complex a;
    Complex b(3.14, 2.71);
    a.printComplex();
    b.printComplex();
    return 0;
}


При создании объекта мы должны либо в круглых скобках указать параметры, чтобы заработал нужный конструктор (как для объекта b), либо не указывать ничего, чтобы использовался конструктор по умолчанию (как для объекта a).


видеокурс по объектно-ориентированному программированию смотрим здесь

Комментариев нет:

Отправить комментарий