Как объяснить объект? - PullRequest
27 голосов
/ 15 июня 2009

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

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

  • Уровни доступа
  • Наследование
  • Инкапсуляция
  • Полиморфизм
  • Абстракция
  • Интерфейсы

Ответы [ 27 ]

1 голос
/ 24 июня 2009

ИМХО, мы должны сначала заинтересовать их в ООП, прежде чем бомбардировать их всеми концепциями в ООП. Чтобы привлечь их к ООП, объяснение всех понятий в ООП или показ примеров кошек и собак не сработают. Вам нужно показать им преимущества, сравнив проблему, решенную способом ООП и не ООП. Убедитесь, что вы сначала решили проблему не ООП, выделите недостатки, воспользуйтесь одной из концепций ООП для ее решения. Возможно, он использует только одну концепцию ООП, но если вы сможете заставить их почувствовать преимущество, которое он имеет по сравнению с другим методом, они сами захотят изучить больше ООП. Вам просто нужно указать их в правильном направлении после этого. Как только они ознакомятся с этими концепциями, направьте их к книгам по шаблонам проектирования, таким как «Шаблоны проектирования с первого взгляда».

1 голос
/ 24 июня 2009

Мой опыт самообучения состоит в том, что я ввел в мою голову немало проблем с концепцией объекта, отображаемого на «реальную сущность», такую ​​как животные, машины и так далее. Он формирует вашу голову в стремлении найти реалистичную (как в «реальном мире») таксономию в ваших бизнес-объектах, даже когда ее нет, и сбивает вас с толку в поиске нереалистичной таксономической классификации, которая вместо этого полезна для реального ОО-дизайна (например, дизайна узоры). Наконец, это подталкивает вас к тому, что вы окаменелы в одной таксономии «реального мира», даже если может существовать другой «менее реальный мир», и они лучше.

В любой книге ООП вы обнаружите, что квадрат - это своего рода прямоугольник, и поэтому квадрат представляется как унаследованный прямоугольником, но мы знаем, что этот подход глубоко ошибочен (я читал статью об этом, не помните, где, но вы можете искать "проблему хрупкого базового класса" в Google). Кроме того, в некоторых языках программирования вам не нужна таксономия OO для наследования интерфейса (см. мой пост на этот счет ).

Итак, я предлагаю следующее: представьте это, но будьте очень осторожны, насколько далеко вы продвинулись, и в конечном итоге немедленно переключитесь с примеров "машина и животные" на менее приятную для представления таксономию. Вы можете глубоко испортить их понимание, если вы слишком далеко продвинетесь.

1 голос
/ 24 июня 2009

Начинающему: объект похож на существительное. Если вы находитесь в классе, то у вас есть парты, ученики, учитель, проектор и т. Д. У каждого есть свои особенности и некоторые общие черты.

Итак, если мы хотим написать программу, которая будет вести себя так же, как классная комната, нам нужно воссоздать все эти «существительные» в коде. Каждый может что-то делать (student :: listen ()), и они могут взаимодействовать друг с другом (student :: search (new Desk ()))

Когда мы определили все правила и поведения (то есть написали наши классы / интерфейсы), тогда мы установили их в программе. for (i = 0; i <30; i ++) {class.Add (new Student ()))} и т. д. </p>

1 голос
/ 22 июня 2009

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

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

