Вітання! Сьогодні ми поговоримо про класи Java. Класи - це, можна сказати, основа основ програмування Java. Коли ти станеш програмістом, твоїм основним завданням буде написання власних класів із різним функціоналом. Давай розберемося, що це за штука така і як вона працює :) Як ти вже знаєш, Java - це об'єктно-орієнтована мова програмування. Усі програми складаються з об'єктів, які зв'язуються між собою. Клас — це, насправді, шаблон для об'єкта. Він визначає, як об'єкт буде виглядати і які функції мати. Кожен об'єкт є об'єктом якогось класу . Розглянемо найпростіший приклад:
public class Cat {
String name;
int age;
}
Допустимо, ми пишемо програму, і в цій програмі нам для чогось потрібні кішки (наприклад, у нас ветеринарна клініка з можливістю онлайн-запису). Ми створабо клас Cat
і вказали для нього дві змінні — рядок name
і число age
. Такі змінні класів називаються полями . По суті це шаблон для всіх кішок, яких ми створимо в майбутньому. Кожна кішка (об'єкт класу Cat
) матиме дві змінні — ім'я та вік.
public class Cat {
String name;
int age;
public static void main(String[] args) {
Cat barsik = new Cat();
barsik.age = 3;
barsik.name = "Барсик";
System.out.println("Ми створабо кота на ім'я" + barsik.name + ", його вік -" + barsik.age);
}
}
Ось так це працює! Ми створабо кота, надали йому ім'я та вік і вивели все це в консоль. Нічого складного :) Класи найчастіше описують предмети та явища навколишнього світу. Кішка, стіл, людина, блискавка, сторінка книги, колесо — все це у твоїй програмі створюватиметься за допомогою окремих класів. Тепер звернемо увагу на змінні, які ми створабо в класі Cat
. Вони називаються полями, або змінними примірниками . У назві, власне, розкрито всю їх суть. Ці змінні будуть у кожного екземпляра (об'єкта) класу Cat
. У кожного кота, якого ми створимо, буде своя змінна name
та своя змінна age
. Логічно, загалом: зі справжніми котами все так і є :) Крім змінних екземплярів існують і іншізмінні класів , або статичні. Доповнимо наш приклад:
public class Cat {
String name;
int age;
static int count = 0;
public static void main(String[] args) {
Cat barsik = new Cat();
barsik.age = 3;
barsik.name = "Барсик";
count++;
Cat vasia = new Cat();
vasia.age = 5;
vasia.name = "Вася";
count++;
System.out.println("Ми створабо кота на ім'я" + barsik.name + ", його вік -" + barsik.age);
System.out.println("Ми створабо кота на ім'я" + vasia.name + ", його вік -" + vasia.age);
System.out.println("Загальна кількість котів = " + count);
}
}
Виведення в консоль:
Мы создали кота по имени Барсик, его возраст - 3
Мы создали кота по имени Вася, его возраст - 5
Общее количество котов = 2
Тепер у нас у класі з'явилася нова змінна – count
(кількість). Вона відповідає за підрахунок створених котів. Щоразу, як у методі main ми створюємо кота, ми збільшуємо цю змінну на 1. Ця змінна позначена ключовим словом static . Це означає, що вона належить класу , а чи не конкретному об'єкту класу. Що, звичайно, логічно: якщо ім'я кожного кота має бути своє, то лічильник котів нам потрібен один на всіх. Саме цього дозволяє домогтися слово static - count
одна змінна для всіх котів. Зверніть увагу: коли ми виводимо її в консоль, ми не пишемо barsik.count
або vasia.count
. Вона не належить ні Барсіку, ні Васі - вона належить всьому класу Cat
. Тому просто count
. Можна також написатиCat.count
- Це теж буде правильно. З виведенням у консоль змінної name
у нас би таке не пройшло:
public class Cat {
String name;
int age;
static int count = 0;
public static void main(String[] args) {
Cat barsik = new Cat();
barsik.age = 3;
barsik.name = "Барсик";
count++;
System.out.println("Ми створабо кота на ім'я" + name + ", його вік -" + barsik.age);
System.out.println("Загальна кількість котів = " + count);
}
}
Помилка! name
у кожного свого кота. У цьому місці компілятор збивається з пантелику. "Вивести в консоль ім'я? А чиє ім'я? :/"
Методи
Крім змінних, кожен клас має методи. Про них ми поговоримо в окремій лекції детальніше, але загальні моменти досить прості. Методи – це функціонал твого класу; те, що об'єкти цього класу вміють робити. З одним із методів ти вже знайомий – це методmain()
. Але метод main
, як ти пам'ятаєш, є статичним — тобто він належить усьому класу (логіка така сама, як із змінними). А звичайні, нестатичні методи можна викликати лише на конкретних об'єктах, які ми створабо. Наприклад, якщо ми хочемо написати клас для кішки, нам треба зрозуміти, які функції кішка повинна мати в нашій програмі. Виходячи з цього, напишемо для неї пару методів:
public class Cat {
String name;
int age;
public void sayMeow() {
System.out.println("Мяу!");
}
public void jump() {
System.out.println("Стриб скок!");
}
public static void main(String[] args) {
Cat barsik = new Cat();
barsik.age = 3;
barsik.name = "Барсик";
barsik.sayMeow();
barsik.jump();
}
}
Ну от тепер наш клас набагато більше схожий на опис справжньої кішки! У нас тепер не просто кіт Барсик з ім'ям та віком. Він ще вміє нявкати і стрибати! Який же кіт без такого "функціоналу" :) Беремо конкретний об'єкт - barsik
, і викликаємо у нього методи sayMeow()
і jump()
. Дивимося в консоль:
Мяу!
Прыг-скок!
Настійний кіт! :)
Створення своїх класів. Абстракція
У майбутньому тобі доведеться писати власні класи. На що потрібно звернути увагу під час їх написання? Якщо ми говоримо про змінні, тобі потрібно скористатися такою річчю як абстракція . Абстракція - один із чотирьох основних принципів об'єктно-орієнтованого програмування. Він має на увазі виділення основних, найбільш значущих показників предмета , і навпаки - відкидання другорядних, незначних. Наприклад, ми створюємо картотеку працівників компанії. Для створення об'єктів "працівник" ми написали класEmployee
. Які характеристики важливі для опису працівника у картотеці компанії? ПІБ, дата народження, номер соціального страхування, ІПН. Але навряд чи в картці працівника компанії нам потрібні його зростання, колір очей та волосся. Компанії ця інформація ні до чого. Тому для класу Employee
ми поставимо змінні String name
, int age
, int socialInsuranceNumber
і int taxNumber
, а від зайвої для нас інформації (типу кольору очей) відмовимося, абстрагуємося . А ось якщо ми створюємо картотеку фотомоделей для модельної агенції, ситуація різко змінюється. Для опису фотомоделі нам дуже важливі зріст, колір очей і колір волосся, а ось номер ІПН для неї нам абсолютно не важливий. Тому в класі Model
нам потрібно створити змінні int height
,, String hair
. String eyes
Отак і працює абстракція, все просто! :)
Конструктори
Повернімося до нашого прикладу з кішками.public class Cat {
String name;
int age;
public static void main(String[] args) {
Cat barsik = new Cat();
System.out.println("Тут у програмі протягом 2-х годин щось відбувається...");
barsik.age = 3;
barsik.name = "Барсик";
}
}
Подивися цей код і спробуй здогадатися, що з нашою програмою не так. Протягом двох годин у нашій програмі існував кіт без імені та віку! Звичайно, це докорінно неправильно. У базі даних ветеринарної клініки не повинно бути котів без інформації про них. Нині ми віддаємо це на відкуп програміста. Не забуде він вказати ім'я та вік – все буде ок. Забуде – у базі буде помилка, невідомі коти. Як нам вирішити цю проблему? Потрібно якимось чином заборонити створювати котів без імені та віку. Тут нам на допомогу приходять функції-конструктори . Наведемо приклад:
public class Cat {
String name;
int age;
//конструктор для класу Cat
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat barsik = new Cat("Barsik", 5);
}
}
Конструктор — це, насправді, шаблон для об'єктів класу. У даному випадку ми зазначимо, що для кожного об'єкта cat
мають бути вказані два аргументи — рядок та число. Якщо ми тепер спробуємо створити безіменного кота — це не вийде.
public class Cat {
String name;
int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat barsik = new Cat(); //помилка!
}
}
Тепер, коли у класі є конструктор, компілятор Java знає, як мають виглядати об'єкти, і дозволяє створювати об'єкти без зазначених у ньому аргументів. Тепер давай розберемося з ключовим словом this
, яке ти бачиш усередині конструктора. З ним також усе просто. "this" англійською - "цей, цього". Тобто це слово свідчить про конкретний предмет. Код у конструкторі
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
можна перекласти майже дослівно: " name при цьому кота (якого ми створюємо) = аргументу name , який вказано у конструкторі. age при цьому кота (якого ми створюємо) = аргументу age , який вказано у конструкторі." Після спрацювання конструктора можеш перевірити, що нашому коту привласнабо всі необхідні значення:
public class Cat {
String name;
int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat barsik = new Cat("Барсик", 5);
System.out.println(barsik.name);
System.out.println(barsik.age);
}
}
Виведення в консоль:
Барсик
5
Коли конструктор відпрацював:
Cat barsik = new Cat("Барсик", 5);
Усередині нього за фактом сталося таке:
this.name = "Барсик";
this.age = 5;
І об'єкту barsik
(він і є this
) присвоєно значення з аргументів конструктора. Насправді, якщо не вказати в класі конструктори у нього все одно спрацьовуватиме конструктор ! Але як це можливо? О_О Справа в тому, що в Java у всіх класів є так званий конструктор за замовчуванням . У нього немає жодних аргументів, але він спрацьовує щоразу під час створення будь-якого об'єкта будь-якого класу.
public class Cat {
public static void main(String[] args) {
Cat barsik = new Cat(); //Ось тут спрацював конструктор за замовчуванням
}
}
На перший погляд, це не помітно. Ну, створабо об'єкт і створабо, де тут робота конструктора? Щоб це побачити, давай прямо руками напишемо для класу Cat
порожній конструктор, а всередині нього виведемо якусь фразу в консоль. Якщо вона виведеться, то конструктор відпрацював.
public class Cat {
public Cat() {
System.out.println("Створабо кота!");
}
public static void main(String[] args) {
Cat barsik = new Cat(); //Ось тут спрацював конструктор за замовчуванням
}
}
Виведення в консоль:
Создали кота!
Ось і доказ. Конструктор за замовчуванням завжди незримо присутній у твоїх класах. Але тобі треба знати ще одну його особливість. Дефолтний конструктор зникає із класу, коли ти створюєш якийсь конструктор із аргументами. Доказ цього насправді ми вже бачабо вище. Ось у цьому коді:
public class Cat {
String name;
int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat barsik = new Cat(); //помилка!
}
}
Ми не змогли створити кота без імені та віку, тому що визначабо конструктор для Cat
: рядок + число. Дефолтний конструктор одразу після цього зник із класу. Тому обов'язково запам'ятай: якщо тобі у твоєму класі потрібно кілька конструкторів, включаючи порожній, його потрібно створити окремо . Наприклад, наша ветеринарна клініка хоче робити добрі справи та допомагати бездомним котикам, чиїх імен та віку ми не знаємо. Тоді наш код має виглядати так:
public class Cat {
String name;
int age;
//для домашніх котів
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
//для вуличних котів
public Cat() {
}
public static void main(String[] args) {
Cat barsik = new Cat("Barsik", 5);
Cat streetCat = new Cat();
}
}
Тепер, коли ми явно вказали конструктора за замовчуванням, ми можемо створювати котів обох типів. У конструкторі можна надавати значення і явно, а не лише брати їх із аргументів. Наприклад, ми можемо записувати всіх вуличних котів у базу даних під ім'ям "Вуличний кіт номер..." :
public class Cat {
String name;
int age;
static int count = 0;
public Cat() {
count++;
this.name = "Вуличний кіт номер" + count;
}
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat streetCat1 = new Cat();
Cat streetCat2 = new Cat();
System.out.println(streetCat1.name);
System.out.println(streetCat2.name);
}
}
У нас є змінна count
, яка є лічильником вуличних котів. Щоразу при виконанні конструктора за умовчанням ми збільшуємо її на 1 і надаємо цей номер як ім'я кота. Для конструктора дуже важливий порядок дотримання аргументів. Поміняємо у нашому конструкторі аргументи імені та віку місцями.
public class Cat {
String name;
int age;
public Cat(int age, String name) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat barsik = new Cat("Барсик", 10); //помилка!
}
}
Помилка! Конструктор чітко описує: при створенні об'єкта Cat
йому мають бути передані число та рядок, саме в такому порядку . Тож наш код не спрацьовує. Обов'язково запам'ятай це і зважай на створення своїх власних класів:
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public Cat(int age, String name) {
this.age = age;
this.name = name;
}
Це два абсолютно різні конструктори! Тепер виріши кілька завдань на закріплення матеріалу:)
- Музей старожитностей.
Artifact
. Артефакти, що зберігаються у музеї, бувають трьох видів. Перший - про які невідомо нічого, крім порядкового номера, присвоєного музеєм (наприклад: 212121). Другий – про які відомий порядковий номер та культура, якою він був створений (наприклад: 212121, "Ацтеки"). Третій вид - про які відомий порядковий номер, культура, якою він був створений, і точний вік його створення (наприклад: 212121, "Ацтек", 12). Створи клас Artifact
, що описує старовини, що зберігаються в музеї, і напиши необхідну кількість конструкторів для нього. У методі main()
створи за одним артефактом кожного виду.
public class Artifact {
public static void main(String[] args) {
}
}
- Сайт знайомств
User
, який матиме поля — ім'я ( String
) вік ( short
) і зростання ( int
). Створіть необхідну кількість конструкторів, щоб ім'я, вік і зростання можна було вказувати в будь-якому порядку.
public class User {
String name;
short age;
int height;
public static void main(String[] args) {
}
}
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