Файл: Основные понятия объектно-ориентированного программирования (История создания объектно-ориентированного программирования).pdf
Добавлен: 28.03.2023
Просмотров: 107
Скачиваний: 2
Некоторые элементы современного объектно-ориентированного программирования
Время не стоит на месте, да и времени с момента появления ООП уже прошло довольно много, поэтому не стоит удивляться, что сегодня словарь по объектно-ориентированному программированию серьезно разросся. Вот некоторые новые термины и понятия, связанные с ООП.
События. Специальный вид объектов, создаваемый для оповещения одних объектов о событиях, происходящих с другими объектами. В разных языках программирования механизм событий реализуется по-разному: где-то с помощью специальных синтаксических конструкции, а где-то силами базовых средств ООП[14].
Универсальный тип. Концепция универсальных типов не связана непосредственно с концепцией ООП, но она является причиной появление таких элементов, как универсальный класс, универсальный метод, универсальное событие и т.д. Универсальный тип – это тип, параметризованный другим типом (набором типов)[15]. Кем является этот тип-параметр в контексте проектирования универсального типа неизвестно, хотя есть возможность ограничить значения типов-параметров, заставив их быть производными от конкретного класса или реализовывать определенные интерфейсы. В качестве примера можно привести универсальный класс сортировки последовательности элементов, где тип элемента в последовательности заранее неизвестен. При проектировании такого класса важно указать, что тип-параметр должен поддерживать операцию сравнения[16]. При создании объектов универсальных типов параметр указывается явно, например целочисленный или строковый тип, а сам объект начинает себя вести так, как если бы это был экземпляр класса, созданный специально для сортировки целых чисел или строк[17].
Исключения. Еще один специальный вид объектов, поддерживаемый встроенным в конкретный язык программирования механизмом обработки ошибок и исключительных ситуаций. Исключения, помимо кода ошибки, содержат ее описание, возможные причины возникновения и стек вызовов методов, имевший место до момента возникновения исключения в программе.
Объектно-ориентированное программирование постоянно развивается, порождая новые парадигмы, такие как аспектно-ориентированное, субъектно-ориентированное и даже агентно-ориентиванное программирование[18]. Нужно отметит, что лавры ООП не дают покоя остальным теоретикам, и они спешат предложить свои варианты его совершенствования и расширения.
Прототипное программирование исключает понятие класса, заменяя его прототипом – образцом объекта[19]. Таким образом, в прототипно-ориентированном языке нет понятия типа объекта, а есть понятие образец или прототип. Прототип – это экземпляр объекта, по которому создаются другие экземпляры, копируя (клонируя) его члены. В JavaScript не описывают поля и методы класса, а создается сначала пустой объект, а потом добавляют ему нужные поля и методы (в JavaScript метод можно определить и добавить к объекту динамически). Точно также создаются и прототипы, на которые потом ссылаются другие объекты, как на свой прообраз. Если у объекта не находится какого-то метода или поля, которое указано в месте вызовы, то оно ищется среди членов его прототипа.
Глава 3. Свойства, достоинства и недостатки ООП
3.1 Основные свойства ООП
Есть сразу 3 основных принципа, которые составляют основу ООП.
Под инкапсуляцией понимается «свойство, благодаря которому разработчику, использующему определенный строительный блок (код), не нужно знать, как он на самом деле реализован и работает для корректного использования этого строительного блока[20]». Другое преимущество инкапсуляции заключается в том, что разработанную программу легче модифицировать, поскольку при сохранении интерфейса класса можно менять его реализацию, и это не затронет внешний программный код (код клиента)[21].
Покажем несколько примеров, которые помогут разобраться с каждым из представленных принципов. Инкапсуляция - это своеобразная защита информации от внешних пользователей[22].
Чтобы сразу же стало понятно что это, приведем реальный пример.
Необходимо совершить определенный звонок, пользуясь своим телефоном - это не требует дополнительных познаний в сегменте сотовой связи, размещении вышек и прочего. Достаточно более простых знаний - номера выбранного абонента и средств, которые позволят совершить запланированный звонок.
Инкапсуляция дает внешним пользователям(программистам) доступ к методам, которые необходимы им для работы с программой, при этом, все важные внутренние методы остаются недоступными, они попросту не нужны внешним пользователям.
Приведем в качестве примера инкапсуляции следующее:
class Human {
private $words;
private $sex;
public function setSex($sex) {
if($sex == "male") {
$this->sex = "male";
} else if($sex == "female") {
$this->sex = $sex;
} else {
echo "Error. Set only male or female sex";
}
}
public function setWords($words) {
$this->words = $words;
}
public function getWords() {
return $this->words;
}
public function sayIt() {
return $this->getWords();
}
}
$human = new Human();
$human->setSex("male");
$human->setWords("Hi!");
echo $human->sayIt();
Здесь показан Human, в данном классе добавили “sex” (пол), которое сделали приватным - это не позволит внешним пользователям получить к нему доступ.
Вот как будет выглядеть попытка получения доступа к данному поля вне самого класса:
$human->sex = "11"; Fatal error: Cannot access private property Human::$sex
Инкапсуляция является весьма полезным свойством ООП и применяется достаточно не редко. Инкапсуляция является невероятно полезной, если созданием определенного проекта занимается целая группа специалистов[23]. Каждый программист будет работать с определенным классом и методами, при этом, не создавая помех в работе другим специалистам.
Наследование (или наследственность) — определение объекта и его дальнейшее использование для построения иерархии порожденных объектов с возможностью для каждого порожденного объекта, относящегося к иерархии, доступа к коду и данным всех порождающих объектов[24].
Как структурная, так и объектно-ориентированная методологии ставят перед собой цель построения дерева иерархии взаимосвязей между объектами[25]. При этом структурная иерархия формируется по простому принципу разделения целого на составляющие, тогда как в случае объектно-ориентированной иерархии отражается наследование свойств вышележащих типов объектов нижележащим типам объектов.
Наследственность в ООП — это его основа. Следует понимать, что потомок — класс, от которого происходят другие классы, наследует свойства предка — класса, который происходит либо порожден из другого класса. Следовательно, потомок всегда «знает», какими он обладает свойствами, а предок не может «знать» свойства своего потомка, поскольку не может «знать» те свойства, которые будут добавлены в новый класс[26]. Данный метод наследования и принят в объектно-ориентированных языках.
Именно наследование дает возможность повторно использовать уже существующий код. С целью применения существующего кода, программист создает новый класс на базе уже существующих классов[27]. В итоге, наследование выполняет две функции: предотвращение дублирования кода, развитие работы в нужном направлении. Отношения между родительскими классами и его потомками именуется термином «Иерархия наследования»[28].
К примеру -каждый человек обладает определенным набором функций при рождении, это так называемый базовый набор - дыхание, переваривание пищи, крик. Любой человек является соединением огромного количества цепочек генов - от самых первых предков и до кровных родителей. Если рассматривать ООП - то в данном случае свойство наследования ничем не отличается от простой жизни.
Существуют родительские классы с базовым функционалом - при создании нового класса, не потребуется создание новых базовых навыков, он изначально унаследует "базу" родительского класса. Это существенно упрощает работу программистам. Есть слово "extends", которое обозначает наследование.
/* Родительский класс Human */
class Human {
private $name;
/* Конструктор (в нем мы задаем поле $name при создании экземпляра класса) */
public function __construct($name) {
$this->name = $name;
}
/* Метод say(). Предполагаем, что Human изначально может говорить */
public function say() {
echo "Меня зовут ".$this->name." и ";
}
}
/* Класс Мужчина. Ключевым словом extends мы наследуем родителя Human */
class Man extends Human {
public function beard() {
echo "у меня растет борода";
}
}
/* Класс Женщина. Ключевым словом extends мы наследуем родителя Human */
class Women extends Human {
public function bearChildren() {
echo "я рожаю детей";
}
}
/* Создаем экземпляр класса Man и вызываем методы. */
$man = new Man("Sergey");
$man->say();
$man->beard();
/* Создаем экземпляр класса Women и вызываем методы. */
$women = new Women("Maria");
$women->say();
$women->bearChildren();
Что же мы увидим в результате:
Меня зовут Sergey и у меня растет борода
Меня зовут Maria и я рожаю детей
Если рассматривать созданные классы - они оба обладают базовым набором навыков, но есть свои отличия - "Мужчина" отращивает бороду, "Женщина" рожает ребенка.
Метод под названием __construct - это конструктор класса.
Полиморфизм — присваивание действию одного имени, которое затем совместно используется вниз и вверх по иерархии объектов, причем каждый объект иерархии выполняет это действие способом, именно ему подходящим[29]. В объектно-ориентированной разработке это относится к сущностям (элементам структур данных), способным в процессе выполнения присоединяться к объектам разных типов[30].
Полиморфизм дает возможность применения одних и тех же функций для решения различных задач и находит свое отражение в том, что под одним именем содержатся разные действия, наполнение которых зависит от типа объекта. Производные одного базового класса считаются полиморфными.[31] Это подразумевает, что им присущи как общие характеристики, так и собственные свойства.
Касательно средств, которые связаны с возможностью реализации полиморфизма, то следует упомянуть следующие виды методов в ООП:
-
- Статические методы класса включаются в код программы в процессе ее компиляции. Таким образом, до запуска программы уже известно, какая процедура будет вызвана в определенной точке.
- Виртуальные методы, которые подключаются к основному коду на этапе выполнения программы и дают возможность определить тип и конкретизировать экземпляр объекта в процессе исполнения, а затем вызвать методы этого объекта. Данный механизм обеспечивает полиморфизм и именуется также поздним связыванием.
Полиморфизм дает возможность создавать множественные определения для операций и функций[32]. Какое именно определение будет использоваться, зависит от контекста программы. ООП предоставляет возможности, связанные с полиморфизмом, такие как: шаблоны функций, перегрузка функций, перегрузка операций, использование виртуальных методов, шаблоны классов[33]. Перегрузка операций позволяет применять для собственных классов те же операции, что используются для встроенных типов C++. Виртуальные методы обеспечивают возможность выбрать на этапе выполнения нужный метод среди одноименных методов базового и производного классов. Шаблоны классов позволяют описать классы, инвариантные относительно типов данных.
Пример полиморфизма:
/* Это интерфейс Say */
interface Say {
public function say();
}
/* Это абстрактный класс Human имплементирующий интерфейс Say */
abstract class Human implements Say{
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
/* Класс Man наследуют класс Human и обязан реализовать метод say() */
class Man extends Human {
public function __construct($name) {
parent::__construct($name);
}
public function beard() {
echo "у меня растет борода";
}
public function say() {
echo "У меня мужской голос, меня зовут ".$this->getName()." и ";
}
}
/* Класс Women наследуют класс Human и обязан реализовать метод say() */
class Women extends Human {
public function __construct($name) {
parent::__construct($name);
}
public function bearChildren() {
echo "я рожаю детей";
}
public function say() {
echo "У меня женский голос, меня зовут ".$this->getName()." и ";
}
}
$man = new Man("Sergey");
$man->say();
$man->beard();
$women = new Women("Maria");
$women->say();
$women->bearChildren();
?>
Результат:
У меня мужской голос, меня зовут Sergey и у меня растет борода
У меня женский голос, меня зовут Maria и я рожаю детей