void printContactInfo(String name, String address, String phoneNumber) {
    System.out.println(name + " lives at " + address + " and his/her phone number is + "phoneNumber");
}

Вы пишете код выше, а затем в какой-то момент решаете, что хотите добавить адрес электронной почты и имя пользователя. Или вы имеете дело с двумя разными людьми. Вы можете легко получить громоздкие функции, которые принимают несколько аргументов, или иметь миллионы переменных для отслеживания. Или вы можете написать класс Person и просто позвоните:

Person someguy = new Person("MatrixFrog", "123 Notareal Street", "555 5555");
someguy.printContactInfo();

Опять, наверное, не лучший пример. И я согласен с mad-j, что эти маленькие примеры «машины» и «человека» не всегда хороши. Но я думаю, что если вы представили пример как решение реальной проблемы, которая возникает при написании кода , это может быть яснее.

То же самое с наследованием. Идея основана на реальном понимании того, что «X - это определенный тип Y», но причина, по которой мы это делаем, - сделать код проще для чтения и записи . Я не думаю, что я действительно понял наследование, пока в первый раз не обнаружил, что пишу два класса, имеющих много общего, и думаю: «Подождите. У них много одинаковых свойств. Может быть, я должен поместить их общие свойства в суперкласс ! "

1 голос
/ 19 июня 2009

Если бы я пытался объяснить классы и объекты кому-то совершенно незнакомому с программированием, я, вероятно, использовал бы что-то вроде следующего:

Класс - это просто " рецепт для вещи", класс состоит из разных типов "ингредиентов", которые имеют разные характеристики (то есть POD и функции / методы).

Таким образом, в нем содержатся только описания макета (строительных блоков) и функциональности.

Ингредиенты могут быть различного типа: «данные» в том смысле, что они содержат фактические поля данных (представьте факты, хранящиеся в переменных / полях ), и «действие» в том, что они содержат специфические методы для выполнения действий.

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

Таким образом, у вас как у повара есть возможность ограничить доступ к ингредиентам, так что пользователи вашего рецепта должны придерживаться вашего рецепта и просто использовать "предварительно консервированные" шаги (методы) выполнения вещи, которые вы предоставляете (без необходимости знать, о чем речь):

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

И затем есть компоненты, которые должны быть в общем видимы и доступны для всех пользователей рецепта ( public ), потому что они составляют «интерфейс» или «интерфейс» конечного продукта (они не Обязательно нужно знать о внутренних / низкоуровневых реализациях).

Как только класс фактически используется для реализации определенного рецепта, создается новый объект (создается экземпляр класса): шоколадный торт - это всего лишь одно проявление / версия рецепта шоколадного торта. Может быть много других версий, использующих тот же самый «рецепт».

Если вам нужно объединить несколько рецептов (например, шоколадный торт и лимонный торт), вы можете создать новый рецепт, который будет производиться от обоих рецептов, в основном создавая совершенно новый рецепт, который будет иметь характеристики оригинальных рецептов ( несколько наследование ).

Благодаря тому, что новые рецепты основаны на существующих рецептах с использованием наследования, изменения в оригинальном рецепте можно напрямую импортировать в новый рецепт. Аналогично, наличие общего рецепта предка (тип / суперкласс) означает, что его свойства (поля и методы) можно ожидать во всех подклассах (наследуемые / дочерние рецепты), другими словами, общий «рецепт шоколадного торта» может быть используется для создания двух новых специализированных версий шоколадного торта: «белый шоколадный торт» и «темный шоколадный торт», где цвет шоколада просто становится атрибутом, который можно настроить с помощью специального метода для шоколадного торта, такого как «setChocolateColor ()» .

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

1 голос
/ 23 июня 2009

Иногда начинающим сложно понять, как объекты связаны с выполнением программы. («Хорошо, у меня есть объект Person, который я могу создать как« Джерри », но где я могу выполнить создание?

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

1 голос
/ 20 июня 2009

объекты (обычно) имеют состояние, поведение и идентичность.

Основными принципами программирования o-o являются инкапсуляция, наследование и полиморфизм.

Основные принципы дизайна O-O здесь: http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

0 голосов
/ 24 июня 2009

Я мог бы начать с анонимных типов или чего-то вроде JSON, чтобы продемонстрировать, что объекты - это просто наборы свойств. Поговорим о сплоченности.

Что если нам понадобится куча этих объектов? Классы / Конструкторы / экземпляры.
Как насчет функциональности? Методы.

Затем продемонстрируйте проблемы, возникающие из-за отсутствия инкапсуляции. Покажите, как методы получения / установки / частные поля решают проблему (возможно, перейдите на типизированный язык, если вы использовали JSON) ...

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

Тогда введите полиморфизм - потому что наследование иногда недостаточно. Включите интерфейсы здесь.

Попробуйте использовать примеры из реального мира - либо из базы кода, над которой они будут работать, либо из вашего собственного портфолио. По ходу дела продемонстрируйте рефакторинг и другие полезные практики. «Эй, я продолжаю повторять эту схему - я должен как-то закрепить ее».

0 голосов
/ 15 июня 2009

Мне нравится пример "Автомобиль". Многие вещи могут быть транспортными средствами (абстрактный класс), но все они имеют что-то общее - они могут двигаться с некоторой скорости. Тогда могут быть разные классы транспортных средств: транспортные средства, находящиеся в движении, некоторые движутся в воде, некоторые в воздухе.

Таким образом, у вас есть другой уровень абстракции - например, всем транспортным средствам в воздухе необходим элемент высоты.

Полагаю, вы поняли картину. Это объясняет большинство пунктов, которые вы дали выше.

0 голосов
/ 24 июня 2009

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

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

Примеры из реальной жизни, такие как машины и т. Д., Можно использовать, чтобы показать, почему хорошо иметь объекты, но после ознакомления ваших учеников с основными концепциями программирования. Для ваших более талантливых учеников я бы дал подсказки, например, что объект - это просто неявный аргумент для его методов, или что член объекта - как ограниченная глобальная переменная, или что объект - как замыкание и т. Д. это, конечно, зависит от ваших учеников, и вы должны быть уверены, что не перепутаете их, так что этот последний совет не является обязательным, конечно :-)).

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