Об'єктно-орієнтоване програмування

Об'єктно-орієнтоване програмування

Перш ніж заглибитися в JavaScript, давайте трохи розглянемо, що люди мають на увазі, коли кажуть «об’єктно-орієнтований», і які основні особливості цього стилю програмування. Ось перелік понять, які найчастіше використовуються при розмові про об’єктно-орієнтоване програмування (ООП):

  1. Об'єкт, метод, властивість
  2. Клас
  3. Капсуляція
  4. Агрегація
  5. Багаторазове використання / успадкування
  6. Поліморфізм

Класи

У реальному житті подібні об’єкти можна групувати за певними критеріями. Колібрі та орел - це обидва птахи, тому їх можна віднести до класу птахів. В ООП клас - це проект або рецепт об’єкта. Інша назва "об'єкта" - "екземпляр", тому ми говоримо, що орел є екземпляром класу Птахи. Ви можете створювати різні об’єкти, використовуючи один і той же клас, оскільки клас - це лише шаблон, тоді як об’єкти - це конкретні екземпляри, засновані на шаблоні. Існує різниця між JavaScript та "класичними" мовами OO, такими як C ++ та Java. Ви повинні зрозуміти з самого початку, що в JavaScript немає класів; все базується на об’єктах. JavaScript має поняття прототипів, які також є об'єктами (ми обговоримо їх далі детально). Класичною мовою OO ви б сказали щось на зразок "створити мені новий об'єкт під назвою Боб, який має клас Person". На прототиповій мові OO ви сказали б: "Я візьму цей об'єкт, якого я маю, і використаю його як прототип для нового об'єкта, який я буду називати Боб".

Також корисно визначити клас об’єктів, які мають певні властивості. Члени або екземпляри класу мають власні властивості утримувати або визначати їх стан, але вони також мають методи, що визначають їх поведінку. Ці методи визначаються класом і спільно використовуються усіма екземплярами. Уявіть собі клас на ім’я Складний, який представляє та виконує арифметику над комплексними числами, наприклад. Екземпляр Складного має властивості утримувати дійсну та уявну частини (стан) комплексного числа. А клас Складний визначав би методи, що дозволяють виконувати додавання та множення (поведінку) цих чисел. У JavaScript класи використовують успадкування, засноване на прототипі: якщо два об'єкти успадковують властивості (як правило, властивості, що мають функцію, або методи) від одного прототипу, ми говоримо, що ці об'єкти є екземплярами одного класу. У двох словах, так працюють класи JavaScript. JavaScript завжди дозволяв визначення класів. ES6 представив абсолютно новий синтаксис (включаючи ключове слово класу), що полегшує створення класів. Ці нові класи JavaScript працюють так само, як і класи старого стилю, і ця сторінка починається з пояснення старого способу створення класів, оскільки це чіткіше демонструє, що відбувається за лаштунками, щоб змусити класи працювати. Ми почнемо використовувати новий, спрощений синтаксис визначення класу. Якщо ви знайомі з звісними об’єктно-орієнтованими мовами програмування, такими як Java або C ++, ви помітите, що класи JavaScript значно відрізняються від класів на цих мовах. Є деякі синтаксичні подібності, і ви можете наслідувати багато особливостей «класичних» класів у JavaScript, але найкраще заздалегідь зрозуміти, що класи JavaScript та механізм успадкування на основі прототипів суттєво відрізняються від класів та заснований на механізмі успадкування Java та подібних мов.

Інкапсуляція

Інкапсуляція - це ще одна концепція, пов’язана з ООП, яка ілюструє той факт, що об’єкт містить (інкапсулює) як:

  • Дані (що зберігаються у властивостях),
  • Так і засоби зробити щось із даними (за допомогою методів)

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

Уявіть собі предмет, скажімо MP3-плеєр. Вам, як користувачеві об’єкта, надається певний інтерфейс для роботи, наприклад, кнопки, дисплей тощо. Ви використовуєте інтерфейс, щоб змусити об’єкт зробити щось корисне для вас, наприклад, відтворення пісні. Як саме це працює зсередини, ви не знаєте і, найчастіше, вам все одно. Іншими словами, реалізація інтерфейсу від вас прихована. Те саме відбувається в ООП, коли ваш код використовує об'єкт, викликаючи його методи. Не має значення, чи ви кодували об’єкт самостійно, чи він надійшов із сторонніх бібліотек; ваш код не повинен знати, як методи працюють усередині. У компільованих мовах ви насправді не можете прочитати код, що змушує об’єкт працювати. У JavaScript, оскільки мова інтерпретується, ви можете бачити вихідний код, але концепція залишається незмінною - ви працюєте з інтерфейсом об'єкта, не турбуючись про його здійснення.

