2012-07-21 27 views
5

Giả sử, chúng tôi có một lớp trừu tượng A và chúng tôi muốn buộc tất cả các lớp con phải có một trường nhất định. Điều này là không thể trong Java, bởi vì chúng ta không thể định nghĩa các trường trừu tượng.Làm thế nào để có được xung quanh việc thiếu các lĩnh vực trừu tượng trong Java?

Cách giải quyết 1: Buộc các lớp con triển khai phương thức phân phối giá trị mong muốn.

abstract class A { 
    abstract int getA(); 
} 

Nhược điểm: Mỗi lớp con có để thực hiện một phương pháp cho từng lĩnh vực trừu tượng chúng ta muốn có. Điều này có thể dẫn đến nhiều triển khai phương pháp.

Advantage: Chúng tôi có thể sử dụng phương pháp getA trong lớp trừu tượng và triển khai phương pháp với nó trong A mà không thực hiện chúng trong mỗi phân lớp. Nhưng giá trị đằng sau phương thức này không thể được ghi đè bởi lớp trừu tượng.

Cách giải quyết 2: Mô phỏng trường trừu tượng bằng cách buộc lớp con cung cấp cho lớp trừu tượng một giá trị.

abstract class A { 
    int a; 

    public A(int a) { 
    this.a = a; 
    } 
} 

Nhược điểm: Khi chúng ta có nhiều lĩnh vực (> 10), cuộc gọi constructor siêu sẽ xem xét một chút xấu xí và khó hiểu.

Advantage: Chúng tôi có thể sử dụng trường a trong lớp trừu tượng và triển khai phương pháp với nó trong A mà không thực hiện chúng trong mỗi phân lớp. Ngoài ra, giá trị a có thể bị ghi đè bởi lớp trừu tượng.

Câu hỏi: Cách giải quyết nào là cách phổ biến để đạt được mục tiêu? Có lẽ có cái nào tốt hơn cái trên?

+2

Tôi có thiếu gì đó không? Tại sao không chỉ đơn giản là cung cấp cho lớp trừu tượng một trường * bê tông * được bảo vệ? Tại sao mong muốn cho một trường "* trừu tượng *"? Trường trừu tượng để bắt đầu là gì? Một lần nữa, những gì tôi đang thiếu hoặc không hiểu? Tôi có đơn giản hóa quá mức vấn đề của bạn không? Và những vấn đề hành vi (không phải vấn đề mã) là bạn đang cố gắng để giải quyết anyway? –

+1

Hoặc bạn có thể cung cấp cài đặt mặc định của 'getA()' và chỉ ghi đè lên nơi bạn muốn có giá trị khác. – Keppil

+0

_Tại sao bạn muốn buộc tất cả các lớp con có trường? Vấn đề thường được xây dựng tốt hơn trong việc buộc họ phải có một _behavior_ cụ thể, mà bạn chỉ làm với các đặc tả phương thức. –

Trả lời

0

Tôi nghĩ opt.1 là trình dọn dẹp cho đến nay. Một vài getters và setters không phải là một vấn đề lớn, và tôi nghi ngờ rằng nhiều trường hợp sử dụng sẽ có nhiều hơn chỉ là một vài "trường trừu tượng".

Về opt.2, bạn quên rằng các hàm tạo không được kế thừa, và do đó sẽ yêu cầu tất cả các hàm tạo lớp con phải được thực hiện theo cách mất a vào tài khoản.

1

Tôi thích cái đầu tiên. tôi không yêu cặp vợ chồng các lớp học trong tên nộp đơn, cách họ xử lý nhà nước và cách họ lưu nó. cái đầu tiên gần hơn là open/close principal

Tôi khuyên bạn nên tránh kế thừa. thừa kế là rất khó khăn và khó bảo trì. nhớ lời khuyên java hiệu quả - thích thành phần thừa kế khác

2

Phương pháp trừu tượng có lẽ là hướng đối tượng nhất.

Nếu bạn có quá nhiều trường, bạn có thể muốn nhóm lại các trường đó trong POJO (nếu một khái niệm mới phù hợp).

+1

tính năng đẹp là có thể thậm chí không tồn tại: int getA() {return 4;} nếu thuộc tính luôn là 4 cho lớp con hoặc getA() {return b + c;} nếu nó phụ thuộc vào các trường khác. – josefx

+0

Làm cho nó trở thành một phương pháp chung và không chỉ nó có thể không tồn tại, đó là loại có thể chưa tồn tại. –

0

Giải pháp 2 là rất phổ biến vì 2 ưu điểm:

1) một trong những bạn cần chú ý - lĩnh vực không thuộc về các lớp con - nó thuộc về cha mẹ và đó là quan trọng vì nó là "yêu cầu" của cha mẹ và vì cha mẹ có thể sử dụng nó

2) Khi phân lớp phụ từ cha mẹ bạn rất ý thức về trường này vì khi bạn triển khai hàm tạo, bạn phải truyền nó. Nếu tôi thấy cách giải quyết đầu tiên tôi sẽ không biết phải hiểu gì từ nó, theo cách này tôi hiểu rằng lớp cha cần trường này để làm việc, vì vậy nó phải có giá trị có ý nghĩa.

lưu ý: nếu bạn có một lớp có 10 trường cần được khởi tạo thì có thể có lỗi trong thiết kế của bạn.

0

1. Trên thực tế nó không phải là về những gì người ta thích nhưng nó về linh hoạt và khả năng thích nghi với những thay đổi để.

2. Luôn luôn tốt hơn để Đóng gói Hành vi tiếp tục thay đổi vào giao diện hoặc lớp Tóm tắt.

3. Bạn 1 Cách giải quyết sẽ được tốt ở những nơi bạn cần thực hiện khác nhau cho hành vi tương tự trong các lớp khác nhau. Sau đó, tại địa chỉ này, giao diện hoặc Giải pháp thứ nhất của bạn sẽ là một lựa chọn tốt.

Ví dụ:

Cân nhắc Painting như một lớp với paint() Method.

Bây giờ

paint() phương pháp có thể có vuốt ve, trượt, bóng vv phong cách làm việc đó.

Sau đó, tốt hơn là đóng gói phương thức đó vào lớp Tóm tắt hoặc Giao diện.

public interface Paint{ 

paintDoIt(String style); 

} 

4.của bạn 2 Wordaround sẽ được tốt ở một nơi, nơi bạn muốn hành vi nhất định được PHẢI thực hiện bởi Subclass.

Ví dụ:

Cân nhắc xe như một lớp trừu tượng, Bây giờ to be car của nó rất quan trọng là nó phải có một chỉ đạo, 4 bánh xe, động cơ, vv Vì vậy, các tính năng này phải được thực hiện.

nơi như các tính năng khác như hệ thống âm nhạc, màn hình LCD, v.v ... là tùy chọn và tùy thuộc vào loại xe.

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