Halo semuanya! Hari ini saya melanjutkan ulasan saya tentang pertanyaan wawancara pengembang Java. Menjelajahi pertanyaan dan jawaban dari wawancara kerja untuk posisi pengembang Java.  Bagian 4 - 1

29. Bisakah return digunakan dalam konstruktor?

Ya, tapi hanya tanpa nilai di sebelah kanan kata kunci return . Anda dapat menggunakan pengembalian; sebagai pernyataan pembantu dalam konstruktor untuk segera menghentikan (mengganggu) eksekusi kode selanjutnya dan menyelesaikan inisialisasi objek. Misalnya, kita memiliki kelas Cat , dan jika Cat adalah tunawisma ( isHomeless = true , maka kita ingin menghentikan inisialisasi dan tidak mengisi kolom lainnya (bagaimanapun juga, kolom tersebut tidak kita ketahui, karena kucing tersebut adalah tunawisma) :

public Cat(int age, String name, boolean isHomeless) {
   if (isHomeless){
       this.isHomeless = isHomeless;
       return;
   }
   this.isHomeless = isHomeless;
   this.age = age;
   this.name = name;
}
Namun jika kita berbicara tentang nilai konkrit, maka kata kunci return tidak dapat mengembalikan nilai tertentu karena:
  • ketika Anda mendeklarasikan konstruktor, Anda tidak akan memiliki tipe kembalian seperti itu;
  • sebagai aturan, konstruktor dipanggil secara implisit selama pembuatan instance;
  • konstruktor bukanlah sebuah metode: ia adalah mekanisme terpisah yang tujuan utamanya adalah untuk menginisialisasi variabel instan, yaitu, kita menggunakan operator baru untuk membuat sebuah objek.
Menjelajahi pertanyaan dan jawaban dari wawancara kerja untuk posisi pengembang Java.  Bagian 4 - 2

30. Bisakah pengecualian dilempar dari konstruktor?

Konstruktor bekerja dengan pengecualian dengan cara yang sama seperti metode. Metode memungkinkan kita untuk melemparkan pengecualian dengan menulis lemparan <ExceptionType> di header metode. Dan konstruktor mengizinkan kita melakukan hal yang sama. Saat kita mewarisi dan mendefinisikan konstruktor kelas anak, kita dapat memperluas jenis pengecualian — misalnya, IOException -> Exception (tetapi tidak sebaliknya). Mari kita gunakan konstruktor kelas Cat sebagai contoh konstruktor yang memberikan pengecualian. Katakanlah ketika kita membuat sebuah objek, kita ingin memasukkan nama dan umur dari konsol:

public Cat() throws IOException {
   BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
   this.name = reader.readLine();
   this.age = Integer.parseInt(reader.readLine());
}
Karena reader.readLine() memunculkan IOException, kami menuliskannya di header sebagai kemungkinan pengecualian yang diberikan.

31. Apa saja elemen header kelas? Tulis sebuah contoh

Untuk mengilustrasikan elemen-elemen yang membentuk header kelas, mari kita lihat skema kecil:
  • elemen wajib muncul dalam tanda kurung <>
  • elemen opsional ada di {}
{access modifier}{static}{final}{abstract<class name>{inheritance of Parent class}{implementation of interfaces} Jadi, yang kita punya: {access modifier} — hanya pengubah akses publik dan default yang tersedia untuk kelas. {static} — pengubah statis menunjukkan bahwa kelas ini statis; itu hanya berlaku untuk kelas dalam (kelas di dalam kelas lain). {final} — ini adalah pengubah terakhir , tentu saja, yang membuat kelas tidak dapat diwarisi (contoh langsungnya adalah String ). {abstract} — pengubah abstrak , yang menunjukkan bahwa kelas mungkin memiliki metode yang belum diterapkan. Pengubah ini bertentangan dengan pengubah akhir . Header kelas hanya dapat memiliki salah satunya karena pengubah abstrak berarti kelas tersebut akan diwarisi dan elemen abstraknya akan diimplementasikan. Namun final menunjukkan bahwa ini adalah versi final kelas tersebut, dan tidak dapat diwariskan. Sebenarnya, menggunakan kedua pengubah secara bersamaan akan menjadi tidak masuk akal. Kompiler tidak akan membiarkan kita melakukan hal ini. <class> adalah kata kunci wajib yang menunjukkan deklarasi kelas. <nama kelas> adalah nama kelas sederhana yang menjadi pengenal kelas Java tertentu. Nama kelas yang memenuhi syarat sepenuhnya terdiri dari nama paket yang memenuhi syarat ditambah '.' ditambah nama kelas yang sederhana. {inheritance of the Parent class} merupakan indikasi kelas induk (jika ada) dengan menggunakan kata kunci extends . Misalnya, ... memperluas ParentClass . {implementation of interfaces} — daftar antarmuka yang diimplementasikan oleh kelas ini (jika ada), menggunakan kata kunci implementasi . Misalnya: ... mengimplementasikan FirstInterface, SecondInterface ... Sebagai contoh, pertimbangkan judul kelas dari kelas Lion , yang mewarisi Cat dan mengimplementasikan antarmuka WildAnimal :

public final class Lion extends Cat implements WildAnimal
Menjelajahi pertanyaan dan jawaban dari wawancara kerja untuk posisi pengembang Java.  Bagian 4 - 3

32. Apa saja elemen dari header metode? Tulis sebuah contoh

Saat mempertimbangkan elemen yang membentuk header metode, mari kita pertimbangkan kembali skema kecil:
  • elemen wajib muncul dalam tanda kurung <>
  • elemen opsional ada di {}
{access modifier}{static}{abstract}{final}{synchronized} {native} <return value><nama metode> <(>{parameter metode}>{throw Exceptions} {access modifier} — semua pengubah akses adalah tersedia untuk metode — public , protected , default , private . {static} — pengubah statis , yang menunjukkan bahwa metode tersebut bersifat statis dan karena itu diasosiasikan dengan kelas, bukan objek. {abstract} — pengubah abstrak , yang menunjukkan bahwa metode tidak memiliki implementasi (tubuh). Agar berfungsi dengan benar, kelas yang mendeklarasikan metode juga harus memiliki pengubah abstrak . Seperti pada header kelas, pengubah ini bertentangan dengan pengubah akhir , dan juga bertentangan dengan pengubah statis , karena sebuah metode abstrak menyiratkan penggantian metode dalam turunan, dan metode statis tidak dapat diganti. {finale} — pengubah terakhir , yang menunjukkan bahwa metode ini tidak dapat diganti. {synchronized} — pengubah tersinkronisasi , yang berarti bahwa metode ini dilindungi dari akses simultan ke sana dari thread yang berbeda. Jika metode ini tidak statis, maka metode tersebut ditutup untuk mutex objek ini. Jika metodenya statis, maka metode tersebut ditutup untuk mutex kelas saat ini. {native} — pengubah asli menunjukkan bahwa metode tersebut ditulis dalam bahasa pemrograman lain. <return type> — tipe nilai yang harus dikembalikan oleh metode. Jika metode ini tidak mengembalikan apa pun, maka void . <nama metode> — nama dari nama metode, yaitu pengidentifikasinya dalam sistem. {metode parameter} — parameter yang diterima metode: parameter tersebut diperlukan untuk mengimplementasikan fungsinya. {thrown Exceptions}menampilkan <ExceptionType> — daftar pengecualian yang dicentang yang dapat dilempar oleh metode ini. Saya akan menawarkan yang berikut ini sebagai contoh header metode:

public static void main(String[] args) throws IOException

33. Buat konstruktor default di kelas anak jika konstruktor belum ditentukan di kelas dasar (tetapi konstruktor berbeda telah ditentukan)

Saya tidak yakin saya sepenuhnya memahami pertanyaannya, tapi mungkin itu berarti kita memiliki beberapa konstruktor seperti ini di kelas induk:

public Cat(int age, String name) {
   this.age = age;
   this.name = name;
}
Dalam hal ini, di kelas induk, kita pasti perlu mendefinisikan konstruktor yang akan menginisialisasi induknya (yaitu memanggil konstruktor induk):

public class Lion extends Cat {
 
   public Lion(int age, String name) {
       super(age, name);
   }
}
Menjelajahi pertanyaan dan jawaban dari wawancara kerja untuk posisi pengembang Java.  Bagian 4 - 4

34. Kapan kata kunci ini digunakan?

Di Jawa, ini memiliki dua arti berbeda. 1. Ini adalah referensi ke objek saat ini, misalnya this.age = 9 . Artinya, this mengacu pada objek yang digunakan dan yang dirujuk oleh kode ini . Tujuan utamanya adalah untuk meningkatkan keterbacaan kode dan menghindari ambiguitas. Misalnya, jika kolom instance dan argumen metode memiliki nama yang sama:

public void setName(String name) {
   this.name = name;
}
Artinya, this.name adalah bidang objek, sedangkan name adalah parameter metode. Referensi this tidak dapat digunakan dalam metode statis. 2. Di konstruktor, ini bisa disebut seperti metode, misalnya this(value) . Dalam hal ini, ini akan menjadi panggilan ke konstruktor lain dari kelas yang sama. Pada dasarnya, Anda dapat memanggil dua konstruktor selama proses pembuatan objek:

public Cat(int age, String name) {
   this(name);
   this.age = age;
}
 
public Cat(String name) {
   this.name = name;
}
Saat memanggil konstruktor pertama untuk membuat objek Cat , kedua kolom instance akan berhasil diinisialisasi. Ada beberapa nuansa di sini:
  1. this() hanya berfungsi di konstruktor.
  2. Referensi ke konstruktor lain harus berada di baris pertama blok konstruktor (body). Artinya, sebuah konstruktor tidak dapat memanggil lebih dari satu konstruktor (lainnya) dari kelasnya.
Menjelajahi pertanyaan dan jawaban dari wawancara kerja untuk posisi pengembang Java.  Bagian 4 - 5

35. Apa yang dimaksud dengan penginisialisasi?

Sejauh yang saya mengerti, pertanyaan ini adalah tentang blok inisialisasi biasa dan statis. Mari kita ingat dulu apa itu inisialisasi. Inisialisasi adalah pembuatan, aktivasi, persiapan, dan definisi bidang. Mempersiapkan suatu program atau komponen agar siap digunakan. Anda akan ingat bahwa ketika Anda membuat sebuah objek, variabel kelas dapat diinisialisasi segera ketika dideklarasikan:

class Cat {
   private int age = 9;
   private String name = "Tom";
Atau atur setelah fakta melalui konstruktor:

class Cat {
   private int age;
   private String name;
 
   public Cat(int age, String name) {
       this.age = age;
       this.name = name;
   }
Namun ada cara lain: Anda bisa menyetel variabel instance menggunakan blok inisialisasi, yang berbentuk kurung kurawal {} di dalam kelas, tanpa nama (seperti metode atau konstruktor tanpa nama):

class Cat {
   private int age;
   private String name;
 
   {
       age = 10;
       name = "Tom";
   }
Blok inisialisasi adalah sepotong kode yang dimuat ketika suatu objek dibuat. Blok seperti itu biasanya digunakan untuk melakukan perhitungan kompleks tertentu yang diperlukan saat suatu kelas dimuat. Hasil perhitungan tersebut dapat ditetapkan sebagai nilai variabel. Selain blok inisialisasi biasa, ada blok statis. Mereka terlihat sama tetapi memiliki kata kunci static di depan kurung kurawal pembuka:

class Cat {
   private static int age;
   private static String name;
 
   static{
       age = 10;
       name = "Tom";
   }
Blok ini sama dengan blok sebelumnya. Tetapi jika yang biasa dieksekusi ketika setiap objek diinisialisasi, maka yang statis hanya dieksekusi satu kali, ketika kelas dimuat. Sebagai aturan, perhitungan kompleks tertentu dilakukan dalam blok statis, yang digunakan untuk menginisialisasi variabel kelas statis. Pembatasan yang sama berlaku untuk blok statis yang berlaku untuk metode statis: Anda tidak dapat menggunakan data non-statis, seperti referensi ke objek saat ini ( this ) di blok statis. Menjelajahi pertanyaan dan jawaban dari wawancara kerja untuk posisi pengembang Java.  Bagian 4 - 6Sekarang kita dapat melihat urutan inisialisasi kelas (bersama dengan kelas induknya) untuk lebih memahami kapan tepatnya blok inisialisasi dipanggil.

36. Diberikan kelas Anak publik yang merupakan perluasan Induk, tuliskan urutan inisialisasi objek

Saat memuat kelas Anak , urutan inisialisasinya adalah sebagai berikut:
  1. Bidang kelas statis dari kelas Induk .
  2. Blok inisialisasi statis dari kelas Induk .
  3. Bidang statis kelas Anak .
  4. Blok inisialisasi statis kelas Anak .
  5. Bidang non-statis dari kelas Induk .
  6. Blok inisialisasi non-statis dari kelas Induk .
  7. Konstruktor kelas induk .
  8. Bidang non-statis dari kelas Anak .
  9. Blok inisialisasi non-statis dari kelas Anak .
  10. Konstruktor kelas Anak .
Menjelajahi pertanyaan dan jawaban dari wawancara kerja untuk posisi pengembang Java.  Bagian 4 - 7

37. Hubungan antar kelas (objek) seperti apa yang Anda ketahui?

Ada dua jenis variabel di Java: tipe primitif dan referensi ke objek lengkap.
  • hubungan IS-A
Prinsip IS-A OOP didasarkan pada pewarisan kelas atau implementasi antarmuka. Misalnya, jika kelas Lion mewarisi Cat , maka kita katakan bahwa Lion adalah Cat :

Lion IS-A Cat
(tetapi tidak semua Kucing adalah Singa ) Situasi yang sama juga terjadi pada antarmuka. Jika kelas Lion mengimplementasikan antarmuka WildAnimal , maka mereka juga ada dalam hubungan tersebut:

Lion IS-A WildAnimal
  • Hubungan HAS-A
Jenis hubungan ini adalah dimana satu kelas menggunakan kelas lain, disebut juga “asosiasi”. Asosiasi adalah satu kelas yang merujuk ke kelas lain (atau saling merujuk satu sama lain). Misalnya, kelas Mobil dapat mereferensikan kelas Penumpang , yang akan membentuk hubungan berikut:

Car HAS-A Passenger
Dan sebaliknya: jika Passenger mempunyai referensi ke Car , maka hubungannya akan menjadi seperti ini:

Passenger HAS-A Car

38. Hubungan objek asosiatif apa yang Anda ketahui?

Agregasi dan komposisi tidak lebih dari kasus asosiasi khusus. Agregasi adalah hubungan di mana satu objek menjadi bagian dari objek lainnya. Misalnya, seorang penumpang mungkin berada di dalam mobil. Terlebih lagi, mungkin ada banyak penumpang atau tidak sama sekali (dan jika kita berbicara tentang Tesla, mungkin tidak ada pengemudi). Misalnya:

public class Car {
   private List passengers = new ArrayList<>();
 
 void setPassenger(Passenger passenger) {
     passengers.add(passenger);
 }
 
   void move() {
       for (Passenger passenger : passengers) {
           System.out.println("Transporting passenger - " + passenger.toString());
       }
       passengers.clear();
   }
}
Dengan kata lain, jumlah penumpang (dalam jumlah berapa pun) tidak penting bagi kami: fungsionalitas kelas Mobil tidak bergantung pada hal ini. Agregasi juga menyiratkan bahwa ketika objek lain menggunakan satu objek, maka objek pertama dapat digunakan oleh objek lain. Misalnya, siswa yang sama mungkin tergabung dalam klub merajut dan band rock dan sekaligus menghadiri kelas bahasa Spanyol. Seperti yang dapat Anda bayangkan, agregasi adalah hubungan asosiatif yang lebih longgar antar kelas. Komposisi merupakan hubungan yang lebih erat lagi dimana suatu benda tidak hanya menjadi bagian dari benda yang lain saja, melainkan karya suatu benda sangat bergantung pada benda yang lain. Misalnya mobil mempunyai mesin. Sebuah mesin mungkin ada tanpa mobil, tapi tidak ada gunanya di luar mobil. Dan sebuah mobil tidak dapat bekerja tanpa mesin:

public class Car {
   private Engine engine;
 
   public Car(Engine engine) {
       this.engine = engine;
   }
 
   void startMoving() {
       engine.start();
           ...
   }
Komposisi juga menyiratkan bahwa ketika objek lain menggunakan suatu objek, objek pertama tidak dapat menjadi milik objek lain mana pun. Kembali ke contoh kita, sebuah mesin hanya dapat dimiliki oleh satu mobil, tidak dapat dimiliki oleh dua atau lebih mobil secara bersamaan. Saya rasa cukup untuk hari ini, jadi kita berhenti di sini.