Використання готових класів
Об'єкти та об'єктні змінні
Для роботи з об'єктом необхідно:
- створити об'єкт (примірник класу);
- встановити вихідний стан об'єкта (ініціалізувати);
- Далі до об'єкта можна застосовувати методи.
Constructor- спеціальний метод, призначений для створення та ініціалізації об'єкта.
У стандартній бібліотеці Java є клас Date. За допомогою об'єкта цього класу можна описати поточний або інший момент часу, наприклад:
Ім'я конструктора завжди збігається з ім'ям класу. Тому конструктор класу Date називається Date. Для створення об'єкта конструктор об'єднується з оператором new:
Цей вираз створює новий об'єкт, який ініціалізується поточною датою та часом.
Об'єкт можна передати методом:
Клас Date містить метод toString(), що дозволяє подати дату у вигляді рядка:
Для багаторазового використання об'єкта його необхідно пов'язати зі змінною:
Між об'єктами та об'єктними змінними є суттєва різниця. Наприклад, наведене нижче вираз визначає об'єктну змінну deadline, яка може посилатися (але не посилається) на об'єкти типу Date:
На даному етапі змінна deadline об'єктом не є і навіть не посилається на жоден об'єкт. Тому методи класу Date за допомогою цієї змінної викликати поки не можна:
Спочатку змінну deadline потрібно ініціалізувати новоствореним об'єктом:
Крім того, можна скопіювати посилання на вже ініціалізований об'єкт:
Тепер змінні deadline і birthday посилаються на той самий об'єкт.
Об'єктна змінна немає ніякого об'єкта, вона лише посилається нею.
Оператор new також повертає лише посилання на створений об'єкт:
Об'єктноюзмінною можна присвоїти посилання null, щоб вказати, що воно не посилається на жодний об'єкт:
Виклик методу об'єкта через змінну, значення якої дорівнює null, призведе до помилки:
Локальні об'єктні змінні не ініціалізуються автоматично. Змінну необхідно ініціалізувати викликом оператора new або значенням null.
Чому для подання дати та часу застосовуються класи, а не вбудовані типи? Наприклад, Visual Basic дата задається так: #6/1/1995#. При такому підході можна використовувати вбудований тип, не переймаючись класами. Але в деяких країнах дати записуються у вигляді month/day/year, а в інших - year/month/day. Чи можуть розробники мови передбачити усі можливі варіанти? Навіть якщо це вдасться, ці кошти будуть занадто складні, а програмісти будуть змушені застосовувати їх. Класи дозволяють перекласти відповідальність за вирішення цих проблем із розробниками мови на творців бібліотек. Якщо системний клас поганий, завжди можна створити своє рішення.
Об'єктні змінні Java не еквівалентні змінним C++, типи яких задаються іменами класів. У C++ така змінна не може мати значення null, і їй нічого не можна присвоїти. Об'єктні змінні Java слід вважати аналогами покажчиків на об'єкти C++:
Зрозуміло, покажчик Date* не ініціалізується, доки не виконано оператора new:
Всі об'єкти Java розміщуються в динамічній пам'яті. Якщо об'єкт A містить об'єктну змінну B, то вона є вказівником на об'єкт B, розташований в динамічній пам'яті.
Покажчики C++ часто призводять до помилок: дуже легко створити невірний покажчик або втратити керування пам'яттю. У Java такої проблеми немає: система підтримки виконання коду виявляє неініціалізований покажчик,повідомляє про помилку та припиняє виконання програми. Програміст не думає про управління пам'яттю, оскільки механізм "складання сміття" робить це за нього автоматично.
Клас GregorianCalendar з бібліотеки Java
Клас Date є частиною стандартної бібліотеки Java. Примірник класу Date відбиває конкретний час.
У класі Date час представлений числом мілісекунд (+ або -), відрахованим відпочатку епохи:
UTC (Universal Coordinated Time) – науковий стандарт часу. UTC застосовується поряд з більш відомим GMT (Greenwich Mean Time).
Клас Date не дуже зручний для роботи з датами. Розробники бібліотеки Java вважали, що подання дати, наприклад "December 31, 2009, 23:59:59", є довільним і має залежати від календаря. Дане відображення підпорядковане григоріанським календарем, найпоширенішим календарем у світі. Але той самий момент часу зовсім інакше представляється в китайському або єврейському місячному календарі.
Вся історія розвитку людства супроводжувалася створенням календарів - систем найменування різних моментів часу. Як правило, основою для календарів був сонячний чи місячний цикл. У книзі Nachum Dershowitz і Edward M. Reingold "Calendrical Calculations" (Cambridge University Press, 2nd ed., 2001) є відомості про календар французької революції, календар Майя та ін екзотичних системах.
Розробники бібліотеки вирішили відокремити питання відстеження моментів часу від питань їх подання. Тому стандартна бібліотека Java містить два окремі класи:
- Date - момент часу, що представляє
- GregorianCalendar - розширює загальний клас Calendar, який описує властивості календаря в цілому
На основі класуCalendar можна створити практично будь-який календар. Але в стандартній бібліотеці, окрім григоріанського календаря, поки що немає жодної іншої реалізації.
Відділення виміру часу від календарів є гарним рішенням, цілком відповідним принципом ООП.
Клас Date містить методи before та after, що дозволяють порівнювати два моменти часу:
Клас GregorianCalendar містить набагато більше методів, ніж клас Date. Зокрема, у ньому є кілька корисних конструкторів:
Місяці лежать у діапазоні: 0 . 11. Для більшої ясності можна використовувати константу:
Конструктор GregorianCalendar дозволяє задати час:
У класі GregorianCalendar інкапсульовані поля екземпляра, у яких записана вказана дата. Не маючи доступу до вихідного тексту, неможливо визначити, яке подання дати та часу використовує цей клас. Але для програміста, який застосовує готовий клас, це зовсім неважливо. Важливим є лише те, які методи йому доступні.
Клас Date містить методиgetDay(),getMonth()таgetYear(), але використовувати їх без крайньої необхідності не рекомендується. Ці методи були частиною класу Date до того, як розробники бібліотеки зрозуміли, що класи, що реалізують різні календарі, розумніше відокремити один від одного. Зробивши це, вони помітили методи класу Date якdeprecated(не рекомендовані до застосування). Можна продовжувати використовувати їх, отримуючи попередження компілятора. Однак, краще відмовитись від використання цих методів, оскільки в майбутньому вони можуть бути видалені з бібліотеки.
Модифікуючі методи та методи доступу
Як отримати поточний день, місяць або рік на базі дати інкапсульованої в об'єкті класу GregorianCalendar? Як можна змінити цізначення?
Календар повинен обчислювати атрибути, що відповідають зазначеному моменту часу (дата, день тижня, місяць чи рік). Отримати одне з цих значень можна за допомогою методу get() класу GregorianCalendar. Бажаний атрибут передається у вигляді константи, визначеної у класі Calendar:
Стан об'єкта можна змінити за допомогою методу set():
Рік, місяць та день можна встановити в одному виклику:
До заданої дати можна додати певну кількість днів, тижнів, місяців тощо.
Зсув у зворотний бік виконується додаванням негативного числа.
Mutator- модифікуючий метод, здатний змінити поля об'єкта.
Accessor- метод доступу, може лише переглядати поля об'єкта.
У C++ на формування методу доступу використовується суфіксconst. Якщо метод не оголошено за допомогою const, він модифікує. У Java немає синтаксичних засобів, що дозволяють розрізняти модифікуючі методи та методи доступу.
У імені методу доступу прийнято використовувати префікс get(), а імені модифікуючого методу - префікс set(). Клас GregorianCalendar забезпечує отримання та встановлення моменту часу, представленого об'єктом, за допомогою методів getTime() та setTime():
Ці методи дуже корисні для перетворення об'єктів GregorianCalendar на об'єкти Date і навпаки. Наприклад, потрібно створити об'єкт Date, поля якого були б заповнені відомими значеннями року, місяця та дня:
Отримання параметрів дати з екземпляра класу Date:
Наступна програма ілюструє роботу класу GregorianCalendar:
Виведення на екран календаря поточного місяця, поточний день позначений зірочкою:
Клас GregorianCalendar дозволяє легко відстежувати дні тижня та враховувати тривалість місяців.Програміст не повинен знати про те, як саме клас GregorianCalendar обчислює місяці та дні. Потрібно просто використовуватиінтерфейскласу - методи get(), set() та add().