Классы ООП. Объектно-ориентированное программирование

Подписаться Редактировать статью

Термины "объект" и "класс" знакомы каждому человеку. Однако для компьютерщиков они имеют свой подтекст. Это основные понятия в объектно-ориентированном программировании. Классы - определяемый разработчиком тип данных, который характеризуется способом их передачи и хранения, профилем использования и набором действий, которые могут с ними производиться. Они отличаются тем, что могут реализовываться в качестве интерфейса.

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

Опытные разработчики хорошо знают языки COBOL и C. Написанные на них программы представляли собой последовательность пошаговых инструкций. Они использовали процедуры и функции для того, чтобы сделать программу модульной. Эта парадигма была сосредоточена на логике, а не на данных, и на методах их объединения.

Объектно ориентированное программирование классы

Современные языки программирования Delphi, Java, C# и другие следуют объектно-ориентированному подходу. При этом важность отдается данным, а не просто написанию инструкций для выполнения задачи. Объект - это вещь или идея, которую вы хотите смоделировать. Им может быть что угодно, например, сотрудник, банковский счет, автомобиль, различные предметы обстановки и так далее.

Понятие объектно-ориентированного программирования (ООП) неотъемлемо связано со следующими критериями:

  • Абстракция.
  • Инкапсуляция.
  • Наследование.
  • Полиморфизм.

Рассмотрим каждый из них более подробно.

Абстракция

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

Мы стараемся выборочно сосредоточиться только на тех вещах, которые важны для нас (в жизни) или для нашего модуля (в программировании). Изменение одного независимого модуля не влияет на другие. Единственное, что нужно знать, - это то, что он нам дает. Человек, который использует этот модуль, не должен беспокоиться о том, как задача решается, что именно происходит в фоновом режиме.

Конструктор класса С

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

Инкапсуляция

Эта концепция тесно связана с абстракцией. Инкапсуляция - это раскрытие решения проблемы, не требующее от пользователя полного понимания ее предметной области. Она связывает данные и поведение в единое целое и не позволяет клиенту или пользователю модуля узнать о внутреннем представлении, в котором реализовано поведение абстракции.

Система объектно ориентированного программирования

Данные недоступны напрямую. Доступ к ним осуществляется через определенные функции. Скрытие внутренних элементов объекта защищает его целостность, не давая пользователям переводить внутренние данные компонента в недопустимое или несовместимое состояние.

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

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

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

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

Полиморфизм

Эта концепция позволяет расширять компьютерные системы за счет создания новых специализированных объектов. Одновременно она дает возможность текущей версии взаимодействовать с новой, не обращая внимания на ее конкретные свойства.

Например, если стоит задача написать сообщение на листе бумаги, можно использовать ручку, карандаш, маркер или перо. Достаточно того, чтобы инструмент мог уместиться в руке и имел возможность оставлять след при соприкосновении с бумагой. Получается, что определенные действия человека делают надпись на листе, а какой при этом используется инструмент, это не столь важно для передачи информации.

Другим примером полиморфизма в системе объектно-ориентированного программирования являются самолет и космический челнок, которые можно назвать летающими объектами. Как именно они перемещаются в пространстве? Разумеется, в их работе есть большая разница. То есть способы реализации их движения неодинаковые. Однако с точки зрения зрителя оба объекта летят.

Реализация ООП

Наследование является одним из способов достижения полиморфизма, когда поведение, определенное в унаследованном классе, может быть переопределено путем написания пользовательской реализации метода. Это называется переопределением (полиморфизмом времени компиляции).

Существует еще одна форма полиморфизма, называемая перегрузкой, при которой наследование не учитывается. Имя метода будет таким же, но аргументы в методе разные.

Особенности понятий "класс" и "объект"

Чтобы начать работать с объектно-ориентированным программированием, нам нужно разобраться, что такое класс ООП и объект. Важно понимать разницу между ними. Класс - это план для создания объекта. Он определяет атрибуты и поведение. Это похоже на инженерный чертеж дома. Объект является экземпляром класса. Вот такая между ними разница. В примере ниже показано, каким образом объявляются класс "TForml" и переменная "Forml" на языке программирования Delphi:

type
TForml = class(TForm)
Buttonl: TButton;
procedure ButtonlClick(Sender: TObject);
end;
var
Forml: TForml;

Если мы хотим смоделировать в нашей программе, например, автомобиль, то должны определить его атрибуты: модель, топливо, марку, цвет, его поведение, а также так называемые методы: запуск двигателя, торможение, ускорение и так далее. Хорошо видно, что указанные показатели характерны не только для одной марки или модели транспортного средства.

При объектно-ориентированном подходе мы пытаемся обобщить наш объект (машину), утверждая, что тот, который мы собираемся смоделировать в нашей программе, будет иметь некоторое количество атрибутов и методов. Могут быть и другие показатели и характеристики транспортного средства, но нам достаточно перечисленных, чтобы понять, как работает класс в ООП.

