Как объяснить концепции объектно-ориентированного программирования 6-летнему ребенку
Вы заметили, что на собеседованиях при приеме на работу всегда задают одни и те же шаблонные вопросы - снова и снова?
Я уверен, вы понимаете, что я имею в виду.
Каким ты видишь себя через пять лет?
Что вы считаете своей самой большой слабостью?
Тьфу ... дай мне передохнуть. Я считаю ответ на этот вопрос большой слабостью! В любом случае, это не моя точка зрения.
Какими бы тривиальными ни были подобные вопросы, они важны, потому что дают подсказки о вас. Ваше текущее состояние ума, ваше отношение, ваша точка зрения.
Отвечая, вы должны быть осторожны, так как можете раскрыть то, о чем позже пожалеете.
Сегодня я хочу поговорить о подобном типе вопросов в мире программирования:
Каковы основные принципы объектно-ориентированного программирования?
Я был по обе стороны этого вопроса. Это одна из тех тем, которые задают так часто, что вы не можете позволить себе не знать.
На это обычно приходится отвечать разработчикам младшего и начального уровня. Потому что это простой способ для интервьюера рассказать три вещи:
- Готовился ли кандидат к этому собеседованию?
Бонусные баллы, если вы сразу услышите ответ — это показывает серьезный подход. - Прошел ли кандидат этап обучения?
Понимание принципов объектно-ориентированного программирования (ООП) показывает, что вы вышли за рамки копирования и вставки из учебников — вы уже видите вещи с более высокой точки зрения. - Является ли понимание кандидата глубоким или поверхностным?
Уровень компетентности в этом вопросе часто равен уровню компетентности по большинству других предметов. Поверьте мне.
Четыре принципа объектно-ориентированного программирования - это инкапсуляция, абстракция, наследование и полиморфизм.
Эти слова могут показаться пугающими для младшего разработчика. А сложные, чрезмерно длинные объяснения в Википедии иногда удваивают путаницу.
Вот почему я хочу дать простое, короткое и ясное объяснение каждой из этих концепций. Это может звучать как то, что вы объясняете ребенку, но мне бы очень хотелось услышать эти ответы, когда я буду проводить собеседование.
Инкапсуляция
Допустим, у нас есть программа. В нем есть несколько логически разных объектов, которые взаимодействуют друг с другом — в соответствии с правилами, определенными в программе.
Инкапсуляция достигается, когда каждый объект сохраняет свое состояние закрытым внутри класса. Другие объекты не имеют прямого доступа к этому состоянию. Вместо этого они могут вызывать только список общедоступных функций, называемых методами.
Итак, объект управляет своим собственным состоянием с помощью методов, и никакой другой класс не может его коснуться, если это явно не разрешено. Если вы хотите взаимодействовать с объектом, вы должны использовать предоставленные методы. Но (по умолчанию) вы не можете изменить состояние.
Допустим, мы создаем крошечную игру Sims. Есть люди, и есть кошка. Они общаются друг с другом. Мы хотим применить инкапсуляцию, поэтому мы инкапсулируем всю “кошачью” логику в Cat
класс. Это может выглядеть так:
Вы можете покормить кошку. Но вы не можете напрямую изменить то, насколько голоден кот.
Здесь “состояние” cat - это частные переменные mood
, hungry
и energy
. У него также есть частный метод meow()
. Он может вызывать его, когда захочет, другие классы не могут сказать кошке, когда мяукать.
То, что они могут делать, определено в общедоступных методах sleep()
, play()
и feed()
. Каждый из них каким-то образом изменяет внутреннее состояние и может вызывать meow()
. Таким образом, выполняется привязка между приватным состоянием и общедоступными методами.
Абстракция
Абстракцию можно рассматривать как естественное продолжение инкапсуляции.
В объектно-ориентированном проектировании программы часто бывают чрезвычайно большими. И отдельные объекты много общаются друг с другом. Таким образом, поддерживать такую большую кодовую базу в течение многих лет — с изменениями на этом пути — сложно.
Абстракция - это концепция, направленная на облегчение этой проблемы.
Применение абстракции означает, что каждый объект должен предоставлять только высокоуровневый механизм для его использования.
Этот механизм должен скрывать внутренние детали реализации. Он должен раскрывать только операции, относящиеся к другим объектам.
Например кофемашина. Она делает много вещей и издает причудливые звуки под капотом. Но все, что вам нужно сделать, это налить кофе и нажать кнопку.
Желательно, чтобы этот механизм был прост в использовании и редко менялся со временем. Думайте об этом как о небольшом наборе общедоступных методов, которые может вызывать любой другой класс, не “зная”, как они работают.
Еще один реальный пример абстракции?
Подумайте о том, как вы используете свой телефон:
Вы взаимодействуете со своим телефоном, используя всего несколько кнопок. Что происходит под капотом? Вам не обязательно знать — детали реализации скрыты. Вам нужно знать только короткий набор действий.
Изменения в реализации — например, обновление программного обеспечения — редко влияют на используемую вами абстракцию.
Наследование
Хорошо, мы увидели, как инкапсуляция и абстракция могут помочь нам разработать и поддерживать большую кодовую базу.
Но знаете ли вы, что является еще одной распространенной проблемой в разработке ООП?
Объекты часто очень похожи. Они разделяют общую логику. Но это не совсем одно и то же. Тьфу…
Итак, как мы можем повторно использовать общую логику и извлечь уникальную логику в отдельный класс? Один из способов добиться этого - наследование.
Это означает, что вы создаете (дочерний) класс, производный от другого (родительского) класса. Таким образом, мы формируем иерархию.
Дочерний класс повторно использует все поля и методы родительского класса (общая часть) и может реализовать свои собственные (уникальная часть).
Если нашей программе нужно управлять государственными и частными преподавателями, а также другими типами людей, такими как студенты, мы можем реализовать эту иерархию классов.
Таким образом, каждый класс добавляет только то, что ему необходимо, при повторном использовании общей логики с родительскими классами.
Полиморфизм
Мы подошли к самому сложному слову! Полиморфизм в переводе с греческого означает “множество форм”.
Итак, мы уже знаем силу наследования и с радостью используем ее. Но возникает такая проблема.
Допустим, у нас есть родительский класс и несколько дочерних классов, которые наследуются от него. Иногда мы хотим использовать коллекцию — например, список — который содержит сочетание всех этих классов. Или у нас есть метод, реализованный для родительского класса, но мы хотели бы использовать его и для дочерних классов.
Это можно решить с помощью полиморфизма.
Проще говоря, полиморфизм дает возможность использовать класс точно так же, как его родительский, поэтому нет путаницы при смешивании типов.Но каждый дочерний класс сохраняет свои собственные методы такими, какие они есть.
Обычно это происходит путем определения (родительского) интерфейса для повторного использования. В нем изложено множество распространенных методов. Затем каждый дочерний класс реализует свою собственную версию этих методов.
Каждый раз, когда коллекция (например, список) или метод ожидают экземпляр родительского элемента (где описаны общие методы), язык заботится об оценке правильной реализации общего метода - независимо от того, какой дочерний элемент передается.
Взгляните на эскиз реализации геометрических фигур. Они повторно используют общий интерфейс для вычисления площади поверхности и периметра:
Наличие этих трех фигур, наследующих родительский Figure Interface
элемент, позволяет создать список из разных типов фигур triangles
, circles
, и rectangles
. И относиться к ним как к объектам одного типа.
Затем, если этот список попытается вычислить поверхность для элемента, будет найден и выполнен правильный метод. Если элемент представляет собой треугольник, CalculateSurface()
вызывается triangle . Если это круг - тогда CalculateSurface()
вызывается circle . И так далее.
Если у вас есть функция, которая работает с фигурой, используя ее параметр, вам не нужно определять ее три раза — один раз для треугольника, круга и прямоугольника.
Вы можете определить это один раз и принять a Figure
в качестве аргумента. Передаете ли вы треугольник, круг или прямоугольник — пока они реализуютсяCalculateParamter()
, их тип не имеет значения.
Надеюсь, это помогло. Вы можете напрямую использовать эти точно такие же объяснения на собеседованиях при приеме на работу.
Если вам все еще трудно что—то понять - не стесняйтесь спрашивать в комментариях ниже.
Что дальше?
Быть готовым ответить на один из классических вопросов для интервью — это здорово, но иногда вас никогда не вызывают на собеседование.
Далее я сосредоточусь на том, что работодатели хотят видеть в младшем разработчике и как выделиться из толпы при поиске работы.
Источник: https://www.freecodecamp.org/news/object-oriented-programming-concepts-21bb035f7260