Тема: поняття об'єкта у мові програмування, його властивостей і методів. Створення програми, її виконання та налагодження мовою Java.
Мета: сформувати визначення об'єкта у мові програмування, ознайомити учнів з його властивостями та методами, навчити створювати програми у cередовищі Java. По завершенню вивчення учень:
Обладнання: ПК із встановленим ОС і середовищем програмування мовою Java (NetBeans, Eclipse) чи стійким сполученням з Інтернетом, (дана) інструкція.
Структура уроку
Хід уроку
1. Організаційний момент
Вітання з класом. Перевірка присутності і готовності учнів до уроку. Перевірка виконання домашнього завдання.
Мотивація навчання: урок присвячено програмуванню логічної іграшки. Цей гральний автомат загадує число і кожну спробу відгадати або підтверджує правильність вибору, або повідомляє, що загадане число більше (менше) від запропонованої відповіді. Такий тренер навчає логічно мислити і використовувати алгоритм бінарного пошуку (поділом навпіл діапазону можливих величин) для ефективного розв'язання і навчальних, і практичних задач.
2. Актуалізація опорних знань
Дати означення понять щодо об'єктно-орієнтованого програмування, виділені жирним шрифтом у тексті, і порівняти з поданим описом.
3. Вивчення нового матеріалу
Мова програмування (англійською programming language) — це система позначень для опису алгоритмів та структур даних.
Java — це об'єктно-орієнтована мова програмування.
Об'єктно-орієнтована мова програмування описує сукупність об'єктів, що взаємодіють між собою. Об'єкт має властивості (змінні) та методи — дії, які об'єкт може виконувати. Кожний об’єкт є представником певного класу. Інакше кажучи, набір властивостей та поведінку (сукупність методів) об’єкта визначають в описі класу, на основі якого створено об’єкт.
Довільна програма мовою Java має містити принаймні один клас. Далі розглянемо приклад опису мовою Java класів — аналогів об'єктів з реального світу: класу Car (автомобіль) або Animal (тварина). Для класу Car природно задати такі властивості: двері, колеса, лобове скло тощо. На основі класу Car, можна створити нові класи (Легковики, Вантажівки, Автобуси), які матимуть усі властивості класу Car, а також свої власні властивості. У класі Animal можна задати властивості (Лапи, Хвіст), а потім створити клас Cat, у якого будуть додаткові властивості (Вуса). Інакше кажучи, клас А може успадковувати властивості іншого класу В, який називають (по відношенню до класу Ф) батьківським класом або суперкласом. Усередині класів можна оголосити поля (властивості, змінні) й методи.
Базовим елементом програмування у мові Java (і не лише ній) є клас. Зауважимо: класи Java не обов'язково містять метод main, що вказує інтерпретатору Java, звідки починати виконання програми. Для того, щоб створити клас, досить мати файл зі службовим словом class, а слідом за ним — допустимий ідентифікатор і пара фігурних дужок, що обмежують його тіло.
Назва файлу Java має повністю (тобто з урахуванням регістру) збігатися з назвою класу, описаного у цьому файлі, бо інакше буде помилка інтерпретації.
Клас — це шаблон для створення об'єкта. Клас визначає структуру об'єкта і його методи, що утворюють функціональний інтерфейс. У процесі виконання програми мовою Java система використовує визначення класів для створення представників класів. Терміни «представник», «екземпляр» і «об'єкт» — взаємозамінні.
Форма визначення класу:
class назва_класу extends назва_суперкласу {тіло класу};
Детальніше:
class назва_класу extends назва_суперкласу { тип_змінної назва_змінної1; тип_змінної назва_змінної2; … тип_результату_методу назва_методу1 (список_параметрів) {тіло методу;} тип_результату_методу назва_методу2 (список_параметрів) {тіло методу;} … }
Службове слово extends вказує на те, що «назва_класу» — це підклас «назва_суперкласу». У корені ієрархії класів Java — єдиний її вбудований клас Object. При створенні підкласу класу Object службове слово extends і наступну за ним назву суперкласу можна опустити.
Прості типи Java не є об'єктно-орієнтованими, вони аналогічні простим типам більшості традиційних мов програмування. Їх поділяють на 4 групи:
У Java, на відміну від деяких інших мов, відсутнє автоматичне зведення типів. Неузгодженість типів призводить не до попередження при трансляції, а до повідомлення про помилку. Для кожного типу строго визначено набори допустимих значень і дозволених операцій.
Інкапсуляція даних — приховування деталей інформації про роботу класів — виникає внаслідок оголошення змінних у тілі класу.
В якості типу зміннихможна використовувати і будь-який з простих типів, і класові типи.
Оператор new створює представника класу й повертає посилання на новостворений об'єкт (на місце початку його даних у пам'яті) таким чином:
назва_класу назва_змінної = new назва_класу()Оголошення методу здійснюють у тілі класу. При оголошенні методу задають тип результату і список параметрів. Загальна форма оголошення методу така:
тип_результату_методу назва_методу (список_параметрів) {тіло методу;}
Тип результату методу може бути будь-яким з допустимих, у тому числі й типом void у тому випадку, коли повертати результат не потрібно. Список параметрів (у круглих дужках) — послідовність пар тип-ідентифікатор, розділених комами, — може бути порожнім.
Розглянемо приклад методу init, у якому формальним параметрам дано назви х, у, а для доступу до однойменних змінних поточного об'єкта використано посилання this — див. приклад програми:
class Point { int x, y; void init(int x, int y) { this.x = x; this.y = y; } } class Rextester { public static void main(String args[]) { Point p1 = new Point(); Point p2 = new Point(); p1.init(10,20); p2.init(42,99); System.out.println("x = " + p1.x + " y = " + p1.y); System.out.println("x = " + p2.x + " y = " + p2.y); } }
Ця програма створює два різних об'єкти класу Point зі своїми значеннями властивостей і виводить ці значення:
x = 10 у = 20 x = 42 у = 99
Оператор . (крапка) використано для доступу до властивостей і методів об'єкта.
Примітка. У Java відсутня можливість передавання параметрів за посиланням на примітивний тип, а всі параметри примітивних типів передають за значенням. Інакше кажучи, метод не може змінити значення змінної, використаної в якості параметра.
У мові Java неможливо використати в одній або у вкладених областях видимості дві локальні змінні з однаковими назвами. Але не заборонено оголошувати формальні параметри методу з назвами, що збігаються з назвами змінних, значення яких передано у метод.
Ініціалізувати всі змінні класу щоразу, коли створюють новий представник — марудна справа навіть у тому випадку, коли у класі є функції, подібні методу init. Для цього в Java передбачені спеціальні методи — так звані конструкторами.
Конструктор — це метод класу, який ініціалізує новий об'єкт після його створення. Назва конструктора збігається з назвою класу, в якому він розташований.
У конструкторів немає типу повернення результату — ніякого, навіть void. Замінимо метод init з попереднього прикладу конструктором.
public class Point { int x, y; Point(int x, int y) { this.x = x; this.y = y; } } public class PointCreate { public static void main(String args[]) { Point p = new Point (10,20); System.out.println("x = " + p.x + " у = " + p.y); } }
Поєднання методів. Мова Java дозволяє створювати кілька методів з однаковими назвами, але з різними списками параметрів. Таку техніку називають поєднанням методів (method overloading). Як приклад див. інший опис класу Point, в якому поєднання методів використано для визначення альтернативного конструктора, який ініціалізує координати х та у значенням –1.
class Point { int x, y; Point(int x, int y) { this.x = x; this.y = y; } Point() { x = -1; y = -1; } } class Rextester { public static void main(String args[]) { Point p = new Point(); System.out.println("x = " + p.x + " у = " + p.y); } }
У цьому прикладі об'єкт класу Point створено за допомогою конструктора без параметрів. Ось результат роботи цієї програми:
x = -1 у = -1
Примітка. Те, який конструктор буде викликано, залежить від кількості і типів параметрів, зазначених у операторі new. Неприпустимо оголошувати у класі методи з однаковими назвами й сигнатурами. У сигнатурі методу не враховують назви формальних параметрів враховуються лише їх типи і кількість.
Ще один варіант опису класу Point показує, як, використовуючи this і поєднання методів, можна будувати одні конструктори на основі інших.
class Point { int x, y; Point(int x, int y) { this.x = x; this.y = y; } Point() { this(-1, -1); } }
Для перевірки коректності коду достатньо зробити відповідну заміну у поданому вище прикладі.
Методи, які використовують поєднання імен, не обов'язково повинні бути конструкторами. У наступному прикладі в клас Point додані два методу distance. Функція distance повертає відстань між двома точками. Одному з суміщених методів в якості параметрів передаються координати точки х і у, в іншому цю саму інформацію передано у вигляді параметра-об'єкта Point.
class Point { int x, y; Point(int x, int y) { this.x = x; this. y = y; } double distance(int x, int y) { int dx = this.x - x; int dy = this.y - y; return Math.sqrt(dx*dx + dy*dy); } double distance(Point p) { return distance(p.x, p.y); } } class Rextester { public static void main(String args[]) { Point p1 = new Point(0, 0); Point p2 = new Point(30, 40); System.out.println("p1 = " + p1.x + ", " + p1.y); System.out.println("p2 = " + p2.x + ", " + p2.y); System.out.println("p1.distance(p2) = " + p1.distance(p2)); System.out.println("p1.distance(60, 80) = " + p1.distance(60, 80)); } }
Зверніть увагу на те, як у другій формі методу distance для отримання результату викликано його перша форма. Нижче подано результат роботи цієї програми:
p1 = 0, 0 p2 = 30, 40 p1.distance(p2) = 50.0 p1.distance(60, 80) = 100.0
Іншою (крім інкапсуляції) фундаментальною властивістю об'єктно-орієнтованого підходу є наслідування. Класи-нащадки мають можливість не лише створювати свої власні змінні і методи, але і наслідувати змінні і методи класів-предків. Класи-нащадки прийнято називати підкласами. Безпосереднього предка даного класу називають його суперкласом.
У наступному прикладі показано можливості успадкування. У ньому розширено клас Box, доданням властивості weight (вага). Таким чином, новий клас матиме такі властивості: ширина, висота, глибина й вага паралелепіпеда — див. файли
Box,
BoxWeight,
Rextester.
Примітка. Файли цього й усіх наступних прикладів, вміст яких (файлів) не подано на даній html-сторінці, але є гіперпосилання на текстові файли з відповідними назвами, потрібно зберігати як окремі класи *.java одного пакунку (у цьому й у наступних прикладах названого у коді rextester).
У цьому прикладі ключове слово extends у коді BoxWeight використано для того, щоб повідомити про створення підкласу класу A. Результат роботи цієї програми такий:
Об'єм myboxl дорівнює 3000.0 вага myboxl дорівнює 34.3 Об'єм mybox2 дорівнює 24.0 вага mybox2 дорівнює 0.076
Клас BoxWeight успадковує всі характеристики класу Box і додає до них властивість weight. Класу BoxWeight не потрібно відтворювати всі характеристики класу Box. Він може просто розширювати клас Box у відповідності з конкретними цілями. Основна перевага успадкування полягає в тому, що як тільки суперклас, який визначає загальні атрибути набору об'єктів, створено, його можна використовувати для створення будь-якої кількості спеціалізованих класів. Кожен підклас може точно визначати свою власну класифікацію.
super — звернення до конструктора суперкласу. Застосування ключового слова super найбільш підходить в тих ситуаціях, коли імена членів підкласу приховують члени суперкласу з такими ж іменами. Розглянемо приклад простої ієрархії класів — див. файли
A,
B,
C, виконання яких дає такий результат:
i в суперкласі: 1 i в подкласі: 2
Заміщення методів розглянемо на прикладі класу Point3DDist і підкласу Point3D класу Point, що успадковує реалізацію методу distance свого суперкласу. У класі Point вже визначено методу distance, яка повертає відстань між точками на площині. Потрібно замістити (override) це визначення методу новим, придатним для випадку тривимірного простору. У прикладі проілюстровано і суміщення (overloading), і заміщення (overriding) методу distance. Результат роботи цієї програми такий:
p1 = 30, 40, 10 p2 = 0, 0, 0 p = 4, 6 p1.distance(p2) = 50.99019513592785 p1.distance(4, 6) = 2.23606797749979 p1.distance(p) = 2.23606797749979
Зверніть увагу: отримано очікувану відстань між тривимірними точками і між парою двовимірних точок. У прикладі використано механізм, який називають динамічним призначенням методів (dynamic method dispatch).
Динамічне призначення методів розглянемо на прикладі двох класів, у яких мають просту спорідненість підклас / суперклас, причому єдиний метод суперкласу заміщено у підкласі.
class A { void callme() { System.out.println("Inside A's callme method"); } } class B extends A { void callme() { System.out.println("Inside B's callme method"); } } class Rextester { public static void main(String args[]) { A a = new B(); a.callme(); } }
Всередині методу main оголошено змінну а класу А, яку проініціалізовано посиланням на об'єкт класу В. У наступному рядку викликано метод callme. При цьому транслятор перевіряє наявність методу callme у класі А. При виявленні того, що насправді у змінній збережено представник класу В, викликано не метод класу А, а метод callme класу В. Результат роботи цієї програми такий :
Inside B's callme method
static. Іноді потрібно створити метод, який можна було б використовувати поза контекстом будь-якого об'єкта його класу. Так само, як у випадку main, все, що потрібно для створення такого методу — вказати при його оголошенні модифікатор доступу static. Такі статичні методи можуть безпосередньо звертатися лише до інших статичних методів, в них не припустимо використання посилань this і super. Змінні також можуть мати модифікатор доступу static, вони подібні до глобальних змінних, тобто доступні з будь-якого місця коду. Усередині статичних методів неприпустимі посилання на змінні представників. Нижче наведено приклад класу, у якого є статичні змінні, статичний метод і статичний блок ініціалізації.
class Rextester { static int a = 3; static int b; static void method(int x) { System.out.println("x = " + x); System.out.println("a = " + a); System.out.println("b = " + b); } static { System.out.println("static block initialized"); b = a * 4; } public static void main(String args[]) { method(42); } }
Результат роботи цієї програми такий:
static block initialized x = 42 a = 3 b = 12
У наступному прикладі створено клас зі статичним методом і кількома статичними змінними. Другий клас може викликати статичний метод за назвою і посилатися на статичні змінні безпосередньо через назву класу.
class StaticClass { static int a = 42; static int b = 99; static void callme() { System.out.println("a = " + a); } } class Rextester { public static void main(String args[]) { StaticClass.callme(); System.out.println("b = " + StaticClass.b); } }
Результат роботи цієї програми такий:
a = 42 b = 99
Інколи потрібно визначити клас, в якому задано довільну структуру, але повна реалізація всіх методів відсутня. У таких випадках за допомогою модифікатора типу abstract оголошують, які з методів обов'язково потрібно замістити у підкласах. Будь-який клас, що містить методи abstract, потрібно оголосити як abstract. У таких класів відсутня повна реалізація, тому їхніх представників не можна створювати за допомогою оператора new. Крім того, не можна оголошувати абстрактними конструктори і статичні методи. Будь-який підклас абстрактного класу або зобов'язаний надати реалізацію всіх абстрактних методів свого суперкласу, або його потрібно оголосити абстрактним.
abstract class A { abstract void callme(); void metoo() { System.out.println("Inside A metoo method"); } } class B extends A { void callme() { System.out.println("Inside B callme method"); } } class Rextester { public static void main(String args[]) { A a = new B(); a.callme(); a.metoo(); } }
У поданому прикладі для виклику реалізованого у підкласі класу А методу callme і реалізованого в класі А методу metoo використано динамічне призначення методів. Результат роботи цієї програми такий:
Inside B callme method Inside A metoo method
4. Інструктаж з ТБ
5. Закріплення вивченого матеріалу
Завдання 1. Створити клас Circle — модель кола на координатній площині — з такими властивостями: координати центра і радіус. Наділити його такими методами:
Програму записати у файл (теку) з назвою Ваше_прізвище_латиницею_1 у вказану вчителем теку. Порівняти з демонстраційним розв'язанням:
Circle і Main.
Завдання 2. Створити клас Point2D — модель кола на координатній площині — з такими властивостями: абсциса й ордината. Наділити його такими методами:
Програму записати у файл (теку) з назвою Ваше_прізвище_латиницею_2 у вказану вчителем теку. Порівняти з демонстраційним розв'язанням:
Point2D і Dist2D.
6. Підбиття підсумків уроку
Виставлення оцінок.
7. Домашнє завдання
Вивчити матеріал уроку. У разі потреби доробити завдання, виконання яких розпочато у класі.
Текст упорядкувала Катерина Олександрівна Кухар, вчитель інформатики спеціалізованої школи І–ІІІ ступенів № 102 з поглибленим вивченням англійської мови Шевченківського району міста Києва, під час виконання випускної роботи на курсах підвищення кваліфікації з 17.10.2017 по 20.10.2017р.