112

Ответ на пост «Поговорим про ооп»1

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

Чем класс в данном контексте отличается от функции? У класса есть свойства и методы. Это такой свод правил для каждой специальности - для бетонщиков, для штукатуров, для маляров - для каждой специальности отдельно. Когда вы нанимаете пять маляров, вы создаёте пять экземпляров класса маляр. У класса есть свойства. Это например возраст маляра, его рост (мелким малярам сложнее работать без стремянки), вес (некоторым малярам возможно понадобится более основательная стремянка), имя и например оклад. Набирая пяток маляров свойства у каждого из них будут отличаться и как говорит известная телеведущая - это нормально. А вот методы работы у них должны быть строго одинаковые!

Теперь к наследованию. Если мы пойдём в истории нашей бригады чуть назад, то мы поймём что все они строители (базовый класс - строитель), все они имеют некий общий набор свойств перечисленных выше. А вот уже от строителей отходят классы наследники - штукатуры, маляры и бетонщики. При этом каждый базовый "строитель" умеет таскать песок - то есть наши специализированные классы унаследовали от родительского такую возможность и в ООП это называется наследованием. Но иногда вы нанимаете шикарного маляра, который говорит: "я кароч песок таскать не буду, но зато смотри как шикарно я крашу!" И тогда это уже другой класс маляра - маляр-профессионал. Ему негоже таскать песок, но красит на пятёрочку и по другим методикам - это называется полиморфизм. На попытку заставить его таскать песок он ответит отказом, а покрасит лучше простого маляра. Это потомучто он переопределил в себе методы родителя CarryingSand() и PaintingAWalls(). Теперь к инкапсуляции. Если методичка по покраске стен написана хорошо, верно и конкретный Махмуд не несёт отсебятины, то результат предсказуем и повторяем. И самое главное нет нужды стоять у него над душой и контролировать процесс. В жизни так конечно не бывает, но мы предположим, что такие чудесные люди существуют в этом мире. Вот в таком случае считается что метод инкапсулирован и не важно что делает ваш маляр - важен итоговый результат или мотивированный отказ с указанием причины почему это сделать невозможно (например нет сен под покраску). Это конечно сильно утрированный пример, но зато понятнее для обывателя.

Лига программистов

2K постов11.8K подписчиков

Правила сообщества

- Будьте взаимовежливы, аргументируйте критику

- Приветствуются любые посты по тематике программирования

- Если ваш пост содержит ссылки на внешние ресурсы - он должен быть самодостаточным. Вариации на тему "далее читайте в моей телеге" будут удаляться из сообщества

Вы смотрите срез комментариев. Показать все
5
Автор поста оценил этот комментарий

А зачем переопределять метод таскания песка на что-то другое? Не будет ли это говнокодом? Т.к. мы от метода CarryingSand() ждём что песок переместится, да, это может быть перенос песка в детском ведёрке, но это должен быть перенос песка. Но я пе пыхыпист, не знаю, может там свои порядки, но выглядит странно, если CarryingSand() не сможет перенести песок.

раскрыть ветку (10)
3
Автор поста оценил этот комментарий

А зачем переопределять метод таскания песка на что-то другое? Не будет ли это говнокодом?


Согласно принципу подстановки Барбары Лисков (L из SOLID) - это говнокод, ибо поведение дочернего класса не соответствуют контракту, описанному в родительском классе, а значит при полиморфизме возникнут проблемы.

2
Автор поста оценил этот комментарий
Тому шо ООП - сложно. Мы переопределяем метод для более высокой гибкости приложения, шоб мы могли таскать песок в разных тарах с разными реализациями, но с ожидаемым исходом. Это реализация контракта, по-сути
раскрыть ветку (3)
0
Автор поста оценил этот комментарий

Но мы же не переопределяем метод таскатьПесок() на фактическое действие по пермешивание краски. А значит даже супермаляр-профессионал будет уметь таскать песок, если это было в родительском классе.

Мы можем переопределить метод в рамках тех же действий. Если в родительском классе таскают песок в ведрах, то мы можем переопределить и таскать тачкой, в ладонях и т.д. но конечный результат для метода - песок переместился из точки А в точку Б.

раскрыть ветку (2)
0
Автор поста оценил этот комментарий
У вас даже тут проблема, что вы слишком зациклены на таскании песка. А завтра нужно будет не таскать песок, а возить его, например. И вам вашего ручного супермаляра нужно будет переучивать на новое действие, а это уже нарушение второго принципа Солид
раскрыть ветку (1)
0
Автор поста оценил этот комментарий

Не поняль, чем моё отличается от вашего?

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

0
Автор поста оценил этот комментарий

Я тоже не ПХПыст и пример общий чисто для примера. Мы же не говорим тут о том как лучше делать, а как нет. В реальной то жизни супер маляра не будут заставлять таскать песок, потомучто чернорабочему можно платить условных 10 единиц, а супермаляру 100 и более. Уметь то он умеет, но станет ли.

раскрыть ветку (3)
4
Автор поста оценил этот комментарий

Некорректный пример ведёт к неправильному пониманию. Переопределение не меняет суть родительского действия.

Иной пример на полиморфизм, надеюсь меня поправят если я ошибся:

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

Машины, попадающие на автомойку делятся на классы: 1) грузовая техника с открытым кузовом, 2) кабриолет с открытым кузовом, 3) обычные гражданские легковые авто.

Можно было бы придумать для каждого типа авто свою автомойку.

Но тогда для каждой автомойки нужен свой водопровод, утилизация, бухгалтерия и т.д.

Поэтому мы создаём одну автомойку, но с разными классами мойщиков. Всё наши мойщики сводятся к одному родительскому классу автомойщик. У него есть метод мытьМашину().

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

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

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

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

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

Про интерфейсы в теории так, на практике не пробовал).

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

раскрыть ветку (2)
1
Автор поста оценил этот комментарий
О, вот так понятнее, благодарочка ☺
0
Автор поста оценил этот комментарий

Может невнимательно читал, с мойкой это шаблон Посетитель (Visitor)?

0
Автор поста оценил этот комментарий

Тоже этот момент смутил )

Вы смотрите срез комментариев. Чтобы написать комментарий, перейдите к общему списку