Ооп языки: ООП языки программирования

Содержание

осваивай функциональные языки прямо сейчас

ООП или объектно-ориентированное программирование – парадигма, которую порой позиционируют как решение всех проблем. Так ли это на самом деле?

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

Конечная цель разработки софта состоит в написании надёжного кода. Забагованному и ненадёжному коду не помогут никакие концепции. А лучший путь к надёжности кода – простота. Следовательно, главная задача разработчиков – снижение сложности кода.

«Объектно-ориентированные программы предложены как альтернатива правильным…»

– Эдсгер Вибе Дейкстра, один из разработчиков концепции структурного программирования.

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

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

Многие не согласятся, но правда в том, что современное ООП никогда не разрабатывалось правильно. Оно никогда не опиралось на правильные исследовательские институты (в отличие от Haskell/FP). У ООП нет десятилетий строгих научных исследований. Лямбда-исчисления предлагают полную теоретическую основу для функционального программирования. У ООП нет ничего близкого к этому. По большому счёту, ООП «просто случилось».

ООП-код недетерминированный, в отличие от функционального программирования нам не гарантирован одинаковый вывод при одном и том же вводе. В качестве упрощённого примера: 2 + 2 или calculator.Add(2, 2) дают на выходе 4, но иногда могу дать 3, 5 или вообще 1004. Зависимости объекта Calculator могут менять результат вычислений в тонкой, но глубокой манере.

«C++ – ужасный [объектно-ориентированный] язык… Ограничение вашего проекта до C означает, что люди не облажаются с какой-нибудь идиотской «объектной моделью»c&@p.» – Линус Торвальдс, создатель Linux.

Линус Торвальдс известен своей критикой в адрес C++ и ООП. Он прав в ограничении программистов. Чем меньше выбора у программиста, тем гибче становится его код. В цитате выше Линус Торвальдс настоятельно рекомендует 

использовать хороший фреймворк как базу для кода.

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

Хороший фреймворк помогает писать надёжный код. Он должен помогать снижать сложность с помощью:

  1. Модульности и повторного использования.
  2. Правильной изоляции состояний.
  3. Высокого отношения сигнал/шум.

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

Функциональное программирование

Некоторые люди склонны считать функциональное программирование очень сложной парадигмой, которую применяют только в научной среде, и которая непригодна для «реального мира». Конечно, это не так!

Да, функциональное программирование имеет под собой сильное математическое основание и уходит своими корнями в лямбда-исчисления. Но большинство идей возникли в нём, как ответ на слабость мейнстримных языков программирования. Функция – это основная абстракция функционального программирования. При правильном использовании функции дают модульность и повторное использование кода, невиданное в ООП.

Функциональное программирование отлично справляется с задачей написания надёжного софта. Необходимость в дебаггере полностью исчезает. Больше не нужно перемещаться по своему коду и отслеживать переменные.

Наконец, если вы умеете использовать функции, вы уже функциональный программист. Осталось научиться использовать функции наилучшим образом!

«Мне очень жаль, что я давно ввёл термин «объекты» для этой темы, потому что он заставляет многих людей сосредоточиться на меньшей идее. Основная идея – обмен сообщениями.» – Алан Кэй, один из пионеров в областях объектно-ориентированного программирования.

Алан Кэй придумал термин «Объектно-ориентированное программирование» а 1960х. Благодаря своему биологическому бэкграунду он пытался создать коммуникацию между компьютерными программами по подобию живых клеток.

Основная идея Алана Кэя состояла в коммуникации между независимыми программами (клетками). Состояние независимых программ никогда не раскрывалось внешнему миру (инкапсуляция).

Вот и всё. ООП никогда не было предназначено для таких вещей, как наследование, полиморфизм, ключевого слова «new» и несчётного количества шаблонов проектирования.

Чистый ООП

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

А есть ли доказательства превосходства неизменяемых сообщений над вызовами методов?

Конечно! Erlang – это, возможно, самый надёжный язык в мире. Он поддерживает основную часть мировой инфраструктуры телекома (следовательно, и интернета). Некоторые системы, написанные на Erlang надёжны на 99.9999999%.

Самый важный аспект разработки – это постоянное понижение уровня сложности. Красивые фичи теряют смысл в коде, который невозможно поддерживать. Даже 100% покрытие тестами ничего не стоит, если код становится слишком сложным.

Что усложняет код? В основном общее изменяемое состояние, ошибочные абстракции, низкое отношение сигнал/шум (часто вызываемое шаблонным кодом). Всё это распространено в ООП.

«Я думаю, что большие объектно-ориентированные программы борются со сложностью, возрастающей по мере построения большого графика изменяемых объектов. Ну, знаете, когда вы пытаетесь понять и держите в памяти то, что произойдёт при вызове метода, и какие будут побочные эффекты.» – Ричард Хикки, создатель языка программирования Clojure.

Состояние само по себе безвредно. Но изменяемое состояние – это большой нарушитель. Особенно если оно общее. Что такое изменяемое состояние? Любое состояние, которое может измениться. То есть, переменные или поля в ООП.

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

Проблема параллелизма

