|
|
ОБ’ЄКТНО ОРІЄНТОВАНЕ ПРОГРАМУВАННЯ Електронний посібник |
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Модуль 1 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1. Основні поняття ООП. Об’єктно орієнтований
аналіз та проєктування. Огляд технології JAVA 1.1. Поняття про об’єкти та класи
Об’єкт – єдине ціле даних та методів. Інтерфейс об’єкта –
набір визначень про те, яким чином об’єкт взаємодіє з зовнішніми об’єктами,
сутностями тощо. Об’єкти та їхні інтерфейси визначаються під час проведення
аналізу. З точки зору бізнесу, об’єктно орієнтований дизайн розробляє систему
об’єктів, кожний з яких виконує свою функцію. Наприклад, для певної компанії,
бізнес-об’єкти можуть містити персонал, вироби, устаткування, транспортні
засоби тощо.
Програмісти
спочатку пишуть клас, а на його основі при виконанні програми створюються
конкретні об’єкти (екземпляри класів). На основі класів можна створювати
нові, які розширюють базовий клас і таким чином створюється ієрархія класів.
Таким чином, програма –
це набір об’єктів, що мають стан та поведінку. Об’єкти взаємодіють, використовуючи повідомлення.
Будується ієрархія об’єктів: програма в цілому – це об’єкт, для
виконання своїх функцій вона звертається до об’єктів, що містяться у ньому,
які у свою чергу виконують запит шляхом звернення до інших об’єктів програми.
Звісно, щоб уникнути безкінечної рекурсії у зверненнях, на якомусь етапі
об’єкт трансформує запит у повідомлення до стандартних системних об’єктів, що
даються мовою та середовищем програмування. Стійкість та керованість системи
забезпечуються за рахунок чіткого розподілення відповідальності об’єктів (за
кожну дію відповідає певний об’єкт), однозначного означення інтерфейсів
міжоб’єктної взаємодії та повної ізольованості внутрішньої структури об’єкта
від зовнішнього середовища (інкапсуляції). В результаті
дослідження Деборою Дж. Армстронг комп’ютерної літератури, що була видана
протягом останніх 40 років, вдалось відокремити фундаментальні поняття
(принципи), використані у переважній більшості визначень об’єктно
орієнтованого програмування. До них належить: Клас. Клас визначає
абстрактні характеристики деякої сутності, включаючи характеристики самої
сутності (її атрибути або властивості) та дії, які вона здатна виконувати (її
поведінки, методи або можливості). Наприклад, клас Собака може
характеризуватись рисами, притаманними всім собакам, зокрема: порода, колір
хутра, здатність гавкати. Класи вносять модульність та структурованість в об’єктно орієнтовану програму. Як правило, клас
має бути зрозумілим для непрограмістів, що знаються на предметній області,
що, у свою чергу, значить, що клас повинен мати значення в контексті. Також
код реалізації класу має бути досить самодостатнім. Властивості та методи
класу разом називаються його членами. Об’єкт. Окремий екземпляр
класу (створюється після запуску програми і ініціалізації полів класу). Клас
Собака відповідає всім собакам шляхом опису їхніх спільних рис; об’єкт Сірко
є одним окремим собакою, окремим варіантом значень характеристик. Собака має
хутро; Сірко має коричнево-біле хутро. Характеристика об’єкта може бути іншим
об’єктом. Об’єкт Сірко є екземпляром (примірником) класу Собака. Сукупність
значень атрибутів окремого об’єкта називається станом. На основі класу Собака
можна також створити інший об’єкт Дружок, який відрізнятиметься від об’єкта
Сірко своїм станом (наприклад, кольором хутра). Обидва об’єкти (Сірко і
Дружок) є екземплярами класу Собака. Метод. Можливості об’єкта.
Оскільки Сірко – Собака, він може гавкати. Тому гавкати() є одним із методів
об’єкта Сірко. Він може мати й інші методи, зокрема: місце(), або їсти(). В
межах програми, використання методу має впливати лише на один об’єкт; всі
Собаки можуть гавкати, але треба щоб гавкав лише один окремий собака. Обмін повідомленнями. "Передача
даних від одного процесу іншому, або надсилання викликів методів". Успадкування (наслідування). Клас може мати "підкласи",
спеціалізовані, розширені версії надкласу. Можуть навіть утворюватись цілі
дерева успадкування. Наприклад, клас Собака може мати підкласи Коллі,
Пекінес, Вівчарка та ін. Так, Сірко може бути екземпляром класу Вівчарка.
Підкласи успадковують атрибути та поведінку своїх батьківських класів, і
можуть вводити свої власні. Успадкування може бути одиничне (один
безпосередній батьківський клас) та множинне (кілька батьківських класів). Це
залежить від вибору програміста, який реалізовує клас та мови програмування.
Так, наприклад, в Java дозволене лише одинарне успадкування, а в С++ і те, і
інше. Приховування інформації (інкапсуляція). Приховування деталей про
роботу класів від об’єктів, що їх використовують або надсилають їм
повідомлення. Так, наприклад, клас Собака має метод гавкати(). Реалізація
цього методу описує як саме повинно відбуватись гавкання (наприклад, спочатку
вдихнути(), а потім видихнути() на обраній частоті та гучності). Петро,
хазяїн пса Сірка, не повинен знати як він гавкає. Інкапсуляція досягається
шляхом вказування, які класи можуть звертатися до членів об’єкта. Як
наслідок, кожен об’єкт представляє кожному іншому класу певний інтерфейс –
члени, доступні іншим класам. Інкапсуляція потрібна для того, аби запобігти
використанню користувачами інтерфейсу тих частин реалізації, які, швидше за
все, будуть змінюватись. Це дозволить полегшити внесення змін, тобто без
потреби змінювати і користувачів інтерфейсу. Наприклад, інтерфейс може
гарантувати, що щенята можуть додаватись лише до об’єктів класу Собака кодом
самого класу. Часто члени класу позначаються як публічні (англ. public),
захищені (англ. protected) та приватні (англ. private), визначаючи, чи
доступні вони всім класам, підкласам, або лише класу, в якому їх визначено.
Деякі мови програмування йдуть ще далі: Java використовує ключове слово
private для обмеження доступу, що буде дозволений лише з методів того самого
класу, protected – лише з методів того самого класу і його нащадків та з
класів із того ж самого пакету, C# та VB.NET відкривають деякі члени лише для
класів із тієї ж збірки шляхом використання ключового слова internal (C#) або
Friend (VB.NET), а Eiffel дозволяє вказувати, які класи мають доступ до
будь-яких членів. Абстрагування. Спрощення складної
дійсності шляхом моделювання класів, що відповідають проблемі, та
використання найприйнятнішого рівня деталізації окремих аспектів проблеми.
Наприклад, Собака Сірко більшу частину часу може розглядатись як Собака, а
коли потрібно отримати доступ до інформації специфічної для собак породи
коллі – як Коллі і як Тварина (можливо, батьківський клас Собака) при
підрахунку тварин. Поліморфізм. Поліморфізм означає
залежність поведінки від класу, в якому ця поведінка викликається, тобто два
або більше класів можуть реагувати по-різному на однакові повідомлення.
Наприклад, якщо Собака отримує команду голос(), то у відповідь можна отримати
Гав; якщо Свиня отримує команду голос (), то у відповідь можна отримати
Рох-рох. На практиці це реалізовується шляхом реалізації низки підпрограм
(функцій, процедур, методів тощо) з однаковими іменами, але з різними
параметрами. Залежно від того, що передається, і вибирається відповідна
підпрограма.
Об'єкт – конкретний
екземпляр класу. Наприклад, зелена "Тойота" вашого сусіда є
екземпляром класу "Автомобіль". По суті, це клас, поля якого
ініціалізовані і він завантажений у пам'ять комп'ютера. На основі одного
класу, можна створити безліч об'єктів. Дані в об’єкті
(тобто глобальні змінні даного об’єкта) називаються полями (атрибутами) екземпляру класу. Процедури, які
оперують даними, називаються методами (операціями). Специфічний
об’єкт, який є екземпляром певного класу, матиме специфічні значення
екземплярних полів. Сукупність цих значень називається станом об’єкта. Коли викликається певний метод, стан об’єкта може
змінюватись. Згідно з принципом інкапсуляції намагаються, щоб доступ до
приватних полів екземпляра здійснювався лише за допомогою відповідних
публічних методів.
Об'єкт може
існувати самостійно. До цього об'єкту можна ставити запитання за допомогою
методів і ці самі методи можу давити відповідь, повертаючи значення. Щоб створити об’єкт
певного класу, програміст викликає один з його конструкторів. Це
спеціальні методи, які покликані задати об'єкту початковий стан і носять його
ім'я.
Проте такий підхід
застосовується, якщо об’єкт потрібен нам в програмі лише раз. Якщо ж його
потрібно буде використати повторно, то для цього використовуються об'єктні
змінні – змінні, які посилаються на певний об’єкт.
Декларація типу
посилання не створює об'єкт! Оператор new
створює екземпляр об'єкта, виділяючи під нього пам'ять. Цей оператор
має лише один постфіксний аргумент – виклик конструктора, і повертає
посилання на створений об'єкт. Необов'язково присвоювати змінній посилання на
створений об'єкт:
Посилання на
об'єкти також передаються в методи за значенням. Це означає, що коли метод завершить свою роботу,
передане посилання як і раніше буде вказувати на той же об'єкт, що і
вказувало до виклику методу. Проте значення полів об'єкта можуть бути
змінені в методі, якщо вони мають відповідний рівень доступу. Наприклад, маємо
клас виду
та метод, що
використовує посилання на нього
Після виконання
наступного коду:
Матимемо на екрані 20; При цьому в пам'яті
JVM буде два об'єкти типу Demo, на один з яких відсутнє
посилання!
Якщо конструктор
явно не створити, то все одно він буде створений за замовчуванням. Перевантажений конструктор викликається залежно від параметрів, зазначених при
виконанні операції new.
Що таке Java? Створюючи програми більшістю мов програмування,
треба визначити, в якій операційній системі і на якому процесорі вони
працюватимуть. Тільки визначивши це, можна долучити до програми виклик
функцій з бібліотеки, призначеної для відповідної операційної системи.
Наприклад: якщо розробляють програму для Windows, то можна використати
бібліотеку Microsoft Foundation Classes; для роботи на платформі Macintosh −
функції з Mac OS Toolbox. Після компіляції вихідних текстів отримуємо код,
готовий до виконання на певному процесорі. Створюючи програми
на Java, можна не замислюватися над тим, в якій операційній системі вони
працюватимуть. Java має власний набір машинно-незалежних бібліотек,
які називають пакетами. Щодо процесорів
ситуація аналогічна. Компілятор Java не генерує безпосередньо інструкції
процесору. Він створює проміжний код − байткод для віртуальної
машини Java (Java Virtual Machine − JVM). Виходячи з того, що ядро
віртуальної машини Java реалізовано практично для всіх типів комп’ютерів,
вважатимемо файли байткодів незалежними від платформи. Започатковано мову
Java у проєкті фірми Sun Microsystems під назвою Green (1991). Головними
розробниками першої робочої версії були Джеймс Гослінг (James
Gosling), Патрік Ноутон (Patric Naughton), Кріс Ворс (Chris
Warth), Ед Френк (Ed Frank) і Майкл Шерідан (Mike Sheridan). До
1995 року мову називали Оак, однак не пройшовши перевірку на
допустимість торгової марки, було перейменовано на Java. Ідеєю створення
нової мови програмування були не потреби інтернету, а необхідність створення
програмного забезпечення, яке не залежить від платформи (тобто архітектури) і
використовується в побутових електронних приладах. Під час
відпрацювання деталей Java виник вагомий чинник, який відіграв важливу роль
щодо цієї мови. Таким чинником була всесвітня інформаційна служба World Wide
Web (WWW), розквіт якої припадає на 1994−1995 р. Ідеї створення
ефективних і незалежних (працюючих на різноманітних процесорах під
керівництвом різних операційних систем) програм такі ж давні, як і саме
програмування, і завжди витіснялися нагальнішими проблемами. Якщо зважити на
те, що більшість програмістів належить до одного з трьох кланів (Windows, Mac
OS, UNIX/Linux), які безупинно змагаються між собою, то зрозумілим стає те,
що нагальної потреби в переміщенні коду довший час не виникало. Проте
з виникненням інтернету і WWW проблема переміщення програм стала
втричі гострішою. Різко змінилися акценти: від створення коду для вбудованих
контролерів побутової техніки до програмування для інтернету. Це і
спричинило великий успіх мови Java. Після виникнення в
1979 р. мови С++, до якої було додано порівняно з мовою С об’єктно
орієнтовані засоби і збережено усі сильні сторони С, складається враження, що
програмісти знайшли нарешті досконалу мову. Проте навіть могутня і популярна
мова програмування має свої недоліки. Це важкі щодо розуміння і
використання аспекти С++, пов’язані з керуванням пам’яттю і покажчиками. У
С++ також легко зберігається процедурний стиль програмування. Згідно з думкою
П. Нортона, наступним кроком у логічному розвитку мов програмування є Java.
Ця мова опирається на найпопулярнішу мову С++ (розробники Java зробили це
свідомо), проте цілковито відкидає поняття процедурного програмування і
змушує підкорятися принципам об’єктно орієнтованого програмування (ООП).
У мові Java відсутні покажчики, а керування пам’яттю відбувається
автоматично. Зважаючи на
подібність мов Java та С++, дехто вважає, що Java − це інтернет-версія
С++. Насправді це не так. Незважаючи на значний вплив С++ на створення Java,
у них не існує ніякої сумісності (ні зверху вниз, ні знизу вверх). Крім того,
цю мову не розроблено з метою заміни С++. Мову С++ застосовують для вирішення
одних проблем, мову Java − для інших. Найважливіша з них − створення
програм, які не залежать від платформ виконання.
Простота, інтерпретація, перенесення,
незалежність від архітектури. До простих мов програмування належать ті, які
працюють з інтерпретатором (наприклад, Бейсік). Перші персональні
комп’ютери поставлялися з інтерпретатором Бейсіка. Сьогодні їхнє місце
займають HTML і мови сценаріїв для Web. Вивчати і використовувати мови
програмування, які компілюються, набагато складніше, ніж ті, які інтерпретуються.
Тобто є мови програмування для професіоналів. Наприклад, С++, де використання
покажчиків і керування пам’яттю є складними не тільки для початківців, але й
для досвідчених програмістів. Один рядок програми, який звертається до
недозволеного місця в пам’яті, може спричинити сбої не тільки програми, але й
комп’ютера загалом.
Байткод дуже
відрізняється від машинного коду, який є послідовністю нулів та одиничок. Байткод −
це набір інструкцій, які подібні до команд Асемблера. Машинний код комп’ютер виконує безпосередньо, а
байткод потрібно інтерпретувати. Тому машинний код можна використати тільки
на конкретній платформі, для якої його скомпільовано. Байткод можна
виконувати на будь-якій платформі, на якій встановлено виконавче середовище
Java. Саме ця можливість і робить програми на Java незалежними від
архітектури. Оскільки байткод є проміжною формою програми, то його
інтерпретація вимагає незначних витрат. Байткод створено для машини, яка
реально не існує. Цю машину називають віртуальною
Java-машиною (JVM), вона існує тільки в пам’яті комп’ютера. Створення
компілятором Java байткоду для неіснуючої машини − це тільки половина
процесу, який забезпечує незалежність від архітектури. Другу частину виконує інтерпретатор
Java, який виконує роль посередника між віртуальною Java-машиною та
реальним комп’ютером. Архітектура мови для розподіленого
мережевого середовища. Головною вимогою щодо мови для роботи в
розподіленому просторі комп’ютерів (наприклад, в інтернеті) – це можливість
працювати на різнорідних і розподілених платформах. Мова Java є пристосованою
до перенесення завдяки підтримці стандартів IEEE для структур даних,
наприклад, цілих чисел, чисел з плаваючою комою і рядків. До мови Java
включено безпосередньо підтримку таких розповсюджених протоколів, як FTP,
HTTP, що забезпечує сумісність під час роботи в мережі. Java забезпечує
розподілену роботу за допомогою механізму виклику віддалених методів
(RMI), тобто дає змогу використовувати об’єкти, розташовані на локальних і
віддалених машинах. Багатопотоковість. У багатопотокових
операційних системах для кожного застосування (процесу) надається окрема захищена
область пам’яті, в якій зберігаються коди програми і дані. А час одного
процесора квантується між цими процесами. З метою запуску процесу або
переключення з одного на інший на рівні операційної системи необхідно
виконати значний обсяг роботи. Тому для розробників прикладних програм
спеціально створили "полегшену" версію системного процесу − потік.
Найбільшою проблемою, пов’язаною з процесами і потоками, є їхнє
функціонування під керуванням конкретної операційної системи. Спеціалісти
компанії Sun зробили потоки частиною мови програмування. Тому багатопотокове
застосування, написане мовою Java, працюватиме і в операційних середовищах
Windows, Unix, Mac OS. Висока продуктивність. Інтерпретатор Java
може виконувати байткоди зі швидкістю, яка наближається до швидкості
виконання коду, відкомпільованого до машинного формату, що досягається
завдяки використанню інтерпретатором багатьох потоків виконання.
Наприклад, доки комп’ютер чекає на введення даних, фонові потоки можуть
зайнятися очищенням пам’яті. Стійкість до помилок. Java −
це мова строгого використання типів, що зумовлює зменшення числа помилок під
час написання програми. У мові Java відбувається автоматична перевірка
виконання граничних умов під час роботи з масивами і рядками, які в Java
є класами. В Java немає арифметики покажчиків, а керування пам’яттю
здійснюється автоматично. Програмний код, написаний мовою Java, не може
послатися на пам’ять поза простором програми або зробити помилку внаслідок
вивільнення пам’яті і тим самим вичерпати всю пам’ять. Зазначимо, що у Java
організовано процес автоматичного збирання сміття, тобто об’єктів, на
які більше ніхто не вказує. Безпека. Функції
забезпечення безпеки дуже важливі для розподілених мереж з безліччю вірусів,
"троянських коней" та ін. Для реалізації цієї мети розробники мови
Java створили механізм, який отримав назву пісочниці (sandbox):
Мова значно
запозичила синтаксис із C і C++.
Зокрема взято за основу об'єктну модель С++, проте її модифіковано. Усунуто
можливість появи деяких конфліктних ситуацій, що могли виникнути через
помилки програміста та полегшено сам процес розробки об'єктно орієнтованих
програм. Значну кількість дій, які в С/C++ повинні здійснювати програмісти,
доручено віртуальній машині. Передусім, Java розроблялась як платформо-незалежна
мова, тому вона має менше низькорівневих можливостей для роботи з
апаратним забезпеченням. За необхідності таких дій, Java дозволяє викликати підпрограми, написані іншими
мовами програмування. Java вплинула на
розвиток J++, що розроблялась компанією Microsoft. Роботу над J++ було
зупинено через судовий позов компанії Sun Microsystems, оскільки ця мова
програмування була модифікацією Java. Пізніше в новій платформі Microsoft
.NET випустило J#, щоб полегшити міграцію програмістів J++ або Java на нову
платформу. З часом нова мова програмування C# стала основною мовою
платформи, перейнявши багато чого з Java. J# востаннє включався в версію Microsoft
Visual Studio 2005. Мова сценаріїв JavaScript має схожу із Java назву і
синтаксис, але не пов'язана із Java. Java дозволяє
створювати самодостатні програми для різних операційних систем, як то
Windows, Linux тощо. Крім того, Java широко застосовується для програмування
різних пристроїв, наприклад, мобільних телефонів, на ній також пишуться
комп'ютерні ігри для них, створюють також програми для інтернету – Аплети
(вважаються небезпечними, тож більше не підтримуються вебоглядачами) і
програми для серверів – Сервлети та JSP (Java Server Pages). Дещо про випуски
Java та їх найменування. 19 березня 2020 року вийшла вже 14 версія Java.
Назви випусків подавалися розробниками Java дещо по-різному, що створило в
літературі деяку плутанину. Спочатку писали JDK 1.0, JDK 1.1 (JDK – Java
Development Kit). Після появи версії 1.2 у випусках Java почали в назві
писали Java2SE, наприклад, J2SE 1.4 (SE – це Standart Editon, крім
того, додатково йдуть випуски EE – Enterprise Edition, ME – Mobile Edition).
П'яту ж версію почали писати J2SE 5.0, а далі викинули 2 з назви і почали
писати Java SE 6. Різкі зміни в найменуванні передусім пояснювалися
ґрунтовними переробками в Java. За історію Java найсерйозніші зміни були
внесені у версію 1.2, відповідно це пояснює появу 2-ки в назвах випусків.
Наступний перегляд був у версії 1.5. В Java SE 8 одним з основних нововведень
стали лямбда-вирази.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||