Xin chào tất cả mọi người! Hôm nay tôi sẽ tiếp tục xem xét các câu hỏi phỏng vấn nhà phát triển Java. Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 4 - 1

29. Có thể sử dụng return trong hàm tạo không?

Có, nhưng chỉ không có giá trị ở bên phải từ khóa trả về . Bạn có thể sử dụng return; như một câu lệnh trợ giúp trong hàm tạo để khẩn cấp chấm dứt (ngắt) việc thực thi mã tiếp theo và hoàn thành việc khởi tạo đối tượng. Ví dụ: giả sử chúng ta có một lớp Cat và nếu một con Cat là người vô gia cư ( isHomeless = true thì chúng ta muốn chấm dứt quá trình khởi tạo và không điền vào các trường khác (xét cho cùng, chúng ta không biết chúng vì con mèo là người vô gia cư) :
public Cat(int age, String name, boolean isHomeless) {
   if (isHomeless){
       this.isHomeless = isHomeless;
       return;
   }
   this.isHomeless = isHomeless;
   this.age = age;
   this.name = name;
}
Nhưng nếu chúng ta đang nói về các giá trị cụ thể thì từ khóa return không thể trả về một giá trị cụ thể vì:
  • khi bạn khai báo một hàm tạo, bạn sẽ không có bất kỳ thứ gì giống như kiểu trả về;
  • như một quy luật, hàm tạo được gọi ngầm trong quá trình khởi tạo;
  • hàm tạo không phải là một phương thức: nó là một cơ chế riêng biệt với mục đích duy nhất là khởi tạo các biến thể hiện, tức là chúng ta đang sử dụng toán tử mới để tạo một đối tượng.
Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 4 - 2

30. Có thể ném ngoại lệ từ một hàm tạo không?

Hàm tạo làm việc với các ngoại lệ giống như cách các phương thức thực hiện. Các phương thức cho phép chúng ta ném ra các ngoại lệ bằng cách viết Throws <ExceptionType> trong tiêu đề phương thức. Và các hàm tạo cho phép chúng ta làm điều tương tự. Khi kế thừa và định nghĩa hàm tạo của một lớp con, chúng ta có thể mở rộng loại ngoại lệ - ví dụ: IOException -> Exception (nhưng không phải ngược lại). Hãy sử dụng hàm tạo của lớp Cat làm ví dụ về hàm tạo đưa ra một ngoại lệ. Giả sử khi tạo một đối tượng, chúng ta muốn nhập tên và tuổi từ bảng điều khiển:
public Cat() throws IOException {
   BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
   this.name = reader.readLine();
   this.age = Integer.parseInt(reader.readLine());
}
reader.readLine() ném ra IOException nên chúng tôi ghi nó vào tiêu đề dưới dạng một ngoại lệ có thể được ném ra.

31. Các thành phần của tiêu đề lớp là gì? Viết một ví dụ

Để minh họa các phần tử tạo nên tiêu đề lớp, chúng ta hãy xem một lược đồ nhỏ:
  • phần tử bắt buộc xuất hiện trong ngoặc <>
  • các phần tử tùy chọn có trong {}
{access modifier}{static}{final}{abstract<class name>{inheritance of Parent class}{implementation of Interfaces} Vì vậy , những gì chúng tôi có: {access modifier} — chỉ có các công cụ sửa đổi truy cập mặc địnhcông khai mới khả dụng cho lớp học. {static} - công cụ sửa đổi tĩnh cho biết lớp này là tĩnh; nó chỉ áp dụng cho các lớp bên trong (các lớp bên trong các lớp khác). {final} — tất nhiên, đây là công cụ sửa đổi cuối cùng , làm cho lớp không thể kế thừa được (một ví dụ sẵn có là String ). {abstract} — công cụ sửa đổi trừu tượng , cho biết lớp có thể có các phương thức chưa được triển khai. Công cụ sửa đổi này xung đột với công cụ sửa đổi cuối cùng . Tiêu đề lớp chỉ có thể có một trong số chúng vì công cụ sửa đổi trừu tượng có nghĩa là lớp sẽ được kế thừa và các phần tử trừu tượng của nó sẽ được triển khai. Nhưng cuối cùng chỉ ra rằng đây là phiên bản cuối cùng của lớp và nó không thể được kế thừa. Trên thực tế, việc sử dụng đồng thời cả hai công cụ sửa đổi sẽ là điều vô lý. Trình biên dịch sẽ không cho phép chúng tôi làm điều này. <class> là từ khóa bắt buộc dùng để khai báo lớp. <tên lớp> là tên lớp đơn giản, trở thành mã định danh của một lớp Java cụ thể. Tên lớp đủ điều kiện bao gồm tên gói đủ điều kiện cộng với '.' cộng với tên lớp đơn giản. {inheritance of the Parent class} là dấu hiệu của lớp cha (nếu có) bằng từ khóa mở rộng . Ví dụ: ... mở rộng ParentClass . {thực hiện các giao diện} - danh sách các giao diện mà lớp này triển khai (nếu có), sử dụng từ khóa thực hiện . Ví dụ: ... triển khai FirstInterface, SecondInterface ... Ví dụ, hãy xem xét tiêu đề lớp của lớp Lion , kế thừa Cat và triển khai giao diện WildAnimal :
public final class Lion extends Cat implements WildAnimal
Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 4 - 3

32. Các thành phần của tiêu đề phương thức là gì? Viết một ví dụ

Khi xem xét các phần tử tạo nên tiêu đề phương thức, chúng ta hãy xem xét lại một lược đồ nhỏ:
  • phần tử bắt buộc xuất hiện trong ngoặc <>
  • các phần tử tùy chọn có trong {}
{công cụ sửa đổi truy cập}{static}{abstract}{final}{synchronized} {native} <return value><method name> <(>{method params><}>{throw ngoại lệ} {access modifier} — tất cả các công cụ sửa đổi truy cập đều là có sẵn cho phương thức này — public , protected , default , private . {static} — công cụ sửa đổi tĩnh , cho biết rằng phương thức này là tĩnh và do đó được liên kết với lớp chứ không phải một đối tượng . phương thức này không có phần triển khai (nội dung). Để hoạt động chính xác, lớp khai báo phương thức cũng phải có công cụ sửa đổi trừu tượng . Như trong tiêu đề lớp, công cụ sửa đổi này xung đột với công cụ sửa đổi cuối cùng và cũng xung đột với công cụ sửa đổi tĩnh , bởi vì một phương thức trừu tượng ngụ ý ghi đè phương thức này trong một phương thức con và các phương thức tĩnh không thể bị ghi đè . truy cập đồng thời vào nó từ các chủ đề khác nhau. Nếu phương thức không tĩnh thì phương thức này sẽ bị đóng đối với mutex này của đối tượng. Nếu phương thức này là tĩnh thì nó sẽ bị đóng đối với mutex của lớp hiện tại. {native} — công cụ sửa đổi gốc cho biết rằng phương thức này được viết bằng ngôn ngữ lập trình khác. <return type> — loại giá trị mà phương thức phải trả về. Nếu phương thức không trả về bất cứ thứ gì thì void . <tên phương thức> — tên của tên phương thức, tức là mã định danh của nó trong hệ thống. {tham số phương thức} — các tham số mà phương thức chấp nhận: chúng cần thiết để triển khai chức năng của phương thức. {các ngoại lệ được ném ra}ném ra <ExceptionType> — một danh sách các ngoại lệ được kiểm tra mà phương thức này có thể ném ra. Tôi sẽ đưa ra những điều sau đây làm ví dụ về tiêu đề phương thức:
public static void main(String[] args) throws IOException

33. Tạo một hàm tạo mặc định trong lớp con nếu một hàm tạo chưa được định nghĩa trong lớp cơ sở (nhưng một hàm tạo khác được xác định)

Tôi không chắc là mình hiểu hết câu hỏi, nhưng có lẽ điều đó có nghĩa là chúng ta có một số hàm tạo như thế này trong lớp cha:
public Cat(int age, String name) {
   this.age = age;
   this.name = name;
}
Trong trường hợp đó, trong lớp cha, chúng ta chắc chắn cần định nghĩa một hàm tạo sẽ khởi tạo lớp cha (tức là gọi hàm tạo cha):
public class Lion extends Cat {

   public Lion(int age, String name) {
       super(age, name);
   }
}
Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 4 - 4

34. Từ khóa this được sử dụng khi nào?

Trong Java, điều này có hai ý nghĩa khác nhau. 1. Nó là một tham chiếu đến đối tượng hiện tại, ví dụ this.age = 9 . Nghĩa là, this đề cập đến đối tượng mà nó được sử dụng và mã có nội dung this đề cập đến. Mục đích chính là cải thiện khả năng đọc mã và tránh sự mơ hồ. Ví dụ: nếu trường đối tượng và đối số phương thức có cùng tên:
public void setName(String name) {
   this.name = name;
}
Nghĩa là, this.name là trường của đối tượng, trong khi name là tham số phương thức. Tham chiếu this không thể được sử dụng trong các phương thức tĩnh. 2. Trong hàm tạo, this có thể được gọi giống như một phương thức, ví dụ: this(value) . Trong trường hợp này, nó sẽ là một cuộc gọi đến một hàm tạo khác của cùng một lớp. Về cơ bản, bạn có thể gọi hai hàm tạo trong quá trình tạo đối tượng:
public Cat(int age, String name) {
   this(name);
   this.age = age;
}

public Cat(String name) {
   this.name = name;
}
Khi gọi hàm tạo đầu tiên để tạo đối tượng Cat , cả hai trường phiên bản sẽ được khởi tạo thành công. Có một vài sắc thái ở đây:
  1. this() chỉ hoạt động trong hàm tạo.
  2. Tham chiếu đến hàm tạo khác phải nằm ở dòng đầu tiên của khối hàm tạo (nội dung). Điều này có nghĩa là một hàm tạo không thể gọi nhiều hơn một hàm tạo (khác) của lớp của nó.
Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 4 - 5

35. Công cụ khởi tạo là gì?

Theo tôi hiểu, câu hỏi này là về các khối khởi tạo thông thường và tĩnh. Đầu tiên chúng ta hãy nhớ khởi tạo là gì. Khởi tạo là việc tạo, kích hoạt, chuẩn bị và định nghĩa các trường. Chuẩn bị một chương trình hoặc thành phần để sẵn sàng sử dụng. Bạn sẽ nhớ lại rằng khi tạo một đối tượng, một biến lớp có thể được khởi tạo ngay khi nó được khai báo:
class Cat {
   private int age = 9;
   private String name = "Tom";
Hoặc đặt sau thực tế thông qua hàm tạo:
class Cat {
   private int age;
   private String name;

   public Cat(int age, String name) {
       this.age = age;
       this.name = name;
   }
Nhưng có một cách khác: bạn có thể đặt một biến thực thể bằng cách sử dụng khối khởi tạo, có dạng dấu ngoặc nhọn {} bên trong một lớp, không có tên (như phương thức hoặc hàm tạo không tên):
class Cat {
   private int age;
   private String name;

   {
       age = 10;
       name = "Tom";
   }
Khối khởi tạo là một đoạn mã được tải khi một đối tượng được tạo. Các khối như vậy thường được sử dụng để thực hiện các phép tính phức tạp nhất định cần thiết khi tải một lớp. Kết quả của những tính toán này có thể được đặt làm giá trị của các biến. Ngoài các khối khởi tạo thông thường, còn có các khối tĩnh. Chúng trông giống nhau nhưng có từ khóa tĩnh ở phía trước dấu ngoặc nhọn mở:
class Cat {
   private static int age;
   private static String name;

   static{
       age = 10;
       name = "Tom";
   }
Khối này giống khối trước. Nhưng nếu cái bình thường được thực thi khi mỗi đối tượng được khởi tạo, thì cái tĩnh chỉ được thực thi một lần, khi lớp được tải. Theo quy định, một số phép tính phức tạp nhất định được thực hiện trong một khối tĩnh, được sử dụng để khởi tạo các biến lớp tĩnh. Các hạn chế tương tự áp dụng cho khối tĩnh áp dụng cho các phương thức tĩnh: bạn không thể sử dụng dữ liệu không tĩnh, chẳng hạn như tham chiếu đến đối tượng hiện tại ( this ) trong khối tĩnh. Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 4 - 6Bây giờ chúng ta có thể xem thứ tự khởi tạo của lớp (cùng với lớp cha của nó) để hiểu rõ hơn khi nào chính xác các khối khởi tạo được gọi.

36. Cho một lớp Public Child kế thừa Parent, viết thứ tự khởi tạo của đối tượng

Khi nạp lớp Child , thứ tự khởi tạo sẽ như sau:
  1. Các trường lớp tĩnh của lớp Cha .
  2. Khối khởi tạo tĩnh của lớp Parent .
  3. Các trường tĩnh của lớp Сchild .
  4. Khối khởi tạo tĩnh của lớp Child .
  5. Các trường không tĩnh của lớp Parent .
  6. Khối khởi tạo không tĩnh của lớp Parent .
  7. Hàm tạo của lớp cha .
  8. Các trường không tĩnh của lớp Сchild .
  9. Khối khởi tạo không tĩnh của lớp Сchild .
  10. Hàm tạo của lớp Сchild .
Khám phá các câu hỏi và câu trả lời từ cuộc phỏng vấn xin việc cho vị trí nhà phát triển Java.  Phần 4 - 7

37. Bạn biết loại mối quan hệ nào giữa các lớp (đối tượng)?

Có hai loại biến trong Java: kiểu nguyên thủy và tham chiếu đến các đối tượng chính thức.
  • mối quan hệ IS-A
Nguyên tắc IS-A của OOP dựa trên sự kế thừa lớp hoặc triển khai các giao diện. Ví dụ: nếu lớp Lion kế thừa Cat thì chúng ta nói rằng LionCat :
Lion IS-A Cat
(nhưng không phải con mèo nào cũng là sư tử ) Tình trạng tương tự cũng tồn tại với các giao diện. Nếu lớp Lion triển khai giao diện WildAnimal thì chúng cũng tồn tại trong mối quan hệ:
Lion IS-A WildAnimal
  • Mối quan hệ CÓ-A
Kiểu quan hệ này là nơi một lớp sử dụng các lớp khác, còn được gọi là "liên kết". Một liên kết là một lớp tham chiếu đến một lớp khác (hoặc các tham chiếu lẫn nhau với nhau). Ví dụ: lớp Ô tô có thể tham chiếu lớp Hành khách , lớp này sẽ tạo thành mối quan hệ sau:
Car HAS-A Passenger
Và ngược lại: nếu Passenger có tham chiếu đến Car thì đây sẽ là mối quan hệ:
Passenger HAS-A Car

38. Bạn biết những mối quan hệ đối tượng liên kết nào?

Tập hợp và thành phần không gì khác hơn là những trường hợp đặc biệt của sự liên kết. Tập hợp là một mối quan hệ trong đó một đối tượng là một phần của đối tượng khác. Ví dụ: một hành khách có thể được định vị trong một chiếc ô tô. Hơn nữa, có thể có nhiều hành khách hoặc không có hành khách nào cả (và nếu chúng ta đang nói về Tesla, có thể không có tài xế). Ví dụ:
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();
   }
}
Nói cách khác, số lượng hành khách (bất kỳ) nào không quan trọng đối với chúng tôi: chức năng của hạng Ô tô không phụ thuộc vào điều này. Tập hợp cũng ngụ ý rằng khi một đối tượng khác sử dụng một đối tượng, đối tượng đầu tiên có thể được sử dụng bởi các đối tượng khác. Ví dụ, cùng một học sinh có thể tham gia cả câu lạc bộ đan len và ban nhạc rock, đồng thời tham gia một lớp học tiếng Tây Ban Nha. Như bạn có thể tưởng tượng, tập hợp là mối quan hệ liên kết lỏng lẻo hơn giữa các lớp. Thành phần là một mối quan hệ thậm chí còn chặt chẽ hơn trong đó một đối tượng không chỉ là một phần của đối tượng khác mà công việc của một đối tượng này phụ thuộc rất nhiều vào đối tượng khác. Ví dụ, một chiếc ô tô có động cơ. Một động cơ có thể tồn tại mà không cần ô tô, nhưng nó lại vô dụng khi ở bên ngoài ô tô. Và một chiếc ô tô không thể hoạt động nếu không có động cơ:
public class Car {
   private Engine engine;

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

   void startMoving() {
       engine.start();
           ...
   }
Thành phần cũng ngụ ý rằng khi một đối tượng khác sử dụng một đối tượng thì đối tượng đầu tiên không thể thuộc về bất kỳ đối tượng nào khác. Quay lại ví dụ của chúng ta, một động cơ chỉ có thể thuộc về một ô tô chứ không phải hai hoặc nhiều ô tô cùng một lúc. Tôi nghĩ hôm nay thế là đủ rồi nên chúng ta sẽ dừng ở đây.