Сегодня на мозг будем натягивать/насаждать всю концепцию ООП разом/целиком, а именно такие понятия как Наследование, Полиморфизм, Инкапсуляция и Абстракция данных, из которых и состоит сама концепция ООП (ака Объектно-ориентированное программирование) почти любого языка прграммирования.
В этой статье мы не будем сильно углубляться в детали реализации, а лишь подробно разжуём сами понятия концепции ООП (Объектно-Ориентированное Программирование), без правильного понимания которых ни о какой успешной реализации речи быть не может.
С наступлением "притворного влияния загнивающего запада" и его активно развивающихся "вражеских" ИТ технологий, в нашем дремучем и брутальном славянском мэжик-пипл-вуду-пипл сообществе появилось множество всяких там заумных "буржуйских" словечек, типа: менеджер (манагер, manager - ака просто управляющий), курьер (фр. courrier - ака посыльный, ходок, шнырь) и т.п. - от которых у самых (dummy) маленьких (много думающих:) часто возникает масса вопросов и недоумений.
Прим. ред.: "Таких мужиков как он почти не осталось. Они все переквалифицировались в артистов, дизайнеров и программистов, - побрили подмышки и аста-ла-виста...". Исполнитель "Джин-Тоник - Водитель КАМАЗа".
Так вот..., для начинающего говнокодера, ой, ах простите, программиздаста, важно в полной мере понимать концепцию ООП (ака Объектно-ориентированное программирование) и входящих в неё заумных понятий Наследование, Полиморфизм, Инкапсуляция и Абстракция данных.
Для облегчения понимания ООП (ака Объектно-ориентированное программирование) для самых маленьких расшифруем ключевые его составляющие понятия:
- Концепция ООП - ака система понятий, в которую входят дочерние понятия Объект, Наследование, Полиморфизм, Инкапсуляция и Абстракция данных;
- Наследование - наследовать двушку в центре от усопшей бабушки. Многие стремятся не заработать что-то, а унаследовать;
- Полиморфизм - многообразный, разнообразный, универсальный. Все работодатели хотят заполучить полиморфных (универсальных) рабочих - т.е. если устраиваешься водилой КамАЗа, то в твои обязанности будет входить не только его вождение, ты ещё должен будешь быть автослесарем, грузчиком, мойщиком, экспедитором, инкассатором, и, ещё чёрт знает кем.., короче полиморфным (универсальным) водилой;
- Инкапсуляция - изолирование, например моего/твоего кореша инкапсулировали в колонии строгого режима;
- Абстракция - отделение, например закинулся галаперидолом, курнул или зелья какого выпил и на пару часов/суток получил абстракцию сознания от окружающего мира.
В результате правильного понимания всех упомянутых выше составляющих, наш код должен быть лаконичным и креативным.

