JavaRush /Java блог /Random UA /Розбір запитань та відповідей із співбесід на Java-розроб...
Константин
36 рівень

Розбір запитань та відповідей із співбесід на Java-розробника. Частина 4

Стаття з групи Random UA
Всім привіт, сьогодні я продовжую розбір 250+ питань із співбесід на Java-розробника. Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 4 - 1Попередні частини розбору: перша , друга , третя . Отже, продовжимо.

29. Чи можна у конструкторі використовувати return?

Можна, але без значення, що повертається праворуч від return . Тобто можна використовувати return; як допоміжну конструкцію при обчисленнях у конструкторі, щоб терміново закінчити (перервати) виконання подальшого коду та завершити ініціалізацію об'єкта. Наприклад, у нас є клас Cat , і якщо Cat бездомний - isHomeless = true , нам потрібно закінчити ініціалізацію і не заповнювати інші поля (адже вони нам невідомі, оскільки котик бездомний):
public Cat(int age, String name, boolean isHomeless) {
   if (isHomeless){
       this.isHomeless = isHomeless;
       return;
   }
   this.isHomeless = isHomeless;
   this.age = age;
   this.name = name;
}
Але якщо говорити про конкретні значення, конструктор не може використовувати return для повернення якогось значення, тому що:
  • при оголошенні конструктора у вас не буде нічого схожого на тип, що повертається;
  • як правило, конструктор неявно викликається під час створення екземпляра;
  • конструктор — це не метод: це окремий механізм, єдина мета якого — ініціалізувати змінні екземпляри, а саме створенням об'єкта займається оператором new .
Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 4 - 2

30. Чи можна з конструктора залишити виняток?

З винятками конструктори працюють так само, як і методи. І якщо методи дозволяють нам прокидати винятки, прописуючи в заголовку методу throws <ТипВиключення> , то і конструктор дозволяє нам це робити, і так само при наслідуванні та визначенні конструктора спадкоємця ми можемо розширювати тип виключення. Наприклад, IOException -> Exception (але не навпаки). Як приклад для прокидання конструктором виключення візьмемо клас Cat . Припустимо, при його створенні ми хочемо вводити ім'я та вік із консолі:
public Cat() throws IOException {
   BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
   this.name = reader.readLine();
   this.age = Integer.parseInt(reader.readLine());
}
Так як reader.readLine() кидає виняток IOException, в заголовку ми його прописуємо як можливий виняток, що викидається.

31. З яких елементів складається заголовок класу? Напишіть приклад

Говорячи про елементи, що становлять заголовок класу, розглянемо невелику схему:
  • обов'язкові складові будуть у дужках <>
  • необов'язкові - в {}
{модифікатор доступу класу} {статичність класу} {фінальність класу} {абстрактність класу} <ім'я класу>{спадкування від класу Батька} {реалізація інтерфейсів} Отже, що ми маємо: {модифікатор доступу класу} — для класу доступні лише модифікатори public та відсутній модифікатор доступу, тобто default . {Статичність класу} - static - модифікатор, який вказує, що даний клас статичний, застосовний тільки до внутрішніх класів (класів всередині інших класів). {Фінальність класу} - як ми пам'ятаємо, це модифікатор final , за наявності якого клас стає не успадкованим (приклад з коробки - String ). {абстрактність класу} – модифікатор – abstractщо вказує на те, що цей клас може мати нереалізовані методи. Цей модифікатор конфліктує з модифікатором final , тобто в заголовку класу може бути тільки один з них, оскільки модифікатор abstract передбачає, що цей клас буде успадкований і буде реалізовано його абстрактні частини. А final вказує на те, що це фінальна (остаточна) версія класу, і успадкований він не може бути. Власне, одночасне використання обох модифікаторів буде абсурдним і компілятор не дасть нам цього зробити. <class> - ключове обов'язкове слово, яке свідчить про оголошення класу. <ім'я класу>- Просте ім'я класу, яке є ідентифікатором конкретного класу Java. Повне ім'я класу складається з повного імені пакета + . + Просте ім'я класу. {успадкування від класу Батька} — вказівка ​​класу батька (якщо є) за допомогою ключового слова extends . Наприклад, .. extends ParentClass . {Реалізація інтерфейсів} - вказівка ​​інтерфейсів, які даний клас реалізує (якщо вони є) за допомогою ключового слова implements . Наприклад: … implements FirstInterface, SecondInterface … Ну і як приклад заголовка класу розглянемо заголовок класу Lion , який успадковується від Catі реалізує інтерфейс WildAnimal :
public final class Lion extends Cat implements WildAnimal
Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 4 – 3

32. З яких елементів складається заголовок методу? Напишіть приклад