Беспорядочный доступ к изменяемому состоянию делает параллельность в таком коде невозможной. Для решения этой проблемы был предложен сложный механизм. Блокировка потоков, Мьютекс и другие сложные механизмы. Конечно, они имеют недостатки – взаимные блокировки, нехватка композиционности, а отладка многопоточного кода очень сложна и отнимает много времени.

Не все состояния – зло

Получается, состояния – зло? Нет, изменение состояния, наверное, нормально в случаях настоящей изоляции (не ООП-изоляции).

Вполне нормально иметь неизменяемые объекты передачи данных. Ключевое слово здесь – «неизменяемые». Такие объекты используются для передачи данных между функциями.

Так или иначе, такие объекты сделают методы и свойства ООП абсолютно избыточными. Какой смысл в методах и свойствах объекта, если они не могут быть изменены?

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

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

Проблема глобального состояния

Нам говорили, что глобальное состояние – корень всех зол. Нужно избегать его, чего бы это ни стоило. Нам никогда не говорили, что инкапсуляция, по факту, вершина глобального состояния.

Для эффективности кода объекты передают не свои значения, а их ссылки. Вот где «внедрение зависимости» терпит неудачу.

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

Это создаёт сложный график беспорядочных общедоступных объектов, которые меняют состояния друг друга. Что, в свою очередь, приводит к огромным проблемам, так как отследить причину изменения состояния программы становится практически невозможно. Можно потратить много дней на отладку подобных изменений состояния. И вам повезло, если вам не нужно разбираться ещё и с параллелизмом.

Методы/Свойства

Методы и свойства, которые предоставляют доступ к определённым полям ничем не лучше прямого изменения полей. Неважно меняете ли вы состояние объекта с помощью красивого свойства метода – результат один: изменённое состояние.

Спойлер: Функциональное программирование. 🙂

Если такие термины, как функторы и монады ни о чём вам не говорят, то вы не одиноки! Функциональное программирование не было бы таким пугающим имей оно более интуитивные названиями основных идей. Функторы – это то, что можно преобразовать с помощью функции, например,

list.map. Монады – просто цепочка связанных вычислений!

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

Возможно, вы ещё не осознали себя функциональным программистом. Вы используете функции в повседневной работе? Да? Тогда вы уже функциональный программист! Осталось научиться эффективному использованию функций.

Два хороших функциональных языка с лёгким обучением – это Elixir и Elm. Они позволяют разработчику сосредоточиться на том, что действительно важно – на написании надёжного софта и удалении сложности традиционных функциональных языков.

Альтернативы? Ваша организация использует C#? Попробуйте F# – классный функциональный язык, совместимый с .NET. Используете Java? Тогда Scala и Clojure – неплохие варианты для вас. Используете JavaScript? С правильным руководством и линтингом JavaScript превращается в хороший функциональный язык.

А вы готовы отказаться от ООП?

Первые языки объектно-ориентированного программирования (ООП)



Первые языки объектно-ориентированного программирования (ООП) на сайте Игоря Гаршина

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

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

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

  1. наследование;
  2. инкапсуляция;
  3. полиморфизм.

Первым языком программирования, в котором были предложены основные понятия, впоследствии сложившиеся в парадигму, была Simula-1, но термин «объектная ориентированность» не использовался в контексте использования этого языка. В момент его появления в 1967 году в нём были предложены революционные идеи: объекты, классы, виртуальные методы и др., однако это всё не было воспринято современниками как нечто грандиозное. Фактически, Симула была «Алголом с классами», упрощающим выражение в процедурном программировании многих сложных концепций. Понятие класса в Симуле может быть полностью определено через композицию конструкций Алгола (то есть класс в Симуле — это нечто сложное, описываемое посредством примитивов). При этом класс можно использовать в качестве префикса к другим классам, которые становятся в этом случае подклассами первого. Впоследствии Симула-1 был обобщен, и появился первый универсальный ООП-ориентированный язык программирования – Simula-67.

Взгляд на программирование «под новым углом» (отличным от процедурного) предложили Алан Кэй и Дэн Ингаллс в языке Smalltalk. Здесь понятие класса стало основообразующей идеей для всех остальных конструкций языка (то есть класс в Смолтоке является примитивом, посредством которого описаны более сложные конструкции). Именно он стал первым широко распространённым объектно-ориентированным языком программирования.

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

