1. Tất cả các lớp kế thừaObject
Tất cả các lớp trong Java đều ngầm kế thừa Object
lớp.
Chúng ta sẽ phân tích kế thừa là gì và nó hoạt động như thế nào trong Java trong nhiệm vụ Java Core. Bây giờ, chúng ta sẽ xem xét một thực tế đơn giản sau đây:
Một đối tượng của bất kỳ lớp nào có thể được gán cho một Object
biến. Ví dụ:
Mã số | Ghi chú |
---|---|
|
Biến o lưu trữ một tham chiếu đến một Scanner đối tượng |
|
Biến o lưu trữ một tham chiếu đến một String đối tượng |
|
Biến o lưu trữ một tham chiếu đến một Integer đối tượng |
|
Biến o lưu trữ một tham chiếu đến một String đối tượng |
Đây là nơi tin tốt kết thúc. Trình biên dịch không theo dõi loại đối tượng ban đầu được lưu trong một Object
biến, vì vậy bạn sẽ không thể gọi các phương thức trên đối tượng đã lưu ngoài các phương thức của Object
lớp.
Nếu bạn cần gọi các phương thức được liên kết với kiểu ban đầu của đối tượng, thì trước tiên bạn cần lưu một tham chiếu đến nó trong một biến có kiểu chính xác, sau đó gọi các phương thức trên biến đó:
Mã số | Ghi chú |
---|---|
|
Chương trình sẽ không biên dịch. Lớp Object không có nextInt() phương thức. |
|
Điều này sẽ làm việc. Ở đây chúng tôi lưu một tham chiếu đến một Scanner đối tượng trong một Scanner biến bằng cách sử dụng toán tử định kiểu . |
Bạn không thể chỉ đi và gán một Object
biến cho một biến Máy quét, ngay cả khi Object
biến đó lưu trữ một Scanner
đối tượng tham chiếu. Nhưng bạn có thể làm điều này nếu bạn sử dụng toán tử typecast mà bạn đã biết. Đây là diện mạo chung của nó:
Type name1 = (Type) name2;
Đâu name1
là tên của một Type
biến, và name2
là tên của một Object
biến lưu trữ một tham chiếu đến một Type
đối tượng.
đánh máy
Nếu kiểu của biến và kiểu của đối tượng không khớp, thì a ClassCastException
sẽ bị ném ra. Ví dụ:
Mã số | Ghi chú |
---|---|
|
Sẽ xảy ra lỗi khi chạy: a ClassCastException sẽ được ném vào đây |
Có một cách để tránh lỗi này trong Java: chúng tôi thực hiện việc này bằng cách kiểm tra loại đối tượng được lưu trữ trong một biến :
name instanceof Type
Toán instanceof
tử kiểm tra xem name
biến có phải là một Type
đối tượng hay không.
Ví dụ, hãy tìm một chuỗi trong một mảng các đối tượng khác nhau:
Mã số | Ghi chú |
---|---|
|
Autoboxing sẽ chuyển đổi các giá trị này thành Integer , String và Double , tương ứng. Lặp lại mảng các đối tượng Nếu đối tượng là một String Lưu nó vào một String biến Hiển thị biến trên màn hình. |
2. Tại sao thuốc generic xuất hiện — bộ sưu tập
Hãy trở lại bộ sưu tập.
Ngay khi các nhà phát triển Java tạo ra ArrayList
lớp này, họ muốn làm cho nó trở nên phổ biến, để nó có thể lưu trữ bất kỳ loại đối tượng nào. Vì vậy, họ đã sử dụng một mảng Object
s để lưu trữ các phần tử.
Điểm mạnh của phương pháp này là bạn có thể thêm một đối tượng thuộc bất kỳ loại nào vào bộ sưu tập.
Tất nhiên, có một số điểm yếu.
Nhược điểm 1.
Luôn cần phải viết một toán tử chuyển đổi kiểu khi truy xuất các phần tử từ một tập hợp:
Mã số | Ghi chú |
---|---|
|
Tạo một bộ sưu tập để lưu trữ các tham chiếu đến Object các đối tượng Điền vào bộ sưu tập các số 10 , 20 , ... 100 ; Tính tổng các phần tử của bộ sưu tập Việc đánh máy là cần thiết |
Nhược điểm 2.
Không có gì đảm bảo rằng một bộ sưu tập chứa một loại phần tử cụ thể
Mã số | Ghi chú |
---|---|
|
Tạo một bộ sưu tập để lưu trữ các tham chiếu đến Object các đối tượng Chúng tôi điền vào bộ sưu tập các số được biểu diễn dưới dạng Double các đối tượng: 0.0 , 2.5 , 5.0 , ... Tính tổng các phần tử của bộ sưu tập Sẽ xảy ra lỗi: a Double could be cast to anInteger |
Dữ liệu có thể được đưa vào bộ sưu tập ở bất cứ đâu:
- trong một phương pháp khác
- trong một chương trình khác
- từ một tập tin
- qua mạng
Nhược điểm 3.
Dữ liệu trong bộ sưu tập có thể bị thay đổi một cách tình cờ.
Bạn có thể chuyển một bộ sưu tập chứa đầy dữ liệu của mình tới một phương thức nào đó. Phương thức đó, được viết bởi một lập trình viên khác, sẽ thêm dữ liệu của nó vào bộ sưu tập của bạn.
Tên của bộ sưu tập không chỉ rõ loại dữ liệu nào có thể được lưu trữ trong đó. Và ngay cả khi bạn đặt cho biến của mình một cái tên rõ ràng, thì một tham chiếu đến nó có thể được chuyển đến hàng chục phương thức và những phương thức đó chắc chắn sẽ không biết gì về tên ban đầu của biến.
3. Thuốc gốc
Trong Java, tất cả những vấn đề này đều được loại bỏ bởi thứ hay ho này gọi là generics.
Trong Java, khái quát có nghĩa là khả năng thêm các tham số kiểu vào các kiểu. Kết quả là một loại hỗn hợp phức tạp. Quan điểm chung của một loại hỗn hợp như vậy là:
ClassName<TypeParameter>
Đây là một lớp chung. Và nó có thể được sử dụng ở bất cứ nơi nào bạn thường sử dụng các lớp học.
Mã số | Sự miêu tả |
---|---|
|
Tạo biến |
|
Tạo đối tượng |
|
Tạo mảng |
Chỉ Integer
các biến có thể được lưu trữ trong một bộ sưu tập như vậy:
Mã số | Sự miêu tả |
---|---|
|
ArrayList bộ sưu tập với Integer các yếu tố Điều này được cho phép Và điều này cũng sẽ hoạt động
hộp tự động
Nhưng điều này không được phép: lỗi biên dịch |
Bạn sẽ học cách tạo các lớp của riêng mình với các tham số kiểu trong nhiệm vụ Bộ sưu tập Java. Bây giờ, chúng ta sẽ xem xét cách sử dụng chúng và cách chúng hoạt động.
4. Thuốc generic hoạt động như thế nào
Trên thực tế, thuốc generic rất nguyên thủy.
Trình biên dịch chỉ cần thay thế các kiểu chung bằng các kiểu thông thường. Nhưng khi các phương thức của một kiểu chung được sử dụng, trình biên dịch sẽ thêm một toán tử typecast để truyền tham số cho các tham số kiểu:
Mã số | Trình biên dịch làm gì |
---|---|
|
|
|
|
|
|
|
|
Giả sử chúng ta có một phương thức tính tổng các số trong một tập hợp các số nguyên:
Mã số | Trình biên dịch làm gì |
---|---|
|
|
Nói cách khác, thuốc generic là một loại đường cú pháp, giống như autoboxing, nhưng nhiều hơn một chút. Với autoboxing, trình biên dịch thêm các phương thức để chuyển đổi an int
thành an Integer
và ngược lại, và đối với generic, nó thêm các toán tử định kiểu.
Sau khi trình biên dịch biên dịch các lớp chung của bạn với các tham số kiểu, chúng chỉ được chuyển đổi thành các lớp thông thường và các toán tử định kiểu. Thông tin về các đối số kiểu được truyền cho các biến kiểu chung sẽ bị mất. Hiệu ứng này còn được gọi là xóa kiểu .
Đôi khi các lập trình viên viết các lớp chung (các lớp có tham số kiểu) thực sự cần thông tin về các kiểu được truyền dưới dạng đối số. Trong nhiệm vụ Bộ sưu tập Java, bạn sẽ học cách giải quyết vấn đề này và những gì nó đòi hỏi.
5. Một số thông tin về thuốc generic
Dưới đây là một số sự thật thú vị hơn về thuốc generic.
Các lớp có thể có một số tham số kiểu. Nó trông giống như thế này:
ClassName<TypeParameter1, TypeParameter2, TypeParameter3>
Trên thực tế, điều này không thực sự đáng ngạc nhiên. Bất cứ nơi nào trình biên dịch có thể thêm một toán tử để truyền thành một loại, nó có thể thêm nhiều toán tử truyền kiểu.
Ví dụ:
Mã số | Ghi chú |
---|---|
|
Tham số đầu tiên của phương put thức là một Integer và tham số thứ hai là mộtString |
Các loại chung cũng có thể được sử dụng làm tham số . Nó trông giống như thế này:
ClassName<TypeParameter<TypeParameterParameter>>
Giả sử chúng ta muốn tạo một danh sách sẽ lưu trữ danh sách các chuỗi. Trong trường hợp này, chúng ta sẽ nhận được một cái gì đó như thế này:
// List of greetings
ArrayList<String> listHello = new ArrayList<String>();
listHello.add ("Hello");
listHello.add ("Hi");
// List of goodbyes
ArrayList<String> listBye = new ArrayList<String>();
listBye.add("Bye");
listBye.add ("Goodbye");
// List of lists
ArrayList<ArrayList<String>> lists = new ArrayList<ArrayList<String>>();
lists.add(listHello);
lists.add(listBye);
Các kiểu chung (kiểu có tham số kiểu) cũng có thể được sử dụng làm kiểu mảng. Nó trông giống như thế này:
ClassName<TypeParameter>[] array = new ClassName<TypeParameter>[size];
Không có gì kỳ diệu xảy ra ở đây: dấu ngoặc nhọn chỉ biểu thị tên loại:
Mã số | đối tác không chung chung |
---|---|
|
|
|
|
|
|
GO TO FULL VERSION