Знову ж таки, при розгляді елементів, з яких складається заголовок методу, розглянемо невелику схему, в якій:
  • обов'язкові складові - у дужках <>
  • необов'язкові - в {}
{модифікатор доступу}{статичність класу}{абстрактність методу}{фінальність методу}{модифікатор синхронізації} {модифікатор native}<повертане значення><ім'я методу> <(> {аргументи методу} <}>{виключення, що кидаються} {модифікатор доступу } — для методу доступні всі модифікатори доступу — public , protected , default , private . { статичність класу}static — модифікатор, який вказує на те, що даний метод статичний, тобто прив'язаний не до об'єкта, а до класу. abstractщо вказує на те, що реалізація (тіло) методу відсутня. Для коректної роботи також потрібен модифікатор abstract класу, в якому наведено метод. Як і заголовку класу, даний модифікатор конфліктує з модифікатором final , але крім нього конфліктує і модифікатором static , т.к. абстрактний метод передбачає перевизначення методу спадкоємця, а статичні методи не перевизначаються. {Фінальність методу} - final - модифікатор, що вказує на те, що даний метод не можна перевизначити. {модифікатор синхронізації}synchronized— модифікатор, який означає, що цей метод захищений від одночасного доступу до нього із різних потоків. Якщо метод не статичний, він закривається на м'ютекc цього об'єкта. Якщо статичний метод, він закривається на м'ютекс поточного класу. {модифікатор native} - native - даний модифікатор вказує на те, що метод написаний іншою мовою програмування. <повертається> - тип значення, який повинен повернути метод. Якщо він не повинен нічого повертати - void . <ім'я методу> - ім'я методу, його ідентифікатор у системі. {Аргументи методу} - аргументи (параметри), які приймає метод: вони необхідні для реалізації його функціоналу. {виключення, що кидаються}throws ТипВинятки — перерахування винятків, що перевіряються, які може кидати даний метод. І як приклад заголовка методу наведу цей:
public static void main(String[] args) throws IOException

33. Створіть в об'єкті-спадкоємці конструктор за умовчанням, якщо у базовому він не визначений (але визначено іншого конструктора)

Я не до кінця розумію саме питання, але можливо мається на увазі, що, наприклад, у батька у нас є якийсь кастомний конструктор:
public Cat(int age, String name) {
   this.age = age;
   this.name = name;
}
Тому в класі предку нам обов'язково потрібно визначити конструктор, який заповнюватиме (викликатиме) батьківський конструктор:
public  class Lion extends Cat {

   public Lion(int age, String name) {
       super(age, name);
   }
}
Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 4 - 4

34. Коли використовується ключове слово this?

У Java цевикористовується в двох різних значеннях. 1. Як посилання на поточний об'єкт типу this.age = 9 . Тобто this посилається на об'єкт, в якому була викликана і до якого відноситься код, який використовує this . Головна функція – підвищити читабельність коду та уникнути неоднозначності. Наприклад, при однаковому імені внутрішнього поля класу та аргументу методу:
public void setName(String name) {
   this.name = name;
}
Тобто, this.name – поле об'єкта name – аргумент методу Посилання this не може використовуватись у статичних методах. 2. this можна застосовувати у конструкторі у вигляді виклику методу, типу this(value) . У такому разі це буде виклик іншого конструктора цього класу. Словом, можна викликати відразу два конструктори під час створення об'єкта:
public Cat(int age, String name) {
   this(name);
   this.age = age;
}

public Cat(String name) {
   this.name = name;
}
При створенні об'єкта Cat та викликі першого конструктора будуть викликані обидва поля об'єкта та успішно проініціалізовані. Є пара нюансів:
  1. this() працює лише у конструкторі.
  2. Посилання на інший конструктор має знаходитись у першому рядку блоку (тіла) конструктора. Тому в одному конструкторі більше одного (іншого) конструктора цього класу викликати не можна.
Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 4 – 5Більше прикладів – у цій статті .

35. Що таке ініціалізатор?

Наскільки я розумію, у цьому питанні йдеться про звичайні та статистичні блоки ініціалізації. Спочатку давайте згадаємо, що таке ініціалізація. Ініціалізація - це створення, активація, підготовка до роботи, визначення параметрів. Приведення програми або компонента до готовності до використання. Як ви пам'ятаєте, під час створення об'єкта змінну класу можна ініціалізувати безпосередньо при оголошенні:
class Cat {
   private int age = 9;
   private  String name = "Tom";
Або задавати ззовні через конструктор:
class Cat {
   private int age;
   private  String name;

   public Cat(int age, String name) {
       this.age = age;
       this.name = name;
   }
Але є ще один спосіб: задавати внутрішню змінну об'єкта через блок ініціалізації, який має вигляд фігурних дужок { } усередині класу, без імені (як у методу чи конструктора):
class Cat {
   private int age;
   private  String name;