Іншим аспектом приховування інформації є видимість методів та властивостей. У деяких мовах об’єкти можуть мати загальнодоступні, приватні та захищені методи та властивості. Ця категоризація визначає рівень доступу користувачів об'єкта. Наприклад, лише внутрішня реалізація об'єкта має доступ до приватних методів, тоді як хтось має доступ до загальнодоступних. У JavaScript усі методи та властивості є загальнодоступними, але ми побачимо, що існують способи захистити дані всередині об’єкта та досягти конфіденційності.

Агрегація

Об’єднання кількох об’єктів у новий - це агрегація або композиція. Концепція агрегації ілюструє можливість об'єднання кількох об'єктів в новий. Агрегація - це потужний спосіб розділити проблему на більш дрібні та керовані частини (розділити та завоювати). Коли сфера проблеми настільки складна, що неможливо продумати її на детальному рівні в цілому, ви можете розділити проблему на кілька менших областей, а потім, можливо, розділити кожну з них на ще менші шматки. Це дозволяє думати про проблему на декількох рівнях абстракції. Персональний комп’ютер - це дуже складний об’єкт. Ви не можете думати про все, що має статися під час запуску комп’ютера. Але ви можете абстрагувати проблему, сказавши, що вам потрібно ініціалізувати об’єкти, з яких вона складається: об’єкт Монітор, об’єкт Миша, об’єкт Клавиатура тощо. Тоді ви зможете зануритися глибше в кожен з підоб’єктів. Таким чином ви складаєте складні предмети, збираючи деталі, що використовуються багаторазово. Щоб використати іншу аналогію, об’єкт Книга може містити (об’єднувати) один або декілька об’єктів автора, об’єкт видавця, кілька об’єктів розділів, зміст тощо.

Успадкування

Успадкування - це дуже елегантний спосіб повторного використання вже написаного коду. Наприклад, у вас може бути загальний об’єкт Person, який має такі властивості, як ім’я та дата народження, і який реалізує функціонал ходити, говорити, спати, їсти. Тоді ви зрозумієте, що вам потрібен програміст об’єктів. Ви можете повторно реалізувати всі методи та властивості, якими володіє Людина, але розумніше було б просто сказати, що Програміст успадковує Людину, і заощадити собі трохи роботи. Об'єкту Програміста потрібно лише реалізувати більш конкретну функціональність, таку як метод "писати код", одночасно використовуючи всю функціональність Людини. У класичному ООП класи успадковуються від інших класів, але в JavaScript, оскільки класів немає, об’єкти успадковуються від інших об’єктів. Коли об’єкт успадковується від іншого об’єкта, він зазвичай додає нові методи до успадкованих, розширюючи, таким чином, старий об’єкт. Часто такі фрази можна використовувати як взаємозамінні: "B успадковує від A" і "B продовжує A". Крім того, об'єкт, який успадкував низку методів, може вибрати один або кілька методів і перевизначити їх, налаштувавши під свої потреби. Таким чином, інтерфейс залишається незмінним, назва методу однакова, але при виклику нового об’єкта метод поводиться по-різному. Цей спосіб перевизначення того, як працює успадкований метод, відомий як перевизначення.

Поліморфізм

У наведеному вище прикладі ми мали об’єкт Програміста, який успадкував усі методи батьківського об’єкта Person. Це означає, що обидва об'єкти забезпечують метод "розмови", серед іншого. А тепер уявіть, що десь у нашому коді є змінна під назвою Боб, і трапляється так, що ми не знаємо, є Боб людиною чи об'єктом програміста. Ми все ще можемо викликати метод "говорити" на об'єкті Боб, і код буде працювати. Ця здатність викликати один і той же метод на різних об’єктах і змусити кожного з них реагувати по-своєму називається поліморфізмом.

Підсумок ООП

Якщо ви новачок у жаргонній програмі OO, і не впевнені, що повністю зрозуміли наведені вище поняття, не хвилюйтеся. Я розгляну деякий код, і ви побачите, що, хоча вони можуть здатися складними, коли просто говорять про концепції високого рівня, на практиці все набагато простіше.