Моя мама защитила диссертацию в колледже на Фортране, и теперь (более десяти лет спустя) ей необходимо изучить c ++ для моделирования жидкостей. Она в состоянии понять все процедурное программирование, но как бы я ни старался объяснить ей объекты, она не прилипает. (Я много работаю с Java, поэтому я знаю, как работают объекты) Я думаю, что я мог бы объяснить это слишком высокоуровневыми способами, так что это не имеет смысла для тех, кто никогда не работал с ними вообще и вырос в эпоху чисто процедурного программирования.
Есть ли какой-нибудь простой способ объяснить ей это, что поможет ей понять?
object-oriented
fortran
Эрик Поли
источник
источник
Ответы:
Краткий ответ: нет.
Длинный ответ: «Простого пути» не существует, потому что ООП далеко не прост. Процедурное программирование - это все о «переменных» и «если тогда иди». Все остальное - синтаксический сахар, но эти четыре вещи - все, что является процедурным программированием. Как только вы их получите, ничто не сможет остановить вас.
ООП - это способ организации переменных и фрагментов кода. Сколько шаблонов существует для определения ООП? 25? 30? Даже учителя, которые изучали ООП на разных языках и с разным опытом, не согласны с его собственным определением, так что ... как это может быть просто?
Я не знаю, как вы к этому пришли, но, поскольку у вашей матери такой же опыт, как у меня, я могу рассказать вам, как я к этому пришел.
Я программировал на С в очень большом проекте. Это был 1988 год. Многие программисты организовывали модули и библиотеки, с трудом избегая вмешательства в другие рабочие места и сохраняя хорошее разделение обязанностей.
Мы пришли к «решению», заключающемуся в том, чтобы поместить все взаимосвязанные глобальные данные в структуры, поместив в эти структуры некоторые указатели на функции, для которых требовались обратные вызовы. Таким образом, мы обобщили то, что мы назвали
io_mask
(диалоговые окна текстового режима) иgraphic_manager
т. Д. И т. Д.В 1996 году было очень легко обнаружить, что эти структуры были названы «классами», и эти указатели функций были заменены функциями-членами и виртуальными функциями или со ссылками на другие объекты (так называемые поведения) другими программистами, которые обновили этот старый проект.
Я начал понимать ООП, когда начал чувствовать потребность в этом: сегрегация, полиморфизм и поведение, определяемое во время выполнения.
Сегодня я работаю с ООП, но я не думаю, что это будет доктрина для служения: просто «общая идиома» (набор ...), которая позволяет нам говорить вместе без необходимости постоянно давать длинные объяснения и описания , На самом деле, больше "конвенция", чем что-либо еще. В конце концов, все ООП делает -again- "if then goto": он просто делает это "многослойно". Отсюда абстракция и идиомы над идиомами.
Игнорируй их. Пока она не испытывает потребности в них, даже не пытайтесь объяснить: она будет чувствовать их как сложный способ делать простые вещи. И она права ... пока все, что она делает, на самом деле просто.
Никто не подумает «организовать стол», если сверху всего четыре вещи. Это имеет смысл, когда вещи сверху начинают мешать друг другу. Это время для ООП, чтобы войти.
Вам не нужно ООП для работы с C ++. Вся стандартная библиотека C ++ не разработана с точки зрения ООП (хотя она может с ней сотрудничать), и C ++ не является Java.
По моему опыту, худшие учителя C ++ и программисты C ++ - это те, кто пришел из Java, учить всем своим предубеждениям обо всем - это не ООП, денатурируя язык, подобный С ++, который не (просто) для ООП.
Позвольте мне предложить хорошую книгу для тех, кто хочет приблизиться к C ++: Ускоренный C ++ : он познакомит вас с идиомами C ++, не притворяясь, что следует предопределенной доктрине.
источник
Старый друг утверждал, что у меня было самое короткое определение, которое он знал о программировании ОО, и я обнаружил, что оно работает для некоторых людей (а не для других):
Объектно-ориентированное программирование - это данные с мнением. Вы не двигаете кресло, вы просите кресло двигаться само. Вы не сортируете список, вы просите его отсортировать себя (возможно, с подсказкой). И т.п.
Идея состоит в том, чтобы заставить человека думать по- другому о том, как все происходит в его программе.
источник
Скажи ей думать об объектах, как объекты в реальном мире. Например, весь мир может быть смесью объектно-ориентированного программирования (на C ++) с неким функциональным программированием (возможно, на языке бога, Lisp).
Возьмите объект, например газонокосилку, у него есть определенные атрибуты, и он может делать определенную вещь. (объект и класс)
Затем расскажите ей о лучшей газонокосилке, которая является продолжением вашей газонокосилки. Скажите ей, что это лучше, но все еще основывается на том же механизме (наследование).
Тогда расскажи ей о себе. Скажите ей, что иногда вы можете стать экспертом по стрижке газонов, но на самом деле вы программист и зарабатываете на жизнь. Это как будто вы действуете как две разные сущности одновременно. Это полиморфизм.
Когда она получит это, расскажите ей о том, как реализовать эти вещи на языке, который она должна выучить (C ++).
Затем скажите ей, что если ей нужно написать симулятор этого мира в компьютерном мире, ей придется научиться делать это.
Когда она знает, как преобразовать ее мысли о реальном мире в программный код. она бы научилась программировать на объектно-ориентированном языке программирования.
источник
Я прошел путь от ассемблера и COBOL до Ruby.
Сначала мне помогло игнорирование концепции создания экземпляров классов.
Просто начните с кода. Есть класс, но просто есть методы уровня класса. Внутри методов много всего о параметрах, переменных, условных выражениях, массивах, строках, логических значениях и т. Д. Этот материал должен быть знаком.
Таким образом, в этот момент класс можно рассматривать как просто служащий цели, как место для размещения всех ваших связанных методов. Назовите его контейнером или библиотекой, который будет ей более знаком.
Очевидно, что код должен быть сегментирован, чтобы быть управляемым, поэтому у вас будет одна из этих областей. Например, для управления набором служебных программ на ПК у вас может быть класс калькулятора, в котором вы можете поместить весь код калькулятора в одно место. Если у вас есть только 1 калькулятор на вашем компьютере, тогда достаточно методов уровня класса.
Это начало.
Хорошо, теперь рассмотрим тот факт, что вы хотите открыть несколько калькуляторов и изменить, как каждый из них выглядит и где он находится на экране. Так что теперь вы не можете просто иметь метод калькулятора типа screen_location, потому что у вас есть несколько из них, и у каждого экземпляра есть свое местоположение ... каждый экземпляр ... хорошо, поэтому нам нужны экземпляры.
Примечание: мои термины взяты из ruby, а не c ++, поэтому вам, возможно, придется перевести.
источник
Я бы объяснил это в два этапа или, может быть, в четыре, в зависимости от того, насколько вы хотели бы разделить свои концепции.
Шаг 1: познакомить ее со структурами. Это довольно маленький шаг от типов данных Fortran к структурам. Шаг 1а: убедитесь, что она понимает динамическое распределение памяти и указатели.
Шаг 2: добавить процедуры, связанные только с этими структурами. Шаг 2а: добавить наследование, основанное на построении больших структур, которые «обертывают» меньшие структуры.
Для программиста на Фортране «вау» будет то, что компилятор будет следить за этим. Ага. Вот для чего нужны компиляторы ...
источник
Если она сделала свою диссертацию десять лет назад, она, вероятно, использовала Fortan 90 или 95, и в этом случае нужно поговорить об этом в связи с производными типами данных. Если это было достаточно давно, что она использовала Fortran 77, то познакомьте ее с производными типами данных в Fortran 90, а затем поговорите об этом ...
Я не буду вдаваться в полиморфизм и наследование до тех пор, пока она не уловит инкапсуляцию, поскольку их можно рассматривать как особые случаи и расширения инкапсуляции. Я, вероятно, начал бы ее на языке, который или разрешает свободные функции или статические классы.
источник
Как только она поймет структуры, я думаю, что следующим ключевым моментом будет признание того, что объектно-ориентированное программирование служит средством ограничения набора методов, которым может быть передана вещь, набором методов, которые фактически могут быть применены к этому. предмет.
В не объектно-ориентированном программировании, если кто-то использует отдельные типы данных для дерева и LinkedList, ему придется использовать разные методы для добавления узла к каждому. Номера объектно-ориентированные языки , как правило , пронзительный крик , если один попытался назвать оба метода
AddItem
, так как любое имя может относиться только к одному способу, что приводит один для создания имен методов , какAddTreeItem
,AddLinkedListItem
,RemoveTreeItem
и т.д. Такой подход работает, но это немного некрасиво. Концептуально методыAddTreeItem
и,RemoveTreeItem
кажется, принадлежат друг другу, но имена не сортируются таким образом. Можно было бы переписать имена , какTreeAddItem
,TreeRemoveItem
,LinkedListAddItem
и т. д., но это привело бы к большому «избыточному шуму» в начале каждого вызова метода. Подавляющее большинство вызовов методов в типичной программе будет содержать три основных элемента информации: (1) какой раздел исходного кода содержит метод; (2) какой из методов в разделе используется; (3) какая часть данных обрабатывается? Во многих случаях тип данных, с которыми осуществляется обработка, будет достаточным для определения того, к какой части кода относится метод, поэтому часть (1) вышеприведенного является избыточной. Легче визуально идентифицировать материал в начале оператора, чем материал где-либо еще, поэтому стиль кодирования / наименования, такой как вTreeAddItem(myTree, whatever)
конечном итоге, ставит наименее полезную часть информации на первое место.В отличие от этого, используя объектно-ориентированное программирование, можно было бы эффективно называть методы как
Tree.AddItem
и т. Д., А оператор likemyTree.AddItem(whatever)
заставил бы компилятор сказать, по сути, «Хм ...myTree
имеет типTree
, поэтому этот код должен вызыватьсяTree.AddItem()
. Нет необходимости указывайтеTree.
при вызове,AddItem
так как компилятор знает типmyTree
. Концептуально, оператор likemyTree.AddItem(whatever)
эквивалентенTree.AddItem(myTree, whatever)
, а некоторые объектно-ориентированные языки могут разрешать обе формы как эквивалентные, фактически большинство языков пропускают первый параметр в спецификации функции и вместо этого имеют методы, определенные в классе , какTree
неявно принимают параметр типаTree
, и присвоить ему имя , какthis
,self
илиMe
.Объектно-ориентированные языки программирования часто включают в себя множество дополнительных функций, таких как наследование, виртуальные функции и т. Д., Которые очень полезны во многих приложениях, но даже без этих функций возможность группировать функции в зависимости от того, над чем они работают, очень полезна.
источник
Объектно-ориентированное программирование - в релевантном здесь класс-ориентированном смысле - связано со связыванием представления данных с кодом, который им манипулирует. Это имеет смысл, если следующие вещи имеют смысл:
Связь: определение операции наряду с представлением данных, над которым она работает
Позднее связывание: выбор комбинации представления данных и поведения во время выполнения
Инкапсуляция: гарантия того, что данные действительны по построению и не будут в дальнейшем аннулированы
Вот и все. Как и любая технология, в основе ее лежит просто удобство, из которого впоследствии последовали многие разработки. Как только вы понимаете основы, остальное следует вовремя.
источник
Я бы предложил скачать BlueJ, поиграть с ним в течение 20 минут, а затем поиграть с ним в течение 20 минут.
То, как он визуализирует классы, интерфейсы и наследование, настолько очевидно и интуитивно понятно, что действительно дает вам мгновенное понимание, когда вы что-то реализуете - что угодно.
Это даже показывает вам разницу между классом и объектом.
Это не даст глубокого понимания шаблонов проектирования ОО, но даст фантастический обзор концепций.
источник
Я хотел бы добавить свой вклад в качестве напоминания о разнице между парадигмами программирования и языками программирования, которые реализуют эти парадигмы.
Так что, на мой взгляд, лучший способ объяснить ориентацию объекта с C ++ для пользователя F77, это действовать поэтапно:
Во-первых, познакомьте пользователя с концепцией объектной ориентации в привычной обстановке, показав ей, как разрабатывать объектоподобные структуры в Fortran 77 - например, взгляните на статьи вроде Б. Паттона «Объектно-ориентированный Fortran 77 (практикующий специалист). view) "SIGPLAN Fortran Forum 12, 2 (1993), pp. 23-24, и ссылки в нем.
Затем установите соответствие между этими структурами и классами и методами C ++.
Наконец, обсудите дополнительные возможности, которые C ++ может предоставить для облегчения программирования ОО.
источник
Когда я впервые перешел на объектно-ориентированный язык из моего начального обучения на Паскале, '.' проблема была самым большим препятствием для меня тоже. Мне потребовались годы, чтобы преодолеть это.
На самом деле очень неинтересно, что переменная принадлежит другой переменной, особенно когда вы привыкли думать о них как о указателях. Камнем преткновения для меня было:
Ага момент для меня, когда я понял, что указатель верхнего уровня в основном просто пространство имен.
Я бы посоветовал ей написать набор кода, который требует от нее пространства имен своих функций, в идеале без использования точечной нотации для начала. Затем попросите ее переписать ее, используя точечную запись.
Выполнение этого упражнения должно привести ее к первоначальному "Что это за колдовство?" препятствие.
источник
Одним из ключевых моментов, который помог мне объяснить ранее, является тот факт, что у вас может быть несколько экземпляров класса. Попытайтесь объяснить это с помощью «рисунков» или «слепков» и «копий» и посмотрите, к чему это приведет.
источник