Ở đây, tôi đang tạo cá thể của lớp tôi
Không, bạn không tạo ra thể hiện của lớp trừu tượng của bạn ở đây. Thay vào đó, bạn đang tạo một thể hiện của một lớp con ẩn danh của lớp trừu tượng của bạn. Và sau đó, bạn đang gọi phương thức trên tham chiếu lớp trừu tượng của bạn trỏ đến đối tượng lớp con .
Hành vi này được liệt kê rõ ràng trong JLS - Mục # 15.9.1 : -
Nếu biểu thức tạo cá thể lớp kết thúc trong một thân lớp, thì lớp được khởi tạo là một lớp ẩn danh. Sau đó:
- Nếu T biểu thị một lớp, thì một lớp con trực tiếp ẩn danh của lớp có tên T được khai báo. Đó là lỗi thời gian biên dịch nếu lớp được ký hiệu là T là lớp cuối cùng.
- Nếu T biểu thị một giao diện, thì một lớp con trực tiếp ẩn danh của Object thực hiện giao diện có tên T được khai báo.
- Trong cả hai trường hợp, phần thân của lớp con là ClassBody được đưa ra trong biểu thức tạo cá thể lớp.
- Lớp được khởi tạo là lớp con ẩn danh.
Nhấn mạnh mỏ.
Ngoài ra, trong JLS - Mục # 12.5 , bạn có thể đọc về Quá trình tạo đối tượng . Tôi sẽ trích dẫn một tuyên bố từ đây: -
Bất cứ khi nào một cá thể lớp mới được tạo, không gian bộ nhớ được phân bổ cho nó có chỗ cho tất cả các biến thể hiện được khai báo trong loại lớp và tất cả các biến thể hiện được khai báo trong mỗi siêu lớp của loại lớp, bao gồm tất cả các biến thể hiện có thể bị ẩn.
Ngay trước khi kết quả tham chiếu đến đối tượng vừa tạo được trả về, hàm tạo được chỉ định được xử lý để khởi tạo đối tượng mới bằng thủ tục sau:
Bạn có thể đọc về thủ tục đầy đủ trên liên kết tôi cung cấp.
Để thực tế thấy rằng lớp được khởi tạo là một lớp con ẩn danh , bạn chỉ cần biên dịch cả hai lớp của bạn. Giả sử bạn đặt các lớp đó vào hai tệp khác nhau:
My.java:
abstract class My {
public void myMethod() {
System.out.print("Abstract");
}
}
Poly.java:
class Poly extends My {
public static void main(String a[]) {
My m = new My() {};
m.myMethod();
}
}
Bây giờ, biên dịch cả hai tệp nguồn của bạn:
javac My.java Poly.java
Bây giờ trong thư mục nơi bạn biên dịch mã nguồn, bạn sẽ thấy các tệp lớp sau:
My.class
Poly$1.class // Class file corresponding to anonymous subclass
Poly.class
Xem lớp đó - Poly$1.class
. Đó là tệp lớp được tạo bởi trình biên dịch tương ứng với lớp con ẩn danh mà bạn đã khởi tạo bằng mã dưới đây:
new My() {};
Vì vậy, rõ ràng là có một lớp khác được khởi tạo. Chỉ có điều, lớp đó chỉ được đặt tên sau khi biên dịch bởi trình biên dịch.
Nói chung, tất cả các lớp con ẩn danh trong lớp của bạn sẽ được đặt tên theo kiểu này:
Poly$1.class, Poly$2.class, Poly$3.class, ... so on
Những con số đó biểu thị thứ tự mà các lớp ẩn danh đó xuất hiện trong lớp kèm theo.
B
từ một một trừu tượngA
, trong phần thi củaB
ví dụ, trong đó bao gồm chạyA
constructor 's, loại thời gian chạy của đối tượng thực sựA
. Chỉ tạm thời tuy nhiên.