2013-05-21 44 views

Trả lời

21

Java không ngăn chặn phân lớp phụ của lớp với các nhà xây dựng riêng tư.

public class Main { 
    static class A { 
     private A() { 
      System.out.println("Subclassed A in "+getClass().getName()); 
     } 
    } 

    static class B extends A { 
     public B() { 

     } 
    } 

    public static void main(String... ignored) { 
     new B(); 
    } 
} 

in

Subclassed A in Main$B 

gì nó ngăn cản là sub-lớp học mà không thể truy cập vào bất kỳ nhà xây dựng của lớp siêu của nó. Điều này có nghĩa là một hàm tạo riêng không thể được sử dụng trong một tệp lớp khác và một hàm tạo cục bộ gói không thể được sử dụng trong một gói khác.

Trong trường hợp này, tùy chọn duy nhất bạn có là ủy quyền. Bạn cần gọi phương thức factory để tạo một thể hiện của lớp "super" và bọc nó.

+0

điều gì đó không đúng? khởi tạo một lớp tĩnh lồng nhau? làm thế nào nó hoạt động? – Jaxox

+0

@jaxox với jvm, các lớp lồng nhau không có gì đặc biệt. Họ giống như bất kỳ lớp học nào khác với thông tin meta nhưng nhiều hơn. Vì vậy, bạn có thể tạo một lớp đã được định nghĩa một lồng nhau theo cùng một cách như bất kỳ khác. Các lớp ẩn danh Btw trong các phương thức tĩnh cũng là các lớp lồng nhau tĩnh. –

+0

@PeterLawrey Tôi nhận được những gì bạn đang nói, nhưng tôi vẫn còn hơi bối rối. Bạn đã không nói rằng Java không cho phép các lớp con không thể truy cập các nhà xây dựng siêu lớp tương ứng. Trong ví dụ của bạn, lớp B không có quyền truy cập vào hàm tạo của A. Vậy cái đó được cho phép như thế nào? – Grateful

18

Vì lớp học phải gọi hàm tạo siêu hạng của nó luôn là. Nếu không thể truy cập hàm tạo lớp siêu, thì lớp con không thể được khởi tạo. Thông tin

thêm: JLS 8.8.10. Preventing Instantiation of a Class


Về ý kiến ​​Brian Roach:

Cuộc gọi [để các nhà xây dựng tầng lớp phụ huynh] chỉ là tiềm ẩn nếu bạn không làm điều đó một cách rõ ràng và phụ huynh có một constructor no-arg công cộng hoặc được bảo vệ (hoặc không định nghĩa bất kỳ trường hợp nào trong đó có một mặc định no-arg). Nó được yêu cầu bởi vì ... đó là cách ngôn ngữ hoạt động. Trẻ em [các lớp] phải gọi hàm tạo của [cha mẹ].

Lưu ý rằng khi bạn nhanh chóng bất kỳ lớp trong Java, luôn có một cuộc gọi ngầm để Object constructor vì nó là lớp siêu của tất cả các lớp học. Nó sẽ thực hiện nó default constructor:

public Object() { 
} 

Lưu ý từ các liên kết JLS:

Đó là một lỗi thời gian biên dịch nếu một constructor mặc định được ngầm tuyên bố nhưng cha không có một constructor truy cập (§6.6) không có đối số và không có mệnh đề ném.

+0

Và tại sao đó là một điều kiện cần thiết ngay cả khi nó là tiềm ẩn? – CodeBlue

+1

Nếu lớp cha đã khai báo một hàm tạo riêng thì không có gì ngầm định về nó. Nó sẽ yêu cầu một cuộc gọi rõ ràng trong đứa trẻ, nhưng vì hàm tạo là riêng tư, bạn không thể. –

+0

Có một cuộc gọi ngầm định tới siêu() trong mọi hàm tạo trừ khi bạn chỉ định một chính mình. – cogsmos

1

Nếu hàm tạo của lớp là riêng tư thì lớp con không thể thực hiện cuộc gọi đến hàm tạo siêu. Do đó thừa kế sẽ thất bại.

0

Có thêm điều gì đó vào câu trả lời của Luiggi tính năng này của java được sử dụng khi tạo các lớp Singleton chỉ cho phép một cá thể của lớp đó được tạo ra.

+1

Không phải nếu bạn đang tạo một singleton một cách chính xác. –

+0

@Brian bạn có thể vui lòng cho tôi biết cách làm điều đó một cách chính xác mà không cần đặt hàm tạo riêng tư không? –

+2

Josh Bloch, 'Phiên bản Java thứ hai hiệu quả' - sử dụng 'enum'. Xem: http://stackoverflow.com/questions/5759596/the-best-singleton-pattern-since-java-5. Nếu bạn không có cuốn sách đó, hãy mua nó. Đó là một-phải đọc cho bất cứ ai nghiêm túc về java –

1

Nếu bạn có lớp con, bạn có 2 thuộc tính cho lớp con (lớp con) constructor: 1. Mặc định Constructor (Không có hàm tạo đối số): Trong trường hợp này hàm khởi tạo mặc định sẽ tự động gọi hàm khởi tạo lớp cha: không thành công vì hàm tạo lớp cha là riêng tư. 2.Parameterized Constructor: Khi bạn cố gắng tạo một đối tượng cho lớp con có hàm tạo tham số, bạn cần bắt buộc gọi hàm khởi tạo lớp cha từ hàm tạo lớp con bằng cách truyền tham số hoặc không truyền tham số: điều này cũng sẽ thất bại vì hàm tạo của hàm là riêng tư.

Vì lớp con sẽ có hàm khởi tạo mặc định hoặc hàm tạo tham số và không thể có một trong hai hàm, bạn không thể có lớp con cho lớp cha với hàm tạo riêng.

Các vấn đề liên quan