Найти в Дзене
Геннадий Шушпанов

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

Все окружающее нас -- объекты. Мы живем среди них, мы их создаем и используем. Наши действия, мысли идеи, понятия и фантазии тоже объекты. Поэтому программисты, всегда работали с объектами. Даже тогда, когда алгоритмические языки поддерживали лишь простые переменные и массивы, а для алгоритмов были лишь процедуры. Рассмотрим пример. Предположим у нас есть набор прямоугольников и кругов. и нам надо перемещать их. Нет записей? Не беда. Уложим координаты фигур в массивы X, Y, тогда индекс в этих массивах будет определять конкретную фигуру. Процедура перемещения в этом случае может выглядеть так: C Перемещение фигуры SHAPE на DX, DY
. . . SUBROUTINE SHMOVE(SHAPE, X, Y, DX, DY, N)
. . . DIMENSION X(N), Y(N)
. . . X(SHAPE) = X(SHAPE) + DX
. . . Y(SHAPE) = Y(SHAPE) + DY
. . . RETURN
. . . END Как видим, процедурный подход к программированию не мешает использовать объекты. Да, порой сигнатуры процедур выглядели устрашающе. Возможно поэтому решили ввести более компактный синтаксис. Это укладыва
Оглавление

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

Все окружающее нас -- объекты. Мы живем среди них, мы их создаем и используем. Наши действия, мысли идеи, понятия и фантазии тоже объекты. Поэтому программисты, всегда работали с объектами. Даже тогда, когда алгоритмические языки поддерживали лишь простые переменные и массивы, а для алгоритмов были лишь процедуры. Рассмотрим пример. Предположим у нас есть набор прямоугольников и кругов. и нам надо перемещать их. Нет записей? Не беда. Уложим координаты фигур в массивы X, Y, тогда индекс в этих массивах будет определять конкретную фигуру. Процедура перемещения в этом случае может выглядеть так:

C Перемещение фигуры SHAPE на DX, DY
. . . SUBROUTINE SHMOVE(SHAPE, X, Y, DX, DY, N)
. . . DIMENSION X(N), Y(N)
. . . X(SHAPE) = X(SHAPE) + DX
. . . Y(SHAPE) = Y(SHAPE) + DY
. . . RETURN
. . . END

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

Сравнивая объекты мы можем заметить, что все они имеют идентичность, состояние и поведение. Идентичность позволяет нам различать объекты, состояние определяется значениями их атрибутов, а поведение определяет, что мы можем с ними делать.

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

Абстракции

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

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

Классы

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

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

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

Полиморфизм

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

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

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

Сокрытие реализации.

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

Сгенерировано в Шедеврум
Сгенерировано в Шедеврум