   {
       age = 10;
       name = "Tom";
   }
Тобто блок ініціалізації – це частина коду, яка завантажується під час створення об'єкта. Як правило, такі блоки використовуються для виконання деяких складних обчислень, які необхідні при завантаженні класу. Результати цих обчислень можна задавати як значення змінних. Крім звичайних блоків ініціалізації існують статичні, які виглядають так само, але перед фігурною дужкою мають ключове слово static :
class Cat {
   private static int age;
   private static String name;

   static{
       age = 10;
       name = "Tom";
   }
Цей блок такий самий, як і попередній. Але якщо стандартний спрацьовує при ініціалізації кожного об'єкта, то статичний відпрацює лише одного разу, при завантаженні класу. У такому блоці, як правило, також роблять деякі складні обчислення для подальшої ініціалізації статичних змінних класу. Для статичного блоку діють самі обмеження, як і статичних методів: у ньому не можна використовувати не статичні дані, як і посилання поточний об'єкт — this . Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 4 – 6Далі ми з вами можемо побачити порядок ініціалізації класу (разом із його предком) для кращого розуміння моменту, коли спрацьовують блоки ініціалізації.

36. Для наслідування класу public class Child extends Parent напишіть порядок ініціалізації об'єкта

При завантаженні класу Child буде наступний порядок ініціалізації:
  1. Статичні поля класу Parent .
  2. Статичний блок ініціалізації класу Parent .
  3. Статичні поля класу Сhild .
  4. Статичний блок ініціалізації класу Child .
  5. Чи не статичні поля класу Parent .
  6. Чи не статичний блок ініціалізації класу Parent .
  7. Конструктор класу Parent .
  8. Чи не статичні поля класу Сhild .
  9. Чи не статичний блок ініціалізації класу Сhild .
  10. Конструктор класу Сhild .
Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 4 – 7Ось невелика стаття, яка практично пояснює порядок ініціалізації.

37. Які знаєте стосунки між класами (об'єктами)?

Між класами в Java є два види відносин:
  • відносини IS-A
Принцип IS-A в ООП заснований на спадкування класів або реалізації інтерфейсів. Наприклад, якщо клас Lion успадковує Cat , ми говоримо, що Lion є Cat :
Lion IS-A Cat
(Але не всякий Cat є Lion -ом) Точно така ж ситуація з інтерфейсами. Якщо клас Lion реалізує інтерфейс WildAnimal , то вони також стосуються:
Lion IS-A WildAnimal
  • відносини HAS-A
Цей тип відносин заснований на використанні класів іншими класами, ще званий "асоціація". Асоціація - це один клас посилається на інший клас (або навіть один на одного). Наприклад, клас Car може посилатися на клас Passenger , і це буде відношення:
Car HAS-A Passenger
І навпаки: якщо Passenger має посилання на Car , то це буде відношення:
Passenger HAS-A Car

38. Які асоціативні зв'язки між об'єктами ви знаєте?

Агрегація та композиція — не що інше, як окремі випадки асоціації. Агрегація - відношення, коли один об'єкт є частиною іншого. Наприклад, пасажир може перебувати у машині. Також пасажирів може бути кілька або не бути зовсім (якщо ми говоримо про теслу, то водій не обов'язковий). Наприклад:
public class Car {
   private List passengers = new ArrayList<>();

 void setPassenger(Passenger passenger) {
     passengers.add(passenger);
 }

   void move() {
       for (Passenger passenger : passengers) {
           System.out.println("Перевозка пассажира - " + passenger.toString());
       }
       passengers.clear();
   }
}
Тобто нам не важлива кількість пасажирів (і чи є вони взагалі): від цього функціонал класу Car не залежить. Також агрегація передбачає, що з використанні об'єкта іншим об'єктом перший можна використовувати ще інших об'єктах. Наприклад, один і той же студент може входити і в гурток в'язання, і в музичну групу рокерів, і при цьому ходити до групи англійських, що вивчають. Як ви зрозуміли, агрегація — це вільніші асоціативні відносини класів. Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 4 – 8Композиція — ще жорсткіше ставлення, коли об'єкт як є частиною іншого об'єкта, а й робота іншого об'єкта залежить від першого. Наприклад, двигун у машини. Хоч двигун і може бути без машини, але поза ним він некорисний. Та й машина не може працювати без двигуна:
public class Car {
   private Engine engine;

   public Car(Engine engine) {
       this.engine = engine;
   }

   void startMoving() {
       engine.start();
           ...
   }
Також композиція передбачає, що з використанні об'єкта іншим об'єктом перший неспроможна належати комусь іншому. Якщо повернутись до нашого прикладу, двигун може належати лише одній машині, але ніяк не двом або більше одночасно. На цьому сьогодні, мабуть, і зробимо зупинку.Розбір запитань та відповідей із співбесід на Java-розробника.  Частина 4 – 9
Інші матеріали серії:
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