В настоящее время количество прикладных языков программирования, реализующих объектно-ориентированную парадигму, является наибольшим по отношению к другим парадигмам. Наиболее распространённые в промышленности языки (С++, Delphi, C#, Java и др.) воплощают объектную модель Симулы. Примерами языков, опирающихся на модель Смолтока, являются Python, Ruby.

Разделы страницы о первых языках объектно-ориентированного программирования:

  • Simula (Си́мула — «объектный Алгол») — 1967 г.
  • Язык абстрактных данных Клу (Clu) — 1974 г.
  • SmallTalk (Смо́лток) — 1980 г.
  • Объектный язык системного программирования C++ — 1980-е г.г.
  • Язык контрактного программирования Eifel

Simula (Си́мула — «объектный Алгол») — 1967 г.

Simula (Си́мула) — язык программирования общего назначения для моделирования сложных систем. Он разработан в конце 60-х сотрудниками Норвежского Вычислительного Центра (Осло) Кристеном Нюгордом и Оле-Йоханом Далем и был представлен как Simula-67. Симула традиционно считается первым в мире объектно-ориентированным языком, но создатель языка Smalltalk Алан Кэй утверждает, что именно он изобрёл термин «ООП». Симулу 67 можно охарактеризовать как объектное расширение Алгола 60.

Simula 67 явилась первым языком с встроенной поддержкой основных механизмов ООП. Этот язык в значительной степени опередил своё время. Его современники (программисты 60-х годов) оказались не готовы воспринять его ценности, и он не выдержал конкуренции с другими языками программирования (прежде всего, с Фортраном). Прохладному отношению к языку способствовала и его весьма неэффективная реализация (в т.ч. из-за сборки мусора). Тем не менее, этот язык активно использовался в образовательном процессе в высших учебных заведениях, особенно в Скандинавии. Более всего в Simula 67 поражает сходство с современными языками: пожалуй, единственными существенными пробелами по сравнению с Java являются отсутствие интерфейсов и невозможность для объекта иметь более одного конструктора.

  • Симула в Википедии.

Язык абстрактных данных Клу (Clu) — 1974 г.

Клу (Clu, CLU) — объектно-ориентированный [?!] язык программирования, одним из первых реализовавший концепцию абстрактных типов данных и парадигму обобщённого программирования. Создан группой учёных Массачусетского технологического института под руководством Барбары Лисков в 1974 году. Язык широкого применения не нашёл, однако многие конструкции и находки использованы при создании таких языков как Ада, C++, Java, Sather, Python, C#.

  • Клу — Википедия

SmallTalk (Смо́лток) — 1980 г.

Smalltalk (Смо́лток) — объектно-ориентированный язык программирования с динамической типизацией, разработанный в Xerox PARC Аланом Кэйем, Дэном Ингаллсом, Тедом Кэглером, Адель Голдберг и др. в 1970-х годах. Язык был представлен как Smalltalk-80. Smalltalk продолжает активно развиваться и собирает вокруг себя сообщество пользователей.

Smalltalk оказал большое влияние на развитие многих других языков, таких как: Objective-C, Actor, Java, Erlang, Groovy и Ruby. Многие идеи 1980-х и 1990-х по написанию программ появились в сообществе Smalltalk. К ним можно отнести рефакторинг, шаблоны проектирования (применительно к ПО), карты «класс — обязанности — взаимодействие» и экстремальное программирование в целом. Основатель концепции Wiki Уорд Каннингем также входит в сообщество Smalltalk.

  • SmallTalk в Википедии.

Объектный язык системного программирования C++ («Си с классами») — 1980-е г.г.

А почему вы используете С++ вместо языка программирования? (из Башорга)

Язык C++ появился в начале 80-х годов. Созданный Бьерном Страуструпом с первоначальной целью избавить себя и своих друзей от программирования на ассемблере, Си или различных других языках высокого уровня. По мнению автора языка, различие между идеологией Си и Си ++ заключается в следующем: программа на C отражает “способ мышления” процессора, а C++ — способ мышления программиста. Язык С++ объединил в себе черты объектно-ориентированного и системного программирования.

Отвечая требованиям современного программирования, C++ делает акцент на разработке новых типов данных наиболее полно соответствующих концепциям выбранной области знаний и задачам приложения. Класс является ключевым понятием C++. Описание класса содержит описание данных, требующихся для представления объектов этого типа и набор операций для работы с подобными объектами.

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

Язык контрактного программирования Eifel

Эйфель (Eiffel) — объектно-ориентированный язык программирования с алголоподобным синтаксисом (но без использования сепаратора) и сильным влиянием Симулы (Simula). Он разработан президентом компании Interactive Software Engineering (ISE) Бертраном Мейером в 1987 году. В этом языке впервые был реализован метод контрактного программирования, что является самым характерным его свойством: встроенные утверждения создают принудительный контракт между вызывающим оператором и вызываемым кодом подпрограмм.

Eiffel имеет несколько важных черт, поддерживающих более жесткий стиль программирования, в том числе параметризованные классы, утверждения и исключения. Неотъемлемой частью языка являются пред- и постусловия — утверждения, которые должны выполняться при входе в метод и выходе из него. Нарушение утверждения вызывает исключительную ситуацию, которую можно перехватить, обработать и попробовать вызвать тот же метод еще раз. Предусловия, постусловия и инварианты называются «контрактами». Его приверженцы считают Eiffel более полным, надежным, универсальным и удобным языком программирования, чем Java.

  • Эйфель (язык программирования) Материал из Википедии — свободной энциклопедии.
  • Язык программирования Eiffel (Эйфель).


Ключевые слова для поиска сведений о пионерах ООП: На русском языке: пионеры объектно-ориентированного программирования, первые языки ООП; На английском языке: OOP, С++, Simula, Smalltalk.

Объектно-ориентированные языки — Информатика, информационные технологии

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

Основными понятиями языков объектно-ориентированного программирования являются объект, класс и метод.

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

• Класс – это шаблон, на основе которого может быть создан конкретный программный объект. Он описывает свойства и методы, определяющие поведение объектов этого класса. Каждый конкретный объект, имеющий структуру данного класса, называется экземпляром этого класса.

• Метод – это процедура или функция, объявленная внутри объявления элемента типа «объект».

Фундаментальными принципами ООП (объектно-ориентированного программирования) являются инкапсуляция, наследование и полиморфизм.

• Инкапсуляция – это объединение данных и свойственных им процедур обработки в одном объекте.

• Наследование предусматривает создание новых классов на базе существующих и позволяет классу-«потомку» иметь (наследовать) все свойства класса-«родителя».

• Полиморфизм означает, что порожденные объекты обладают информацией о том, какие методы они должны использовать в зависимости от того, в каком месте цепочки они находятся.

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

Основные шаги разработки программы, предусмотренные данной методологией:

• определение проблемы;

• развитие неформальной стратегии, представляющей общую последовательность шагов и удовлетворяющей требованиям к будущей программе;

• формализация стратегии;

• идентификация объектов и их атрибутов;

• идентификация операций;

• установка интерфейсов;

• реализация операций.

Первый объектно-ориентированный язык программирования Simula 67 был разработан в 1967 г. в Норвегии. Основные представители в наше время:

C++

Разработан датским программистом, работающим в США, Бьярном Страуструпом в 1983 г. на основе классического языка C, появившегося одиннадцатью годами ранее. Широко используется во многих областях, обеспечивая хорошее сочетание функциональности и простоты использования.

Visual Basic

Разработанный в 1991 г. объектно-ориентированный вариант одного из наиболее простых языков программирования.

Delphi

Разработанный в 1995 г. компанией Borland объектно-ориентированный вариант языка программирования Pascal.

Java

Разработан корпорацией Sun в 1995 г. Потомок C++; основным его преимуществом считается платформо-независимость, т.е. приложения, написанные на Java, могут выполняться на любых компьютерах, независимо от их типа и установленной ОС. Java стал стандартным языком программирования Internet, — именно на нем пишутся маленькие программные дополнения к Web-приложениям – апплеты.

C#

Разработан в 2000 г., является удачным сочетанием C++ и Java, ориентирован на разработку Web-приложений.

В отношении объектно-ориентированного программирования уместно говорить не просто о языках или даже системах программирования, а об интегрированных средах разработки или системах визуального проектирования, в которых интерфейсная часть программного продукта создается в диалоговом режиме, практически без написания программных операторов. ОС Ms Windows за многие годы установила стандарт графической оболочки GUI – Graphic User Interface, обеспечивающей среду для пользователя и программиста. Все программирование в Windows базируется на использовании набора функций интерфейса прикладного программирования Win32 API, специально сконструированного для работы с различными языками программирования. Программирование на Win32 API поддерживается любой существующей средой разработки ПО.

При помощи визуальных языков программирования механизмы Drag and Drop («перенеси и брось») упрощают создание интерфейсов приложений. Такие системы имеют название RAD (Rapid Application Development – быстрая среда разработки приложений). Такой подход в программировании позволяет уделить больше времени на разработку логики программы, а не на создание интерфейса будущего приложения. Каждая среда разработки имеет огромный набор встроенных объектов, называемых элементами управления или примитивами.

К наиболее известным инструментам визуального программирования относятся среды Delphi и C++ Builder компании Borland (в прошлом Inprise) и продукты семейства Visual Studio компании Microsoft. Первая версия Visual Studio вышла в свет в 1997 г., а версия Visual Studio 6.0 включает в себя Visual Basic (VB), Visual C++, Visual FoxPro, Visual InterDev, Visual J++, Visual SourseSafe и библиотеку MSDN. Microsoft разработала свою компонентную модель MFC (Microsoft Foundation Class Library – библиотека основных классов от Microsoft), являющуюся прямым конкурентом модели VCL (Visual Component Library – библиотека визуальных компонент), используемой в Delphi и C++ Builder. Библиотека VCL имеет богатый выбор функционала, а библиотека MFC отличается производительностью и быстродействием. В настоящее время Visual Studio расценивается как полнофункциональный набор продуктов для проектирования в среде Windows, который может с успехом применяться для разработки как традиционных клиентских приложений, так и приложений для Internet.

В конце 2001 г. Microsoft анонсировал новую платформу для разработки ПО — .NET, ориентированную на Web-разработки. Для этой платформы была дополнительно создана новая спецификация языка программирования C#, которому свойственны модное течение, хорошие возможности и многофункциональность.

Статьи к прочтению:

Основные принципы объектно-ориентированного программирования. Что такое ООП и зачем оно нужно?


Похожие статьи:

Объектно-ориентированный язык программирования — это… Что такое Объектно-ориентированный язык программирования?

Объектно-ориентированный язык программирования (ОО-язык) — язык, построенный на принципах объектно-ориентированного программирования.

В основе концепции объектно-ориентированного программирования лежит понятие объекта — некой субстанции, которая объединяет в себе поля (данные) и методы (выполняемые объектом действия).

Например, объект человек может иметь поля имя, фамилия и методы есть и спать. Соответственно, в программе можем использовать операторы Человек.Имя:="Иван" и Человек.Есть(пища).

Особенности , Ulan

В современных ОО языках используются механизмы:

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

Список языков

Неполный список объектно-ориентированных языков программирования:

Кроме ОО-языков общего назначения существуют и узкоспециализированные ОО-языки.

Литература

  • Иан Грэхем. Объектно-ориентированные методы. Принципы и практика = Object-Oriented Methods: Principles & Practice. — 3-е изд. — М.: Вильямс, 2004. — 880 с. — ISBN 0-201-61913-X
  • Антони Синтес. Освой самостоятельно объектно-ориентированное программирование за 21 день = Sams Teach Yourself Object-Oriented Programming in 21 Days. — М.: Вильямс, 2002. — 672 с. — ISBN 0-672-32109-12
  • Гради Буч. Объектно-ориентированный анализ и проектирование с примерами приложений на С++. — Бином, 1998. — ISBN 0-8053-5340-2, ISBN 5-7989-0067-3, ISBN 5-7940-0017-1
  • Петер Коуд (Дэвид Норт, Марк Мэйфилд). Объектные модели. Стратегии, шаблоны и приложения.

Ссылки

Коротко об истории объектно-ориентированного программирования

Является ли Go языком ООП? / Хабр

Object-oriented design is the roman numerals of computing.
— Rob Pike, автор Go.

Предлагаю вашему вниманию вольный перевод заметки «Is Go An Object Oriented Language?» за авторством Steve Francia, в которой автор наглядно рассказывает об особенностях использования парадигмы ООП в Go. Сразу предупреждаю, что из-за свойств оригинального материала большую часть текста пришлось переформулировать полностью, где-то добавить своего. Флажок перевода убирать не стал.

1. Введение

Так что же это значит, быть «объектно-ориентированным»? Обратимся к истории возникновения концепта ООП, попробуем разобраться.
Первый объектно-ориентированный язык, Simula, появился на горизонте в 60-x годах. Он привнёс понятия объектов, классов, понятия наследования и классов-потомков, виртуальных методов, сопрограмм и многое другое. Походу, самым ценным вкладом стала парадигма абстракции данных.

Вы можете быть не знакомы со Simula, но, вне всяких сомнений, точно знаете некоторые из тех языков, для которых он стал вдохновением — Java, C++, C# и Smalltalk, которые позже, в свою очередь, сильно повлияли на Objective-C, Python, Ruby, Javascript, Scala, PHP, Perl… полный перечень содержит почти все популярные современные языки. Эта парадигма настолько прочно вошла в нашу жизнь, что большинство современных программистов никогда и не думали иначе.

Поскольку общепринятого определения ООП не существует, для продолжения дискуссии мы сформулируем своё.

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

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

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

2. Объекты?

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

Для наглядности приведу пример:

type rect struct {
    width int
    height int
}

func (r *rect) area() int {
    return r.width * r.height
}

func main() {
    r := rect{width: 10, height: 5}
    fmt.Println("area: ", r.area())
}

Первый блок определяет новый тип rect структурного типа, содержащего 2 целочисленных поля. Следующий блок определяет метод на этой структуре путём определения функции area и прикрепления её к типу rect. Точнее, на самом деле функция прикрепляется к типу-указателю на rect.
Последний блок является точкой входа программы, это функция main. Первая строка создаёт новый экземпляр rect (выбранный способ создания экземпляра — через составной литерал — является наиболее удобным в Go). Вторая строчка отвечает за вывод результатов вызова функции area на значении r.

Лично мне это всё сильно напомнило работу с объектами. Я могу создать тип структурированных данных и определить методы для работы с некоторыми из них.
Чего-то ещё не хватает? Да, в большинстве объектно-ориентированных языков для описания объектов используются классы с поддержкой наследования, причём хорошей практикой считается определение интерфейсов для этих классов и тем самым определение дерева иерархии классов (в случае простого наследования).

2. Наследование и полиморфизм

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

2.1. Простое и множественное наследование
Наследование это механизм языка, позволяющий описать новый класс на основе уже существующего (базового) класса. Существует две разновидности наследования, на основании количества базовых классов. Принципиальную разницу можно ощутить лишь оценивая последствия применения множественного наследования: иерархия простого наследования (single inheritance) представляет собой дерево, в то время как множественное наследование порождает решётку. Языки с поддержкой исключительно простого включают PHP, C#, Java и Ruby, а к языкам с поддержкой множественного наследования относятся Perl, Python и C++.

2.2. Полиморфизм подтипов
В некоторых языках понятия подтипов и наследования так тесно переплетены, что разница между ними едва заметна. На самом деле подтипы определяют семантические отношения между двумя и более объектами, тем самым образуя отношения is-a. То есть, тип A является подтипом B тогда, когда спецификация A следует из спецификации B и любой удовлетворяющий спецификации A объект (или класс) также удовлетворяет спецификации B. В то время как простое наследование только повторно использует реализацию, тем самым обеспечивая синтаксический сахар, но не более.

Следует чётко различать наследование через реализацию и «наследование» через полиморфизм подтипов, что будет понятно из текста далее.

2.3. Композиция
При композиции один объект определяется путём включения в него других объектов, то есть вместо наследования он просто содержит их. Такой тип взаимосвязи называется has-a и включаемые объекты подчиняются правилам принадлежности.

3. Есть ли в Go наследование?

Go по задумке был спроектирован без наследования в обычном понимании этого слова. Вовсе не значит, что объекты (структуры) не имеют отношений, просто авторы языка выбрали иной механизм обозначения таковых. Для многих начинающих писать на Go это решение может показаться серьёзной недоработкой, однако, в действительности же, это одно из самых приятных свойств языка и оно решает много проблем, заодно закрывая споры вокруг наследования — возраст которых исчисляется десятками лет — раз и навсегда.
4. «Простое наследование лучше выкинуть»

Далее я приведу фрагмент из статьи на JavaWorld — «Why extends is evil»:
В книге банды четырёх о паттернах проектирования детально обсуждается замена наследования через реализацию (extends) на наследование через интерфейсы (implements).

Я однажды посетил сходку юзер группы Java, куда James Gosling (создатель Java) был приглашён делать доклад. Во время памятной сессии вопросов и ответов кто-то спросил его: «Если бы вы могли сделать Java заново, что бы вы изменили?». «Я бы выкинул классы», ответил он. После того как смех в зале утих, он объяснил, что настоящая проблема заключается не в классах по сути, а в наследовании через реализацию (отношение extends). Наследование же через интерфейсы (отношение implements) является предпочтительным, следует избегать наследование через реализацию там, где возможно.


5. Отношения объектов в Go

5.1. Композиция типов
Вместо обычного наследования в Go строго используется принцип композиции вместо наследования и отношения между структурами и интерфейсами строятся по принципам is-a и has-a. Используемый здесь механизм композиции объектов представляется встраиваемыми типами, так, Go позволяет встроить структуру в структуру, создавая при этом отношения типа has-a. Хорошим примером является связь между типами Person и Address в коде ниже:
type Person struct {
   Name string
   Address Address
}

type Address struct {
   Number string
   Street string
   City   string
   State  string
   Zip    string
}

func (p *Person) Talk() {
    fmt.Println("Hi, my name is", p.Name)
}

func (p *Person) Location() {
    fmt.Println("Im at", p.Address.Number, p.Address.Street, p.Address.City, p.Address.State, p.Address.Zip)
}

func main() {
    p := Person{Name: "Steve"}
    p.Address = Address{ Number: "13", Street: "Main" }
    p.Address.City = "Gotham"
    p.Address.State = "NY"
    p.Address.Zip = "01313"
    p.Talk()
    p.Location()
}

Результат:
>  Hi, my name is Steve
>  Im at 13 Main Gotham NY 01313

play.golang.org/p/5TVBDR7AYo

В этом примере важно то, что Address остаётся обособленной сущностью, находясь внутри Person. В функции main продемонстрировано, как можно присвоить p.Address объект адреса и, обращаясь к его полям через точку, проинициализировать его.

5.2. Имитация полиморфизма подтипов

Примечание автора. Первая версия данной статьи неверно объясняла реализацию отношения is-a через анонимные поля структуры. На деле же она лишь напоминает отношение is-a, поскольку включаемые методы и свойства становятся видимыми извне, как если бы они существовали во включающей структуре. Такой подход не является is-a по причинам, описанным далее, однако, в Go есть поддержка is-a и достигается она через интерфейсы. Текущая версия статьи ссылается на анонимные поля как на имитацию is-a, поскольку они похожи на механизм полиморфизма, но не более. //

Имитация отношения is-a работает подобным же образом. Пусть человек (Person) умеет говорить. Горожанин (Citizen) является человеком (Person), а значит также умеет говорить (Talk). Расширим предыдущий пример с учётом этого.

type Citizen struct {
   Country string
   Person // анонимное поле без имени
}

func (c *Citizen) Nationality() {
    fmt.Println(c.Name, "is a citizen of", c.Country)
}

func main() {
    c := Citizen{}
    c.Name = "Steve"
    c.Country = "America"
    c.Talk()
    c.Nationality()
}

Результат:
>  Hi, my name is Steve
>  Steve is a citizen of America

play.golang.org/p/eCEpLkQPR3

Мы наладили имитацию отношения is-a используя анонимное поле структуры, в данном случае поле Person (указывается только тип) у Citizen. Тип Citizen приобрёл все свойства и методы типа Person и имеет возможность дополнить или перекрыть некоторые из этих свойств и методов своими. Например, пусть городские жители будут отвечать немного иначе:

func (c *Citizen) Talk() {
    fmt.Println("Hello, my name is", c.Name, "and Im from", c.Country)
}

Результат:
>  Hello, my name is Steve and Im from America
>  Steve is a citizen of America

play.golang.org/p/jafbVPv5H9

Обратите внимание, что теперь в main вызывается метод *Citizen.Talk() вместо *Person.Talk().

6. Почему анонимные поля не дают полиморфизм

Имеются две причины.

6.1. Остаётся доступ к индивидуальным полям каждого из встроенных типов
Ну, на самом деле это не так уж и плохо, поскольку при множественном «наследовании» становится неочевидно, какой именно метод из родительских классов будет вызван. При использовании анонимного поля Go создаёт вспомогательное поле, дублируя имя типа, поэтому вы всегда сможете обратиться к индивидуальным методам всех анонимных полей, то есть базовых классов в нашей имитации наследовательного механизма. Пример:

func main() {
    c := Citizen{}
    c.Name = "Steve"
    c.Country = "America"
    c.Talk()         // <- Метод доступен
    c.Person.Talk()  // <- Также доступен
    c.Nationality()
}

Результат:
>  Hello, my name is Steve and Im from America
>  Hi, my name is Steve
>  Steve is a citizen of America

6.2. Тип-потомок не становится типом-предком
Если бы полиморфизм был настоящий, анонимное поле заставило бы включающий тип стать включаемым типом, но в Go и включаемый и включающий до конца остаются раздельными. Лучше один раз увидеть, приведём пример:

type A struct {
}

type B struct {
	A // B is-a A
}

func save(A) {
	// xxx
}

func main() {
	b := &B{}
	save(b) // OOOPS! b IS NOT A
}

Результат:
>  prog.go:17: cannot use b (type *B) as type A in function argument
>   [process exited with non-zero status]

play.golang.org/p/EmodogIiQU

Данный пример предложен в этом комментрии с Hacker News. Спасибо, Optymizer.

7. Настоящий полиморфизм подтипов

Интерфейсы в Go — штука довольно уникальная по своей природе. В данном разделе мы сосредоточимся на применении интерфейсов для реализации полиморфизма, что не является их первоочередной задачей.

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

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

Возвращаясь к предыдущему примеру, добавим новую функцию SpeakTo и в main попробуем применить её поочерёдно к экземплярам Citizen и Person.

func SpeakTo(p *Person) {
    p.Talk()
}

func main() {
    p := &Person{Name: "Dave"}
    c := &Citizen{Person: Person{Name: "Steve"}, Country: "America"}

    SpeakTo(p)
    SpeakTo(c)
}

Результат:
>  Running it will result in
>  prog.go:48: cannot use c (type *Citizen) as type *Person in function argument
>  [process exited with non-zero status]

play.golang.org/p/fkKz0FkaEk

Как и предполагалось, конструкция просто неверна. В данном случае Citizen не является Person, даже не смотря на то, что у них общие свойства. Однако, добавим интерфейс Human, сделаем его принимаемым типом функции SpeakTo и вот, всё пошло по плану.

type Human interface {
    Talk()
}

func SpeakTo(h Human) {
    h.Talk()
}

func main() {
    p := &Person{Name: "Dave"}
    c := &Citizen{Person: Person{Name: "Steve"}, Country: "America"}

    SpeakTo(p)
    SpeakTo(c)
}

Результат:
>   Hi, my name is Dave
>   Hi, my name is Steve

play.golang.org/p/vs92w57c5-

Подытоживая, можно сделать два важных замечания про полиморфизм в Go:

  • Используя анонимные поля можно добиться соответствия типа интерфейсу, в том числе одновременного соответствия набору интерфейсов, тем самым достигая почти канонического полиморфизма.
  • Go может обеспечить полиморфизм подтипов во время использования значения (c.Name = "Xlab"), но в действительности же все типы являются обособленными. Как показано в последнем примере, чтобы установить свойство Name у Citizen, мы обязаны явно указать это свойство у Person, присвоив затем объект Person соответствующему полю у Citizen. (речь о составном литерале Citizen{Person: Person{Name: "Steve"}, Country: "America"}).

8. Итоги

Как вы могли наблюдать в примерах выше, фундаментальные принципы объектно-ориентированного подхода актуальны и успешно применяются в Go. Существуют отличия в терминологии, поскольку используются несколько иные механизмы, нежели в других классических языках ООП. Так, для объединения состояния и поведения в одной сущности используются структуры с заданными (прикреплёнными) методами. Для обозначения отношений has-a между типами используются композиция, тем самым минимизируя количество повторений в коде и избавляя нас от бардака с классическим наследованием. Для установления is-a отношений между типами в Go используются интерфейсы, без лишних слов и контрпродуктивных описаний.

Вот так, встречайте новую модель объектно-ориентированного программирования — без объектов!

~ translation & adaptation by Xlab.
См. также: «Повторное использование кода в Go на примере»
Кстати, на всякий случай приведу здесь эту цитату:

I invented the term Object-Oriented and I can tell you I did not have C++ in mind.
— Alan Kay

Что такое объектно-ориентированное программирование? Определение Webopedia

Главная »СРОК» O »

Автор: Ванги Бил

O bject- o riented p rogramming ( OOP ) относится к типу компьютерного программирования (разработка программного обеспечения), в котором программисты определяют тип данных структуры данных, а также типы операций (функции), которые можно применить к структуре данных.

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

Основные концепции ООП

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

  • Абстракция: Процесс выделения (абстрагирования) общих характеристик объектов и процедур.
  • Класс: Категория объектов. Класс определяет все общие свойства различных объектов, которые ему принадлежат.
  • Инкапсуляция: Процесс объединения элементов для создания нового объекта. Процедура — это тип инкапсуляции, поскольку она объединяет серию компьютерных инструкций.
  • Скрытие информации: Процесс скрытия деталей объекта или функции. Скрытие информации — мощный метод программирования, поскольку он снижает сложность.
  • Наследование: функция, которая представляет связь «есть» между различными классами.
  • Интерфейс: языков и кодов, которые приложения используют для связи друг с другом и с оборудованием.
  • Обмен сообщениями: Передача сообщений — это форма связи, используемая в параллельном программировании и объектно-ориентированном программировании.
  • Объект: автономный объект, который состоит из данных и процедур для управления данными.
  • Полиморфизм: Способность языка программирования обрабатывать объекты по-разному в зависимости от их типа данных или класса.
  • Порядок действий: раздел программы, выполняющий определенную задачу.

Преимущества объектно-ориентированного программирования

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

OOPL — языки объектно-ориентированного программирования

An o bject- o riented p rogramming l anguage ( OOPL ) — это язык программирования высокого уровня, основанный на объектно-ориентированной модели. Для выполнения объектно-ориентированного программирования необходим объектно-ориентированный язык программирования.Многие современные языки программирования являются объектно-ориентированными, однако некоторые старые языки программирования, такие как Паскаль, предлагают объектно-ориентированные версии. Примеры объектно-ориентированных языков программирования включают Java, C ++ и Smalltalk.

Первое OOPL

Simula, разработанный в 1960-х годах в Норвежском вычислительном центре в Осло, считается первым объектно-ориентированным языком программирования. Несмотря на то, что Smaslltalk является первым, он считается единственной настоящей объектно-ориентированной средой программирования, с которой следует сравнивать все остальные.Впервые он был разработан для использования в образовательных целях в исследовательском центре Xerox Corporation в Пало-Альто в конце 1960-х годов и выпущен в 1972 году.

Рекомендуемая литература: Учебные пособия Webopedia — Основы Java: переменные, синтаксис и условные обозначения и Основы Java, часть 2: Операторы, модификаторы и структуры.



НОВОСТИ ВЕБОПЕДИИ

Будьте в курсе последних событий в терминологии Интернета с помощью бесплатного информационного бюллетеня Webopedia.Присоединяйтесь, чтобы подписаться сейчас.

.Функциональное программирование

против ООП | 8 основных отличий, которые нужно знать

Различия между функциональным программированием и ООП

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

Функциональное программирование

  • Функциональное программирование также поддерживает такие языки программирования, как Lisp, Clojure, Wolfram, Erlang, Haskell, F #, R и другие известные и предметно-ориентированные языки. Функциональное программирование отлично подходит для работы в области науки о данных, а R — популярный язык среди специалистов по данным.
  • Языки
  • FP могут быть хорошо переведены в интерактивную среду, что упрощает понимание кода.
  • Функциональное программирование обеспечивает такие преимущества, как эффективность, ленивое вычисление, вложенные функции, код без ошибок, параллельное программирование. На простом языке функциональное программирование заключается в написании функции, имеющей операторы для выполнения определенной задачи для приложения.
  • Функцию можно легко вызвать и использовать повторно в любой момент. Это также помогает управлять кодом, и одно и то же не нужно писать снова и снова.
  • Функциональное программирование, основанное на различных концепциях, — это 1. Функции высокого порядка (HOF). 2. Чистые функции. 3. Рекурсия. 4. Строгая и нестрогая оценка. 5. Системы типов. 6. Ссылочная прозрачность. В функциональном программировании функции считаются первоклассными гражданами.

ООП (объектно-ориентированное программирование)

  • Объектно-ориентированное программирование, основанное на следующих основных функциях: 1. Абстракция: Это помогает в предоставлении полезной информации или соответствующих данных пользователю, что повышает эффективность программы и упрощает работу. 2. Наследование: Это помогает в наследовании методов, функций, свойств и полей базового класса в производном классе. 3. Полиморфизм: Он помогает выполнять одну задачу разными способами с помощью перегрузки и переопределения, которые также известны как полиморфизм времени компиляции и времени выполнения соответственно. 4. Инкапсуляция: Помогает скрыть несущественные данные от пользователя и предотвращает несанкционированный доступ пользователя.
  • Объектно-ориентированные языки программирования: C ++, C #, Java, Python, Ruby, PHP, Perl, Objective-C, Swift, Dart, Lisp и т. Д.В объектно-ориентированном приложении объекты можно легко повторно использовать в другом приложении. Новые объекты могут быть легко созданы для одного и того же класса, а код можно легко поддерживать и изменять.
  • Он также имеет функцию управления памятью. Это дает большое преимущество при разработке больших программ, которые можно легко разделить на более мелкие части, и помогает различать компоненты или фазы, которые необходимо выполнить или запланировать определенным образом.

Прямое сравнение функционального программирования и ООП

Ниже приведены 8 лучших сравнений между функциональным программированием и ООП:

.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *