Об'єктно-орієнтоване програмування (ООП) - значно змінило підхід до програмування увівши у вжиток цілий ряд понять і зокрема такі поняття як клас та об'єкти (екземпляри класу).
Парадигма ООП Парадигма(ідеологія) об’єктно-орієнтованого програмування (ООП) в даний час стала домінувати в програмному світі. Вона прийшла на зміну структурній техніці програмування, що була розроблена в 1970. Java є повністю об’єктно-орієнтованою мовою, тому потрібно засвоїти принципи ООП якомога краще.
В структурному програмуванні передбачалася розробка окремих алгоритмів та процедур для вирішення конкретної задачі. Такий підхід виправдує себе для невеликих задач, проте для великих проектів ООП більш виправдане. В літературі можна знайти приклад, що для реалізації простого веб-браузера необхідно близько 2000 процедур при структурному програмування. При використанні ж ООП можна створити 100 класів з приблизно 20-ма процедурами(далі методами) в кожному з них. Таким чином набагато простіше шукати помилку серед 20-ти методів одного класу ніж шукати її серед 2000 методів.
Як уже говорилося раніше: клас – це певний шаблон, який слугує для створення об’єктів. Ви можете розробити власний клас, а можете отримати його від інших розробників. В інтернеті зараз є чимало бібліотек класів різноманітного призначення як безкоштовних так і платних. Наприклад, бібліотеки для промальовування різноманітних діаграм у своїх програмах і т.п.
ООП в java базується на ряді понять (або ж концепцій)Lesson: Object-Oriented Programming Concepts:
Клас - певна абстрактна сутність, наприклад, "Пес", "Кіт", "Автомобіль", "Ціна товару", що на програмному рівні представлена змінними (полями даних) та методами, що оперують над цими полями даних.
Об'єкт - конкретний екземпляр класу. Наприклад, зелена "Тойота" вашого сусіда є екземпляром класу "Автомобіль". По суті, це клас, поля якого ініціалізовані і він завантажений у пам'ять комп'ютера. На основі одного класу, можна створити безліч об'єктів.
Успадкування (або ж "спадкоємство") - утворення нових класів на основі інших.
Інтерфейс - посилальний тип даних. Інтерфейси схожі на класи, проте їхні поля даних є константами, а методи переважно нереалізовані (Починаючи з java 8 в інтерфейсах стало можливим реалізовувати методи). Об'єкти на основі інтерфейсів не створюються, проте класи можуть реалізовувати певний інтерфейс. І через об'єктну змінну інтерфейсного типу можна викликати реалізації даних методів.
Пакети - каталоги, у яких розміщуються класи. Таким чином ми можемо використовувати однойменні класи, оскільки їхнє розрізнення іде не тільки за іменами, але й за розміщенням їх у каталогах (пакетах).
Насправді доволі часто різні автори по різному виділяють головні концепції ООП. Причиною є те, що в ООП справді доволі багато понять. І з плином часу та розвитком програмування їх лише більшає. Різноманітні поняття доволі тісно взаємопов'язані між собою. В літературі часто виділяють наступні три концепції і навіть вказують, що вони основні для ООП ("три кити"):
інкапсуляція (incapsulation) - концепція побудови класів через закриття(капсулювання) їхньої реалізації. успадкування (inheritance) - створення одних класів на основі інших поліморфізм (polymorphism) - можливість використання батьківських класів замість класів нащадків. По суті є частиною реалізованої в мові концепції успадкування.
Деякі теоретики додають до цих трьох ще "абстрагування". Власне коли програміст створює клас, він створює певну абстракцію, модель чогось із реального світу. Ряд теоретичних книг побудовані на тому, як потрібно створювати класи, їхні ієрархії, зв'язки між ними. Проте переважно вони настільки теоретичні, що практичні програмісти часто питання абстрагування вирішують виходячи із конкретної задачі, яку потрібно вирішити. Щоправда є і винятки. В даний час виділяють так звані Патерни проектування, ряд шаблонів чи то зразків того, як найбільш ефективно вирішити деякі задачі в ООП. Проте для того, щоб їх можна було освоїти, необхідне ґрунтовне вивчення об'єктно-орієнтованого програмування і зокрема наведених вище понять. Поняття з обох вищенаведених списків є важливими для ООП і потрібно розуміти, що є що і як працює. Саме всім цим поняттям та їхній реалізації в мові програмування Java і присвячений даний розділ.
Об'єкти та об'єктні змінні Дані в об’єкті (тобто глобальні змінні даного об’єкту) називаються полями екземпляру класу. Процедури, які оперують даними називаються методами. Специфічний об’єкт, який є екземпляром певного класу матиме специфічні значення екземплярних полів. Сукупність цих значень називається станом об’єкта. Коли викликається певний метод стан об’єкту може змінюватися. Згідно принципу інкапсуляції намагаються, щоб доступ до полів екземпляру здійснювався лише за допомогою певних методів.
Об’єкт – це конкретна реалізація певного класу. На основі одного класу може бути створено безліч об’єктів. При цьому в об’єктах виділяють:
Поведінку об’єкту – що можна зробити з даним об’єктом, або які методи можна застосовувати до нього Стан об’єкту – те як об’єкт змінюється, коли Ви застосовуєте його методи Ідентичність об’єкту – відмінність об’єкту від інших об’єктів. Об’єкти можуть мати однаковий стан, проте все рівно вони ідентифікуються як різні об’єкти.
Розробці класів присвячена чимала кількість літератури. Переважно назва класу складається з іменника, оскільки вони представляють собою певну сутність, а методи класу дієсловами, оскільки вони визначають його поведінку. Коли система, яка розробляється доволі велика усі її компоненти уже важко утримувати розробнику в голові. Тому в таких випадках часто використовують UML діаграми, на яких можуть вказувати як взаємозалежності класів у вигляді різноманітних стрілок так і стан та поведінку класів. Ви можете звернутися до відповідної літератури, якщо вас зацікавила дана тема.
Щоб створити об’єкт певного класу програміст викликає один з конструкторів даного класу. Спеціальні методи, які покликані задати об’єкту початковий стан і носять його ім’я. Наприклад стандартна бібліотека джави містить клас Date, який описує момент часу. Як то “December 31, 1999, 23:59:59 GMT” new Date(); // створюємо об’єкт, який містить поточний час
Ми можемо зразу ж вивести поточний час системи на екран:
System.out.println(new Date());
Проте такий підхід застосовується якщо об’єкт потрібен нам в програмі лише раз. Якщо ж його потрібно буде використати повторно, то для цього використовуються об’єктні змінні. Змінні, які посилаються на певний об’єкт.
Так для нашого випадку, наступний рядок створить об’єктну змінну типу Date, яка посилатиметься на створюваний нами об'єкт. Date curDate = new Date(); Значення об’єктної змінної може бути змінене, так що буде посилатися на інший об’єкт, або ж взагалі встановлене в null, тобто не вказувати на жодний об'єкт. Через об'єктні змінні можна здійснювати доступ до полів об'єкта та його методів.
Приклади створення і роботи з класами були наведені у: "Освоюємо Java/Вступ в класи та методи"
Пакети Джава дозволяє групувати класи в своєрідні колекції, які називаються пакетами. Це дозволяє, зокрема розмежувати класи з одним і тим же ім’ям. Так якщо ви розробили клас Car, то цілком логічно, що такий клас вже не раз розробляли.
Стандартна бібліотека Java поширюється з набором пакетів. Наприклад, java.lang, java.util, java.net і т.п. Все що необхідно для створення пакету, це створити звичайну папку і в ній розмістити ваші класи. Якщо папка вкладена в іншу утворюється ієрархія класів. Так всі стандартні класи Джава розміщені в каталогах java та javax.
Розробники Джава рекомендують розміщувати пакети по принципу доменних імен, лише в зворотньому порядку, наприклад: com.horstmann.corejava. Якщо ви або ваша фірма має доменне ім’я – це доволі зручний спосіб розміщення, оскільки забезпечує унікальність найменування пакету.
Імпортування пакетів Ваш клас може використовувати класи з власного пакету або всі відкриті класи з іншого пакету. Проте, якщо класи знаходяться в іншому пакеті, їх потрібно імпортувати. Це можна зробити двома способами:
вказувати повну назву пакету перед використовуваним класом: java.util.Date today = new java.util.Date(); Такий спосіб доволі незручний. Другий спосіб – це використати інструкцію import, яка ставиться на початку сирцевого коду програми. import java.util.Date; // імпортуємо класс можна також імпортувати цілий пакет, таким чином не лише класс Date буде доступний, але й усі класи, які знаходять в одному каталозі з ним: import java.util.*; Таким чином в коді програми можна писати: Date today = new Date();
Щоб визначити, який пакет вам потрібно імпортувати можна скористатися документацією класів. Деякі середовища розробки дозволяють зробити це автоматизовано при натисненні певного пункту меню. В NetBeans наприклад можна клацнути правою кнопкою миші будь-де у вікні редагування коду і вибрати пункт “Fix Import”. Щоправда дана команда також підчищає рядки з імпортом і забирає імпорт тих пакетів, які не використовуються.
Інколи все ж коли ви імпортуєте пакет не вказуючи ім'я класу, то можуть виникати конфлікти імен. В таких випадках необхідно, або точно вказати, який клас ви імпортуєте, або якщо вам необхідно використовувати однойменні класи з двох різних пакетів, то прийдеться використовувати повне ім'я пакету при роботі з класом та його методами.
Імпорт статичних класів Починаючи з Java SE 5.0 можливості використання імпорту були розширені. Тепер можна імпортувати не тільки класи, але й поля і методи статичних класів.
Наприклад, можна зробити так: import static java.lang.System.*; Таким чином можна уже не писати назву класу System: out.println("Goodbye, World!"); // i.e., System.out exit(0); // i.e., System.exit Щоправда для класу System це є лишнім, оскільки код може стати менш читабельним. Проте використання такого імпорту для таких статичних класів як Math є цілком виправданим, оскільки замість: Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) Тепер можна писати: sqrt(pow(x, 2) + pow(y, 2))
Компілювання і запуск програми, змінна CLASSPATH Після створення класів в пакеті, їх можна відкомпілювати так, як це ви робили раніше. Проте, якщо спробуєте запустити, то Ви отримаєте помилку інтерпретатора Джави, що не може знайти ваш клас. Причина в тому, що тепер потрібно запускати створений клас знаходячись в вершині ієрархії пакету. Крім того тепер при запуску на виконання потрібно задавати повну назву пакету. Так, якщо ваш клас знаходиться у пакеті test під назвою PackTest. То Вам необхідно вийти з каталогу test і звідти скористатися командою: java test.PackTest Інший спосіб – це встановлення змінної середовища CLASSPATH. Так у віндовзі вона встановлюється схожим чином як змінна path, де необхідно вказати ваш робочий каталог в якому знаходяться пакети. Так якщо ви працюєте в каталозі c:\work. То встановлюємо в CLASSPATH наступне: .; C:\work Тепер команду java test.PackTest можна використовувати з будь-якого каталогу.
Можна також задавати змінну classpath при запуску компілятора та інтерпретатора: java -classpath c:\classdir;.;c:\archives\archive.jar MyProg.java
Саме так здійснюють виклики віртуальної машини інтегровані середовища розробки (IDE). Якщо ви використовуєте певне середовище розробки, то в ньому є внутрішні можливості прописування classpath і вносити зміни в змінні середовища системи немає потреби.
(В даному розділі бракує прикладів програм)
Керування доступом в пакеті Розглянемо як впливають модифікатори доступу на видимість елементів класів. Так при модифікаторі public усе може бути використано будь-яким класом. Приватні елементи (private) можуть бути використані тільки класами даного пакету. Якщо явно не вказаний модифікатор, то використовується модифікатор по замовчуванню, який надає ширші можливості доступу ніж private проте вужчі ніж public. Дивіться таблицю доступу до членів класу.