Когда мы используем эти данные, мы создаем автомобиль с конкретными параметрами. Программируя один и тот же объект (машину), мы можем взять разные характеристики, как показано в таблице ниже:

Объект 1 Объект 2
модель: Ваз 2107 модель: Ваз 2109
топливо: Бензин топливо: Дизель
цвет: Красный цвет: Зеленый
метод запуска двигателя: Start () метод запуска двигателя: Start ()
метод торможения: Break () метод торможения: Break ()
метод ускорения: Acceleration () метод ускорения: Acceleration ()

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

Что такое класс в ООП

Классы ООП состоят из элементов различных типов:

  1. Поля данных: хранят состояние класса с помощью переменных и структур.
  2. Методы: подпрограммы для манипулирования указанными данными.
  3. Некоторые языки допускают третий тип - свойства. Это что-то среднее между первыми двумя.

Методы

Поведение класса или его экземпляров определяется с помощью методов. Это подпрограммы с возможностью оперировать объектами. Данные операции могут изменить состояние объекта или просто предоставить способы доступа к нему.

Существует множество методов. Их поддержка зависит от языка. Одни создаются и вызываются кодом программиста, другие (специальные, такие как конструкторы, деструкторы и операторы преобразования) создаются и вызываются сгенерированным компилятором кодом. Язык может позволить программисту определять эти специальные методы.

Интерфейс

Это определение группы абстрактных действий. Он выясняет, какое поведение должен демонстрировать определенный объект без указания того, как оно должно быть реализовано.

Объект может иметь несколько ролей, а пользователи имеют возможность использовать его с разных точек зрения. Например, объект типа "человек" может иметь роли:

  • Солдата (с поведением "стреляй в противника").
  • Мужа (с поведением "люби свою жену").
  • Налогоплательщика (с поведением "плати налоги") и так далее.

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

Что такое ООП

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

Хорошим примером являются кнопки на передней панели телевизора. Можно сказать, что они - это интерфейс между пользователем и электропроводкой на другой стороне корпуса прибора. Человек нажимает кнопку питания для включения и выключения электроприбора. В этом примере конкретный телевизор является экземпляром, каждый метод представлен кнопкой, а все вместе они составляют интерфейс. В своей наиболее распространенной форме он представляет собой спецификацию группы связанных методов без их реализации.

Конструктор

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

Следующий пример объясняет концепцию конструктора класса на C++ (распространенном языке программирования):

#include <iostream>
using namespace std;

class Line {
public:
void setLength( double len );
double getLength( void );
Line(); // Объявление конструктора
private: double length;
};

// Определение функций, включая конструктор

Line::Line(void) {
cout << "Объект создан" << endl;
}

void Line::setLength( double len ) {
length = len;
}

double Line::getLength( void ) {
return length;
}

// Тело программы

int main() {
Line line;

// Длина строки

line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}

Когда приведенный выше код компилируется и выполняется, он дает следующий результат:

Объект создан

Length of line: 6

Деструктор

Это специальная функция класса, которая уничтожает объект, как только заканчивается область его действия. Деструктор автоматически вызывается компилятором, когда объект выходит из области видимости.

Синтаксис для деструктора такой же, как и для конструктора, однако имя класса используется в данном случае для него со знаком тильды "~" в качестве префикса.

Следующий пример на языке C++ объясняет понятие деструктора:

#include <iostream>
using namespace std;

class Line {
public: void setLength( double len );
double getLength( void );
Line(); // Объявление конструктора
~Line(); // Объявление деструктора
private: double length;
}

// Определение функций, включая конструктор

Line::Line(void) {
cout << "Объект создан" << endl;
}

Line::~Line(void) {
cout << "Объект удален" << endl;
}

void Line::setLength( double len ) {
length = len;
}

double Line::getLength( void ) {
return length;
}

// Тело программы

int main() {
Line line;

// Длина строки

line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;

}

Когда приведенный выше код скомпилирован и выполнен, он даст следующий результат:

Объект создан

Length of line: 6

Объект удален

В чем заключаются достоинства классов

Преимущества организации программного обеспечения в классы объектов делятся на три категории:

  • Быстрое развитие.
  • Простота обслуживания.
  • Повторное использование кода и дизайна.
Основные понятия объектно ориентированного программирования

Классы и ООП в целом способствуют быстрой разработке, поскольку они уменьшают смысловой разрыв между кодом и пользователями. Это по достоинству оценили многие программисты. Благодаря этой системе аналитики могут общаться как с разработчиками, так и с пользователями, используя один и тот же словарь, говоря об учетных записях, клиентах, счетах и ​​так далее.

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