heap.tech
лаборатория велосипедов
×

Выживание на собеседовании, часть 4. Основные принципы ООП

21 января 2017
Какие принципы ООП вы знаете ? Это коронный вопрос, с которого начинается каждое собеседование IT-специалиста. Иногда вопрос усложняют, например, так – «любезный, расскажите мне, обычному человеку, далекому от программирования, что означает каждый из принципов так, чтобы я понял суть и стал богом программирования». Если вам задали такой вопрос, радуйтесь - есть шанс самоутвердиться морально раздавив интервьюера знаниями и опытом.
Ссылки на предыдущие уроки выживания
Массивы, коллекции, перечисления, foreach
Упаковка и распаковка (boxing, unboxing)
Принципы SOLID (СОЛИД)

Что такое ООП


ООП – это аббревиатура объектно-ориентированное программирование. В миру это означает что программа оперирует объектами, которые взаимодействуют между собой. Объект - это обобщенное и название различных сущностей, то есть экземпляры классов или структур, перечисления.

Основные принципы ООП. Инкапсуляция


Инкапсуляция или сокрытие – это намеренное скрытие данных (или методов) объекта подальше от пользователя. Это позволяет избежать неожиданных изменений, которые не были предусмотрены программистом. Обычно пользователь все-же должен иметь возможность изменять данные, но делать он это должен в точности так, как того требует спецификация программы. Поэтому создаются public методы и свойства, которые дают возможность пользователю манипулирования данными, других способов изменения данных быть не должно. Под пользователем можно считать сферическую блондинку из бухгалтерии, нажимающую на кнопку или разработчика в свитере с оленями, который не должен знать частности работы модуля – он должен просто вызывать публичные методы, бережно созданные специально для него.
Для реализации инкапсуляции существуют модификаторы доступа: private, public, protected, internal.
Private - означает доступность компонента (метода, свойства, переменной & etc.) только для компонентов , находящихся с ним в одном классе (структуре). Во многих языка программирования все создаваемые компоненты, по умолчанию, являются private, пока не объявлено иное.
Public – компонент доступен отовсюду и без ограничений. Представим, вы скомпилировали библиотеку Core.dll с публичным классом Core и методом HelloWorld. Теперь любой программист, использующий вашу библиотеку, может вызывать ваш метод.
Protected – компонент доступен только для производных классов (то есть для потомков, потомки тесно связаны с наследованием, его я рассмотрю позднее)
Internal – компонент доступен только в текущей сборке. Под сборкой можно представить отдельную библиотеку, содержащую несколько классов. Классы, помеченные internal, доступны только внутри этой библиотеки.

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


Понятие наследования в программировании означает заимствование методов, свойств, переменных или иных компонентов от предка. Точно также и в жизни – потомки всегда похожи на своих предков и имеют идентичный набор базовых свойства. Например две руки и ноги. А частности, цвет глаз, волос могут быть переопределены наследником.
На практике механизм наследования применяется для расширения функциональности уже существующих сущностей без копипаста кода. Это увеличивает функциональности – базовый класс описывает общую функциональность, производные классы (наследники) дополняют его конкретными частностями. Как следствие это сокращает объем кода.

Представим доску объявлений по продажам товаров. Любое объявление должно содержать уникальный идентификатор, цену, дату создания и контакты продавца. И конечно информацию о продаваемом товаре товара, будь то шуба, телефон или автомобиль. Перечисленные товары обладают разными характеристиками и описывать их в одном точно не стоит. Правильное решение использовать механизм наследования - выделить базовый класс, с набором компонентов, обязательных для любого объявления (id, цена, дата, тип товара, методы удаления, изменения цены, статуса и т.д). Потом объявить наследников, который описывают конкретный товар. Такой подход помогает абстрагироваться от частностей объявления и работать с его базовыми компонентами. Конечно встает вопрос хранения информации о товаре, проще всего это делать с помощью сериализации. Но это отдельная история.

Полиморфизм


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

Представим - вы работаете в команде и делаете UI. В определенном месте вам нужно выводить на экран строчку "Hello World!", вы знаете, что для этих целей нужно использовать класс, который уже представлен в вашем UI-проекте в виде интерфейса IPrint. Внутри интерфейса есть метод PrintHelloWorld, да это то что нужно! Вызов PrintHelloWorld(). Но вместо того, чтобы напечатать что-то на экране он начинает печатать это на принтере. Как так!? Вы бежите к программисту Пете, ответственного за объект IPrint в контексте вашего UI, и бьете его головой о монитор, ты что наделал ? Петя отходит от боли и объясняет, что случайно подсунул вам другую реализацию, она для работы с принтером и нужна для ИТ-отдела бухгалтерии. А для работы с монитором он подсунет вам другой объект в этот интерфейс, и что вам ничего менять не надо.
Другими словами полиморфизм - это когда есть один интерфейс и много его реализаций, каждая реализация работает согласно своей логике. Интерфейс описывает только сигнатуры* методов, свойств (событий и индексаторов), а класс, который его реализует, должен делать это в точности так, как это описано.

*сигнатура метода (свойства) - это совокупность количества входящих параметров и их типов и типа возвращаемого значения (если метод не void или свойство имеет аксессор get).

Также во многих ООП языках есть абстрактные классы. Абстрактный класс это класс, который содержит хотя-бы один абстрактный метод, свойство или индексатор. Абстрактный метод (свойство, индексатор) не может содержать реализации, только сигнатуру, кроме того - нельзя создать его экземпляр. Странно, но это все что-то очень напоминает интерфейс, где разница ?
Да, напоминает. Поэтому это один из частых вопросов на собеседовании: ЧЕМ ОТЛИЧАЕТСЯ АБСТРАКТНЫЙ КЛАСС ОТ ИНТЕРФЕЙСА? Да просто - интерфейс не содержит реализаций, а абстрактный класс может содержать методы, свойства или индексаторы, которые имеют реализацию (не помечены как abstract).

Абстракция


Наследование, полиморфизм, интерфейсы и абстрактные классы - это механизмы и фичи ООП, которые нужны, чтобы помочь программисту выделить важный набор характеристик нескольких объектов в одну сущность и отбросить остальные характеристики. Абстракция позволят быстро вносить изменения в код с минимальными затратами на их кодирование - для этого достаточно изменить какую-то часть абстракции, самое важное в этом то, что необходимость править ссылки на переписанный кусок отпадает.
Абстракция на конкретном примере хорошо описана мной здесь. Очень рекомендую прочитать мою статью про принципы SOLID, как минимум, это полезно знать!
 
5537
0

Оставлять комментарии могут только зарегистрированные пользователи

пока никто не оставлял комментариев

Последние статьи

Сборка на водяном охлаждении. Часть 1

Компьютер на водяном охлаждении

Основы моддинга

Моддинг. Домашние компьютеры больше не унылые