Концепция ООП и Инкапсуляция
Пупом в системе понятий (ака концепция) является Объект, без наличия которого ООП не ООП вовсе, - имхо программирование то Объектно-то ориентированное. Объект же получается при создании экземпляра класса (в PHP например ака $myObj = new MyClass();), а когда у нас есть объект, то он автоматически выполняет сокрытие/изолирование (ака Инкапсуляция) данных от остальных частей программы до тех пор, пока они не будут извлечены из объекта и не будут переданы другому объекту или программе.
Наследование в ООП
Что же касается наследования двушки в центре от усопшей бабушки, то здесь проблем никаких нет, - а нет, как нет проблем и у наследования классом свойств и методов другого класса. На примере того же РНР делается так:
<?php // Снимаем комментарий ели нужно отображать все ошибки ini_set('display_errors', 'On'); error_reporting(E_ALL); class MyClass extends ArrayObject { // здесь наш полиморфный говнокод public function whoAmI() { return __METHOD__; } public static function print_data($data) { if (is_array($data)||is_object($data)) { echo '<pre>'; print_r($data); echo '</pre>'; } else { echo $data; } } } $testObj = new ArrayObject(); MyClass::print_data($testObj);
Здесь мы пополнили/расширили/унаследовали свой класс MyClass уже не "двушкой" усопшей бабушки, а глобальным классом ArrayObject и теперь в нашем классе/объекте MyClass будут доступны все свойства и методы класса в зависимости конечно от того, какая определена им видимость (global, static, public, protected, private).
К сожалению в РНР, в отличии от иных языков программирования, не поддерживается множественное наследование классов ака "class MyClass extends MyClass1, MyClass2, MyClass3", - на момент написания сего эпоса в РНР множественное наследование возможно только для интерфейсов (ака class MyClass extends MyClass1 implements Interface1, Interface2, Interface3).
Полиморфизм в ООП
Методы класса MyClass, whoAmI и print_data, получились очень даже полиморфненькими (универсальненькими), - первая выдаёт название используемого класса и метода, а вторая распечатывает на экран данные независимо от их типа.
Обратите внимание на то, что одна функция/метод (whoAmI) обычная, а вторая (print_data) статическая (static) - print_data мы без проблем вызвали статически (т.е. без создания объекта), а при вызове второй таким же образом мы получим ошибку "Strict Standards: Non-static method MyClass::whoAmI() should not be called statically in ...".
Статические методы экономят РАМу и как следствие способствуют повышению производительности, но в таком случае мы будем не полными ООП программильщиками имхо, как мы помним, пупом концепции ООП является объект, а при использовании статических классов/методов создавать объект нет надобности;)
Абстракция в ООП
Обычно, когда говорят "Абстракция" автоматом подразумевается "абстрактный класс". "Абстрактный класс" по сути не представляет из себя никакой практической пользы, - т.е. из него нельзя создать объект (экземпляр класса), к нему нельзя обратиться статическим путём. Полностью абстрактные классы называются "интерфейсами".
Цель "интерфейсов" (абстрактных классов) является определение того, что должно быть обязательно реализовано (implements). Поэтому не зря и слово implements подобрано, - в переводе означающее "реализует". Различие между "Абстрактным классом" и "Интерфейсом" в том, что абстрактный класс может содержать в себе как обычные, так и абстрактные методы. На примере того же РНР:
// абстрактный класс abstract class AbClass1 { abstract function method1(); static function method2(){ //... } } // интерфейс interface Interface1 { public function method1(); public function method2(); }
Когда создаётся интерфейс, то отпадает необходимость писать слово abstract перед методами (функциями) имхо все методы в интерфейсе по-умолчанию считаются абстрактными. В абстрактных методах никогда не представляется их {//...кода...} реализация.
Нужно запомнить, что интерфейс, как и абстрактный класс, является по сути шаблоном без реализации {//...кода...} методов. Шаблоны (паттерны, интерфейсы) призваны для того, чтобы следовать их структуре.
MyClass implements Interface1 { // наш собственный независимый метод public static function method(){//...код...}; // практическая реализация методов интерфейса Interface1 public static function method1(){//...код...}; public static function method2(){//...код...}; }
Создавая класс MyClass мы пожелали реализовать (implements) методы интерфейса (шаблона) Interface1, для чего мы обязаны переопределить method1 и method2 в нашем классе, а в противном случае получим ошибку.
Итоги
Как видим, всё познаётся в сравнении и ООП не является исключением.
Если с Концепцией ООП, Инкапсуляцией, Наследованием и Полимрфизмом всё более или менее определённо, то с понятием "Абстракция" и "Абстракция данных" не всё так однозначно...
Абстракция в ООП - это понятие довольно обширное и холиварное.
Абстракция данных в ООП - не менее обширное и холиварное понятие. Однако, на многих сайтах и в литературе под абстракцией данных с помощью интерфейсов и абстрактных классов почти всегда нужно иметь ввиду "Паттерны проектирования" (design pattern), а это как в анекдоте - "похожа свиня на коня, токо чуть шерсть не така".
Интерфейсы и абстрактные классы не содержат в себе никакой реализации и не несут в себе никакого практического функционала, а значит и не обрабатывают никаких данных, а следовательно не имеют совершенно никакого практического отношения к абстракции данных. Интерфейсы и абстрактные классы правильнее было бы называть шаблонами проектирования или абстракцией методов/логики на худой конец.
Абстракция же данных в ООП, в моём личном понимании, - выполняется приложением, которое построено по шаблону MVC (Model-view-controller, модель-представление-контроллер), где с момента получения запроса от пользовательской части идёт реальная абстракция данных, которые вначале поступают в контроллер (C, Controller), где после обработки некоторые из них передаются в модель (M, Model) делающую запросы в БД или производящую некоторые вычисления, снова возвращаются в контроллер и потов в представление/браузер (V, View) - таким образом некоторая часть наших данных абстрагировалась и зависла в БД, вторая пошла в кеш, иная в браузер пользователя, а остальная была сброшена вовсе.
Считаю, что говоря про Абстракцию в ООП следует фильтровать базар и не путать (коня со свиня) понятия абстракции. Абстракция бывает разная, и, в ООП её на мой взглялд нужно разделять на:
- Абстракция логики приложения - с использованием шаблонов (design pattern) проектирования (ака интерфейсы, абстрактные классы) и различных концепций типа MVC (модель, отображение, контроллер);
- Абстракция данных - как результат работы приложения, в результате работы которого данные разбиваются (абстрагируются друг от друга) на части, которые имеют разное функциональное предназначение и свой персонал их обслуживающий (программист, веб-мастер). Т.е. абстракции данных без самого, уже готового, приложения происходить не может.
Также в корне неверным считаю утверждение, что (interface) интерфейсы могут в РНР решить проблему невозможности множественного наследования классов! ИМХО наследовать (extends) и реализовать (implements) являются такими же разными понятиями, как - без напряга "унаследовать двушку от усопшей бабули" чем расширить (extends) перечень своего имущества, и, пойти работать грузчиком, чтобы "заработать или построить (implements) её (двушку т.е.)".
Проблема с пониманием четырёх концептуальных понятий ООП (почти на любом собеседовании требуют назвать): абстракции, инкапсуляции, наследования и полиморфизма - возникает в основном из-за подмены понятий или не верной их трактовки (один пи...нул, другой тупо закопипастил, и понеслось), в результате которых у начинающих сносит крышу и они из перспективных начинающих программистов превращаются в тупых говнокодеров или вовсе бросают это дело.

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

