Автор: Ткаченко О.М.
1. Методи
Які маніпуляції можна робити з об’єктом типу Box? Нас може цікавити об’єм бруска, площа поверхні, сумарна довжина ребер та ін. Додамо у клас метод, який обчислює об’єм бруска:
class Box {
double w, h, d;
double getVolume() { return w*h*d; }
}
Метод – структурна частина опису класу, яка реалізує функціональність (поведінку) об'єктів даного класу.
Тіло методу - програмний код всередині опису.
Ознакою методу (на відміну від атрибутів) є наявність дужок після імені: з параметрами-змінними чи без. Зверніть увагу на обов’язковий оператор return в кінці тіла методу getVolume(). При виконанні цієї команди у точку виклику даного методу повертається значення виразу, який стоїть після return. Тип значення виразу повинен бути сумісним з типом, вказаним перед назвою методу (тут: double).
Очевидно, може виникнути потреба в ініціалізації атрибутів (довжини, ширини і висоти), як при створенні об’єкта, так і в процесі роботи програми, дізнатися значення кожного атрибуту в конкретний момент роботи програми тощо.
Наведемо приклад.
Лістинг
// опис класу Вох
class Box {
double w, h, d;
double getVolume() { return w*h*d; }
}
class pr3_2 {
public static void main(String [ ] args){
// створення двох об’єктів типу Вох
Box mybox1 = new Box();
Box mybox2 = new Box();
// ініціалізація атрибутів об’єкту mybox1
mybox1.w=5;
mybox1.h=4;
mybox1.d=1;
// ініціалізація атрибутів об’єкту mybox2
mybox2.w=4;
mybox2.h=3;
mybox2.d=2;
System.out.println("Об'єм першого бруска: "+mybox1.getVolume());
System.out.println("Об'єм другого бруска: "+mybox2.getVolume());
}
}
Результати роботи програми:
Об'єм першого бруска: 20.0
Об'єм другого бруска: 24.
Зверніть увагу на синтаксис виклику методу: ім’я_об’єкту. ім’я_методу();
Зауваження. Гарним стилем програмування вважається недопустимість доступу до атрибутів об’єкта безпосередньо з програми. Для цього створюють окремі методи, як для ініціалізації, так і для доступу (отримання значень). Іменування та використання таких методів є стандартизованим (негласно):
setАтрибут(...) (ініціалізувати), getАтрибут() (отримати значення).
Метод, який повертає значення деякого типу, називається типізованим. Метод, який не повертає значення, називається безтиповим, або нетипізовним.
У описі класу перед іменем типізованого методу завжди вказано тип значення, яке повертається, і в тілі методу має бути команда return. Перед іменем безтипового методу в описі класу вказується службове слово void.
Так, у наступному лістингу перші три методи в описі класі Box є безтиповими, наступні – типізовані.
class Box {
double w, h, d;
void setWidth(double x) { w=x; } // безтиповий
void setHeight(double x) { h=x; } // без типовий
void setDepth(double x) { d=x; } // безтиповий
double getWidth() { return w; } // типізований
double getHeight() { return h; } // типізований
double getDepth() { return d; } // типізований
double getVolume() { return w*h*d;} // типізований
}
class pr3_3 {
public static void main(String [ ] args){
Box mybox = new Box();
// ініціалізація
mybox.setWidth(5);
mybox.setHeight(4);
mybox.setDepth(1);
System.out.println("Ширина бруска: " + mybox.getHeight());
}
}
На перший погляд, така методика є досить громіздкою. Але при написанні досить об’ємних і складних програм, особливо при використанні коду іншими програмістами, такий підхід дозволяє уникнути плутанини. Дійсно, дотримуючись загальноприйнятої техніки програмування, ви можете бути автором своєї бібліотеки класів, якою зручно буде користуватися іншим, і навпаки: маючи опис доступних
методів класу, створених не вами, можете легко їх використати в інших блоках програми, навіть не маючи доступу до тіла методу.
Ще одним сильним мотивом стандартного специфікування класів користувача є необхідність убезпечити програмістів від несанкціонованого доступу безпосередньо до атрибутів об’єктів, дозволивши доступ лише через відкриті методи. Це дозволяє також зберегти авторське право на спосіб реалізації методів, оскільки тіло методів приховане від програмістів, які використовують готові бібліотеки (бінарні, уже відкомпільовані).
2. Конструктори
Конструктор - спеціальний метод, який ініціалізує об’єкт одразу після його створення (після виділення області в пам’яті).
Ім’я конструктора повинно співпадати з іменем класу.
Приклад для класу Вох:
class Box {
double w, h, d;
//конструктор
Box() { w=1; h=1; d=1; }
}
Для даного випадку команда
Box mybox = new Box();
створить об’єкт mybox, атрибути якого отримають значення 1. Виклик конструктора відбувається у момент створення об’єкта. Один і той самий клас може мати кілька конструкторів, кожен з яких дозволяє по-різному ініціалізувати об’єкт.
Лістинг
class Box {
double w;
double h;
double d;
// конструктори
Box() { w=0; h=0; d=0; }
Box (double x) { w=x; h=x; d=x; }
Box (double x, double y, double z) { w=x; h=y; d=z; }
}
class pr3_4 {
public static void main(String [ ] args){
// ініціалізується нулями – перший конструктор
Box mybox1 = new Box();
// атрибути отримують значення 3,2 – це другий конструктор
Box mybox2 = new Box(3.2);
// третій конструктор
Box mybox3 = new Box(3, 4, 5);
. . .
}
}
Для даного випадку створення об’єкта командою Box mybox = new Box (1, 2); недопустиме, оскільки конструктора з таким переліком параметрів немає в описі класу. Конструктор без параметрів в дужках ще називають конструктором за замовченням.
Повторне використання імені методу в межах класу є проявом поліморфізму – другого принципу об’єктно-орієнтованого програмування. Даний тип поліморфізму має термін "перевантаження" (overloading): ім’я методів одне і те ж, але сигнатура(список параметрів методу) – різна.
Поліморфізм може виявлятися не лише на конструкторах, а й на довільних методах класу.
На наступному уроці продовжимо вивчення ООП.