2009-04-11 9 views
6

tôi đã tự hỏi nếu có một tính năng ngôn ngữ trong Java, trong đó phương pháp của một lớp cha sẽ là vô hình cho các thành viên của một lớp con:Cấu trúc lớp được bảo vệ trong Java?

public class Subclass extends protected Superclass 

hoặc một cái gì đó. Tôi sẽ đưa ra một ví dụ.

Đây là lớp cha của bạn.

public class A{ 
    public String getA(){...} 
    public String getB(){...} 
    public String getC(){...} 
    public void setA(String a){...} 
    public void setB(String b){...} 
    public void setC(String c){...} 
} 

Nếu bạn muốn phân lớp Một khi bảo vệ một số phương thức của nó, và bạn không thể thay đổi modifyers truy cập trong phương pháp trừ khi bạn ghi đè lên chúng, bạn sẽ kết thúc với một cái gì đó giống như this-

public class B extends A{ 
    private String getA(){return super.getA();} 
    private String getB(){return super.getB();}//These four methods have 
    private void setA(String a){super.setA(a);}//to be redeclared. 
    private void setB(String b){super.setB(b);} 

    public String getC(){return super.getC();}//These two methods can be 
    public void setC(String c){super.setC(c);}//removed. 
    public String getD(){...} 
    public void setD(String d){...} 
} 

hoặc đó hoặc bạn có thể giữ một trường hợp riêng của A và có một cái gì đó như thế này:

public class B{ 

    private A obj; 

    private String getA(){return obj.getA();} 
    private String getB(){return obj.getB();}//These four methods can also 
    private void setA(String a){obj.setA(a);}//be removed. 
    private void setB(String b){obj.setB(b);} 

    public String getC(){return obj.getC();}//These two methods are 
    public void setC(String c){obj.setC(c);}//redeclared. 
    public String getD(){...} 
    public void setD(String d){...} 
} 

bạn có thể có cái gì đó mất cả trong một cách mà bạn không cần phải redeclare bất kỳ phương pháp?

Trả lời

10

Không có thừa kế "không công khai" trong Java, không giống như tình huống trong C++.

Thừa kế tạo mối quan hệ phụ. Bất kỳ cá thể nào của B cũng là một cá thể của A và phải trả lời cùng một thông điệp. Nếu các trường hợp B rõ ràng không trả lời tất cả các thông báo mà các cá thể của A phản hồi, thì thừa kế sẽ không phù hợp.

Giải pháp cuối cùng của bạn (B không kế thừa từ A) là giải pháp phù hợp: bạn không tạo mối quan hệ loại phụ, chỉ cần sử dụng một loại để (bí mật) triển khai thực hiện khác.

+0

+1 để so sánh với C++ (đã được bảo vệ và kế thừa riêng). –

+0

Khi tôi sử dụng để dạy nâng cao C++, tôi sử dụng để vẽ sơ đồ venn để hiển thị các mối quan hệ con, và hiển thị những gì được nhìn thấy bên trong và bên ngoài các lớp con, thấy nó rất hiệu quả để chứng minh khái niệm. Tuy nhiên, tôi cảm thấy rằng nó thường gặp nhiều rắc rối hơn nó đáng giá. – Uri

2

Khác với việc đặt trường/phương thức thành riêng tư trong lớp cha, tôi không nghĩ có cách nào xung quanh vấn đề này.

Tôi nghĩ tốt nhất của bạn tốt nhất là lựa chọn thứ hai của bạn, nơi lớp B giữ một tham chiếu tới lớp A.

3

Tôi không nghĩ rằng đó là hay nên có thể.

Nếu bạn sử dụng thừa kế để B mở rộng A, bạn sẽ có thể sử dụng đối tượng B làm đối tượng A. Ví dụ: điều này có thể:

A obj = new B(); 

Hiện tại, chương trình không có cách nào để biết rằng bạn không thể gọi một số phương thức công khai của A.

Và không thừa kế, việc xác định lại các hàm là không thể tránh khỏi.