У першому семестрі нас ознайомили з такими поняттями OOP, як інкапсуляція, приховування даних, модульність, успадкування тощо тощо через Java та UML. (Java - моя перша мова програмування)
Жодне з них не є концепціями ООП. Всі вони існують за межами ОО, незалежні від ОО, і багато навіть були винайдені перед ОО.
Отже, якщо ви вважаєте, що це все, що стосується ОО, то ваш висновок правильний: ви можете зробити все це на процедурних мовах, оскільки вони не мають нічого спільного з ОО .
Наприклад, одна з наглядових робіт про модульність - про критерії, які слід використовувати у розкладанні систем на модулі . Там немає згадки про ОО. (Це було написано в 1972 році, тодішній ОО ще був незрозумілою нішею, незважаючи на те, що йому вже було більше десяти років.)
Хоча абстракція даних є важливою для ОО, вона є скоріше наслідком первинної ознаки ОО (обміну повідомленнями), ніж визначальною. Також дуже важливо пам’ятати, що існують різні види абстрагування даних. Два найпоширеніші види абстрагування даних, які використовуються сьогодні (якщо ми ігноруємо "ніякої абстракції", яка, ймовірно, все ще використовується більше, ніж інші дві комбіновані), - це абстрактні типи даних та об'єкти . Отже, просто кажучи «Приховування інформації», «Інкапсуляція» та «Абстракція даних», ви нічого не сказали про ОО, оскільки ОО є лише однією формою абстрагування даних, а дві фактично принципово різні:
- При абстрактних типах даних механізмом абстракції є система типів ; саме система типів приховує реалізацію. (Система типів не обов'язково повинна бути статичною.) З об'єктами реалізація прихована за процедурним інтерфейсом , який не потребує типів. (Наприклад, він може бути реалізований із закриттями, як це робиться в ECMAScript.)
- Завдяки абстрактним типам даних екземпляри різних ADT інкапсульовані один від одного, але екземпляри одного ADT можуть перевіряти та отримувати доступ до представництва та приватної реалізації інших. Об'єкти завжди капсульовані від усього . Тільки об'єкт сам може перевірити своє власне представництво і доступ до власним реалізації. Жоден інший об'єкт , навіть інші об'єкти одного типу, інші екземпляри одного класу, інші об'єкти, що мають той самий прототип, клони об'єкта або що-небудь інше. Немає .
До речі, це означає, що в Java класи не є об'єктно-орієнтованими. Два екземпляри одного класу можуть отримати доступ до представлення один одного та приватної реалізації. Тому екземпляри класів не є об'єктами, вони фактично є ADT. Java interface
s, проте, дійсно забезпечують об'єктно-орієнтованої абстракції даних. Отже, іншими словами: у Java є об'єктами лише екземпляри інтерфейсів, екземпляри класів - ні.
В основному для типів можна використовувати лише інтерфейси. Це означає, що типи параметрів методів та конструкторів, типи повернень методів, типи полів екземплярів, статичні поля та локальні поля, аргумент instanceof
оператору чи оператору керування та аргументи типу для конструктора загального типу завжди повинні бути інтерфейсами. Клас може використовуватися лише безпосередньо після new
оператора, ніде більше.
Наприклад, для модульності ми можемо просто розділити програму на багато невеликих програм, які виконують чітко визначені завдання, код яких міститься в окремих файлах. Ці програми взаємодіють одна з одною через їх чітко визначений вхід та вихід. Файли можуть бути захищені (зашифровані?) Для досягнення інкапсуляції. Для повторного використання коду ми можемо просто викликати ці файли, коли вони знадобляться в нових програмах. Хіба це не охоплює все, що є OOP, або я пропускаю щось дуже очевидне?
Те, що ви описуєте, є ОО.
Це дійсно хороший спосіб подумати про ОО. Насправді, це саме те, що мали на увазі оригінальні винахідники ОО. (Алан Кей пішов на крок далі: він передбачив безліч маленьких комп'ютерів, що надсилають повідомлення один одному через мережу.) Те, що ви називаєте "програмою", зазвичай називають "об'єктом", а замість "дзвінка" ми зазвичай кажемо "надішліть повідомлення ".
Об'єктна орієнтація стосується Повідомлень (також динамічної диспетчеризації ). Термін "Орієнтований на об'єкт" був введений доктором Аланом Кей, головним дизайнером Smalltalk, і він визначає це так :
OOP для мене означає лише обмін повідомленнями, локальне збереження та захист та приховування державно-процесу, а також надзвичайне запізнення всіх речей.
Розберемо це:
- обмін повідомленнями ("віртуальний метод відправки", якщо ви не знайомі з Smalltalk)
- державний процес повинен бути
- локально зберігається
- захищені
- приховано
- крайнє пізнє зв’язування всіх речей
По мірі впровадження, обмін повідомленнями - це запізнілий виклик процедури, і якщо виклики процедури запізніли, то ви не можете знати в час проекту, що ви збираєтесь викликати, тому ви не можете робити жодних припущень щодо конкретного подання стану. Отже, насправді мова йде про обмін повідомленнями, пізнє зв’язування - це реалізація повідомлень, а інкапсуляція є наслідком цього.
Пізніше він уточнив, що " велика ідея - це" обмін повідомленнями ", і шкодує, що назвав її" об'єктно-орієнтованою "замість" орієнтованою на повідомлення ", оскільки термін" об'єктно-орієнтований "ставить акцент на неважливу річ (об'єкти) ) і відволікає від того, що дійсно важливо (обмін повідомленнями):
Лише ніжне нагадування про те, що я взяв певні болі на останньому OOPSLA, щоб спробувати нагадати всім, що Smalltalk - це не лише НЕ його синтаксис чи бібліотека класів, мова навіть не про класи. Мені шкода, що я давно придумав для цієї теми термін «об’єкти», оскільки це змушує багатьох людей зосередитися на меншій ідеї.
Велика ідея - це "обмін повідомленнями" - саме про це і полягає ядро Smalltalk / Squeak (і це те, що ніколи не було завершено в нашій фазі Xerox PARC). У японців є невелике слово - ma - для "того, що знаходиться між ними" - можливо, найближчий англійський еквівалент "interstitial". Ключове значення у створенні чудових та розростаючих систем - це набагато більше, щоб розробити те, як його модулі спілкуються, а не якими мають бути їх внутрішні властивості та поведінка. Подумайте про Інтернет - щоб жити, він (а) повинен дозволити багато різних ідей та реалізацій, що виходять за межі будь-якого єдиного стандарту, і (b) дозволяти різного ступеня безпечної взаємодії між цими ідеями.
(Звичайно, сьогодні більшість людей навіть не зосереджуються на предметах, а на заняттях, що ще більше неправильно.)
Повідомлення є основним для ОО як метафори, так і як механізму.
Якщо ви надіслаєте комусь повідомлення, ви не знаєте, що вони з ним роблять. Тільки річ , яку ви можете спостерігати, їх відповідь. Ви не знаєте, чи обробляли вони повідомлення самостійно (тобто, якщо об'єкт має метод), чи пересилали повідомлення комусь іншому (делегування / надання доступу), якщо вони навіть розуміли його. Ось в чому полягає інкапсуляція, ось про що йдеться ОО. Ви навіть не можете відрізнити проксі від реального, якщо він відповідає, як ви цього очікуєте.
Більш "сучасним" терміном "обмін повідомленнями" є "динамічне відправлення методу" або "віртуальний виклик методу", але це втрачає метафору і фокусується на механізмі.
Отже, є два варіанти визначення визначення Алана Кей: якщо ви дивитесь на це самостійно, ви можете помітити, що повідомлення в основному є запізненням виклику процедури, а пізнє зв'язування передбачає інкапсуляцію, тому ми можемо зробити висновок, що №1 і №2 насправді надлишкові, і OO - все про пізнє зв’язування.
Однак пізніше він уточнив, що важливою справою є обмін повідомленнями, і тому ми можемо дивитись на це з іншого кута: обмін повідомленнями запізнюється. Тепер, якби обмін повідомленнями був єдиним можливим, то №3 тривіально відповідає дійсності: якщо є лише одне, а ця річ є пізньою, то всі речі запізнілими. І ще раз, інкапсуляція випливає з обміну повідомленнями.
Подібні пункти також зроблені в On Розуміння даних абстракцією, Revisited по Вільям Р. Кук , а також його пропозиція щодо спрощення, сучасні визначення «об'єкта» і «об'єктно - орієнтованого» :
Динамічна відправка операцій є істотною характеристикою об'єктів. Це означає, що операція, яку слід викликати, є динамічною властивістю самого об'єкта. Операції неможливо ідентифікувати статично, і взагалі немає способу [знати], що саме виконає операція у відповідь на заданий запит, за винятком її виконання. Це точно так само, як і з першокласними функціями, які завжди динамічно розсилаються.
У Smalltalk-72 навіть об’єктів не було! Були лише потоки повідомлень, які були розібрані, переписані та перепрограні. Спочатку з'явилися методи (стандартні способи розбору та перенаправлення потоків повідомлень), пізніше з'явилися об'єкти (групування методів, які поділяють деякий приватний стан). Успадкування з'явилося набагато пізніше, і заняття були запроваджені лише як спосіб підтримки спадщини. Якби дослідницька група Кей вже знала про прототипи, вони, ймовірно, ніколи б не вводили заняття в першу чергу.
Бенджамін Пірс у типах та мовах програмування стверджує, що визначальною особливістю об'єктно-орієнтованої діяльності є відкрита рекурсія .
Отже: за словами Алана Кей, OO - все про обмін повідомленнями. За словами Вільяма Кука, OO полягає в диспетчеризації динамічних методів (це дійсно те саме). За словами Бенджаміна Пірса, все стосується відкритої рекурсії, що в основному означає, що самонавіювання динамічно вирішується (або, принаймні, це спосіб задуматися), або, іншими словами, повідомленнями.
Як бачите, людина, яка ввела термін "ОО", має досить метафізичний погляд на об'єкти, Кук має досить прагматичний погляд, а Пірс - дуже суворий математичний погляд. Але важливо: філософ, прагматик і теоретик всі згодні! Повідомлення - це один стовп ОО. Період.
Зауважте, що тут не йдеться про спадщину! Спадкування не є важливим для ОО. Загалом, більшість мов OO мають певний спосіб повторного використання, але це не обов'язково має бути спадком. Наприклад, це може бути якась форма делегування. Насправді, Орландоський договір обговорює делегування як альтернативу успадкування та те, як різні форми делегування та спадкування призводять до різних пунктів дизайну в просторі дизайну об'єктно-орієнтованих мов. (Зауважте, що насправді навіть мовами, які підтримують успадкування, як, наприклад, Java, людей насправді вчать уникати цього, знову ж таки вказуючи, що це не потрібно для ОО.)