Почему мне кажется, что студентов учат ООП неправильно
Когда я учился в университете мне довольно тяжело было понять ООП (Объектно-ориентированное программирование), сейчас я понимаю, что просто нас учили ООП на не совсем ясных и правильных аналогиях и вообще, кажется, сами преподаватели не совсем понимали, в чем же суть ООП.
Вспомните, классические аналогии ООП, вот есть класс Домашние любимцы с методами «голос» и «есть», от него мы наследуем Кошку и Собаку и все хорошо.
Но тут приходит Света и приносит аквариумных рыбок, которые не разговаривают, а потом приходит Вася, которые приносит любимый кактус, которые не только не разговаривает, но и не ест.
Мы уже запутались, но Вовочка спрашивает: «а где в этом зоопарке статические методы, интерфейсы, абстрактные классы и чем отличается объект класса от самого класса?». Объяснить, несомненно, можно, но сложно. Понять, еще сложнее.
Или другой классический пример, вот есть прямоугольник, от которого так и хочется унаследовать квадрат (ну по логике, квадрат это частный случай прямоугольника), но у прямоугольника есть длина и ширина, а у квадрата только одна сторона. Что-то тут тоже запутано.
Теперь подумаем как объяснить ООП лучше?
Объектно-ориентированное программирование это не описание объектов реального мира (точнее не только и столько описание реального мира), оно появилось от техник проектирования (до появления всяких компьютеров) от всяких инженерных бюро, архитекторов зданий, проектировщиков техники и т.п.
Итак представим себе фирму, производящую самолеты и конструкторское бюро при этой фирме (ну, скажем, Боинг). Нам заказали несколько моделей: военный самолет, грузовой и пассажирский.
Первое, что мы сделаем, это начнем чертить некоторый общий чертеж для всех моделей. По этому чертежу еще нельзя построить реальный самолет, но он уже содержит общие детали реализации. Это абстрактный класс.
Второе, нам нужно описать требования для унифицированного самолета, у него должны быть определенны такие параметры как грузоподъемность, крейсерская и максимальная скорость, практический потолок (они могут отличаться у разных моделей, но они должны быть), он должен уметь взлетать и, крайне желательно, уметь садиться. Требования к самолетам это интерфейс.
Параметры унифицированного самолета, которые заданы, но еще не определенны, или действия, которые он должен делать (взлет/посадка) это виртуальные методы и члены класса.
Дальше мы приступаем к чертежам конкретных моделей, по которым уже можно построить реальные самолеты. Это классы. Да, класс это именно чертеж и только чертеж, У конкретных классов должны определены все параметры унифицированного самолета и возможно добавлены новые. Мы должны определить как наш будущий самолет будет садиться, взлетать, как он будет летать. Это методы класса.
Если мы произведем реальный самолет это будет инстанс (объект) класса. Он построен по конкретным чертежам, но его параметры изменяются со временем, например, его максимальная и крейсерская скорость может чуть уменьшиться после определенных лет налета. То есть реальный существующий самолет это инстанс (объект) класса.
У каждой модели самолета есть общие параметры, например, процент аварийности. Каждое прошествие с любым самолетом этой модели его может изменить. Это статические методы и переменные класса.
Если мы сделали унифицированную модель самолет с определенным размахом крыльев и 2 реактивными двигателями, мы можем быть уверены, что любой из наших самолетов (военных, гражданских или грузовых) сможет сесть на ВВП полосу предназначенную для данного типа самолета. Это полиморфизм.
Если мы делаем самолет, но двигатель разрабатывает другая команда, нам проще не указывать его на самом чертеже самолета (тем более что один двигатель может использовать на большом количестве самолетов), а только указать «смотри чертеж такого-то двигателя». Это композиция.
Если мы разрабатываем трап, подходящий под этот тип самолета (и, возможно, другие подробные самолеты), пилот самолета при приземлении просит подать именно этот трап. Это будет ассоциация.
Если мы создали модель пассажирского самолета на 120 мест, а потом чуть-чуть доработали увеличив количество мест до 130 (за счет сокращения бизнес класса), нам не потребуется создавать новый чертеж, достаточно лишь указать изменения. Тут же становится легко понятно, почему если поменяется что-то в чертеже модели самолета на 120 мест, так же измениться самолет на 130 мест, так мы не делаем копию чертежей, мы только описываем, что изменилось в проекте. Это наследование.
На мой взгляд (если я не прав пишите в комментариях), принципы ООП становятся простыми и понятными, если перестать их пытаться объяснить на уровне реального мира, а представлять, как некоторую разработку чего-то нового (самолетов, машин, домов, электроники), тогда классы будут чертежами, схемами. Интерфейсы — контрактами или требованиями к новой продукции. А готовая продукция — объектами класса и т.д.
Спасибо за внимание!
P.S. Другие мои статьи (например, шпаргалку по Java SE) можно найти в моем профиле