2012-10-23 21 views
8

Tôi gặp khó khăn khi hiểu cách thức hoạt động của kế thừa trong Java khi các lớp bên trong hiện diện. Tôi hiện đang làm việc trên một cái gì đó mà một lớp con cần phải thay đổi chút ít chức năng của lớp bên trong của cha mẹ của nó. Tôi đã đưa ra một ví dụ đơn giản hơn, mang tính hậu môn bên dưới.Làm thế nào để kế thừa Java hoạt động khi các lớp bên trong có liên quan

Tôi mong đợi mã này để in "Tôi là ChildClass.InnerClass" nhưng thay vào đó nó in "Tôi là ParentClass.InnerClass". Tại sao điều này? Ngoài ra, nếu tôi thay đổi đối tượng obj trong chính thành loại ChildClass thì đầu ra sẽ thay đổi thành "Tôi là ChildClass.InnerClass". Tại sao điều này?

Nói chung, cách được khuyến nghị thay đổi hành vi của đối tượng bên trong của lớp cha đối tượng là gì?

class InnerClassTest { 
    //----------------------------------------------------------------------- 
    // PARENT CLASS 
    class ParentClass { 
     public ParentClass() { 
     x = new InnerClass(); 
     } 

     InnerClass x; 

     class InnerClass { 
     public void speak() { 
      System.out.println("I am a ParentClass.InnerClass"); 
     } 
     } 
    } 

    //----------------------------------------------------------------------- 
    // CHILD CLASS 
    class ChildClass extends ParentClass { 
     public ChildClass() { 
     x = new InnerClass(); 
     } 

     InnerClass x; 

     class InnerClass extends ParentClass.InnerClass { 
     public void speak() { 
      System.out.println("I am a ChildClass.InnerClass"); 
     } 
     } 
    } 

    //----------------------------------------------------------------------- 
    // MAIN 
    public static void main(String[] args) { 
     ParentClass obj = (new InnerClassTest()).new ChildClass(); 
     obj.x.speak(); 
    } 
} 

Trả lời

6

Biến không được "ghi đè" làm phương pháp.

Trong cuộc gọi, bạn mong đợi x là số Child nhưng không phải vì x là một biến, không phải là phương thức.

Nhưng chú ý: loại tài liệu tham khảo của bạn là ParentClass nên obj.x điểm để InnerClass thuộc tính 's ParentClass mặc dù trường hợp thực sự đằng sau parentClass là một ChildClass!

Để hiển thị câu mong đợi của bạn, bạn phải thay đổi các tài liệu tham khảo loại để ChildClass:

public static void main(String[] args) { 
     ChildClass obj = (new InnerClassTest()).new ChildClass(); 
     obj.x.speak(); 
} 

Để hiểu rõ hơn về khái niệm, cố gắng xác định một phương pháp trong cả ParentClassChildClass lớp:

public InnerClass getInnerClass(){ 
    return x; 
} 

và đặt x riêng tư.

để "áp dụng khái niệm ghi đè".

cuộc gọi cuối cùng của bạn sẽ là trong trường hợp này:

ParentClass obj = (new InnerClassTest()).new ChildClass(); 
obj.getInnerClass().speak(); 

Để thay đổi hành vi của các lớp bên trong, suy nghĩ của Template phương pháp mẫu hoặc tốt hơn: Chiến lược mẫu (vì tôn trọng hơn DIP)

3

Tháo khai báo lại

InnerClass x; 

fr om lớp con. Vì vậy, bạn sẽ chỉ có một x và sẽ được chỉ định lại trong hàm tạo của lớp con. Có nghĩa là một x (đề cập đến đối tượng được tạo ra trong con ctor).

Ẩn mật khẩu trong lớp cha. Đó là lý do tại sao bạn kết thúc có hai trường, tham chiếu đến hai đối tượng khác nhau.Và do tĩnh (thời gian biên dịch hoặc đầu) ràng buộc trong trường hợp của các biến,

ParentClass obj; 
//obj.x means the x in parent 

ChildClass obj; 
//obj.x means the x in child 
+0

'ParentClass obj; //obj.x có nghĩa là x trong child' ?? bạn có nghĩa là ChildClass obj; – exexzian

+0

@sansix: Chính xác. Cảm ơn bạn đã chỉnh sửa. –

+0

+1 cho giải pháp – exexzian

1

Nói chung, cách đề nghị làm thay đổi hành vi của một đối tượng là những gì đối tượng bên trong của lớp cha?

Tôi khuyên bạn nên sử dụng thiết kế ít phức tạp hơn để bắt đầu. Một lớp con nên sửa đổi hành vi của cha mẹ bằng cách ghi đè các phương thức của nó, vì vậy tôi chỉ cần thêm một số phương thức factory newInnerClass() để ghi đè việc tạo phụ thuộc này và quản lý đối tượng này ở trên cùng của phân cấp lớp.

Điều này sẽ linh hoạt hơn những gì bạn đề xuất, bởi vì newInnerClass() có thể khởi tạo một lớp được xác định bất cứ nơi nào miễn là nó có giao diện phù hợp.

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