2010-02-19 25 views
5

Tôi đang sử dụng thư viện GWT. Có một lớp cơ sở được gọi là Widget mà tất cả các Widgets kế thừa từ đó. Một số Widget thực hiện một số giao diện nhất định (ví dụ: HasText), một số khác thì không. Đôi khi tôi muốn đảm bảo rằng một cái gì đó được chuyển như một đối số cho một hàm là một lớp nhất định VÀ thực hiện một giao diện nhất định.Tôi có thể đảm bảo nhập trên giao diện VÀ lớp của đối số không?

Ví dụ: tôi muốn có một hàm lấy đối số X, trong đó X là thuộc loại tiện ích con loại AND của loại giao diện HasText. Tôi muốn có hành vi này bởi vì chỉ Widgets có thể được thêm vào Layout container, và HasText chỉ định bộ hành vi hoàn chỉnh mà tôi thực sự cần từ Widget nói.


Ở dạng mã giả, nó có thể là:

public void fx(I_AM_A_Widget_AND_IMPLEMENT_INTERFACE_HasText x){ 
    //do stuff with x, which is guaranteed to be a Widget AND implement HasText 
} 

Đây có phải là bằng mọi cách có thể trong Java? Nếu có nhiều cách để làm như vậy, có cách ưa thích/tốt hơn không?

+0

Các trường hợp như thế này là lý do tại sao tôi ghét nhập danh nghĩa. – dsimcha

Trả lời

0

Cảm ơn bạn cho cả hai giải pháp của bạn. Cuối cùng, tôi quyết định rằng giải pháp tốt nhất là chỉ cần chỉ định các loại bị chặn ở phía trên cùng của định nghĩa lớp. Ví dụ: tôi đã sử dụng biểu mẫu

public class Example<Editable extends Widget & HasText> { 
    private Editable editor = null; 

    //do stuff in various methods (including the constructor) with the 
    //editor variable and the Editable type. 
} 

Tôi đã chọn giải pháp này vì một vài lý do.

  1. Cả hai giải pháp được đề cập ở trên đều yêu cầu sử dụng các phương pháp (boilerplate) không thực sự liên quan đến chức năng kinh doanh, mà thay vào đó liên quan đến việc phá vỡ giới hạn của ngôn ngữ.
  2. Anon, giải pháp của bạn là chính xác, nhưng tôi có vấn đề không thể khai báo biến sẽ giữ tham chiếu đến đối tượng chung mà phương thức của bạn trả về. Tôi tin rằng đây là trường hợp vì đối tượng chung trả về từ phương thức của bạn chỉ tồn tại ở cấp độ của phương thức chứ không phải lớp. Có lẽ tôi đã bỏ lỡ một số cú pháp có thể cho phép tôi khai báo các biến có thuộc tính chung?
  3. Yishai, giải pháp của bạn hoạt động tốt, nhưng sau đó tôi có vấn đề phải khai báo một phương pháp riêng biệt trong mọi giao diện mà tôi muốn đảm bảo hỗ trợ, điều này có vẻ cồng kềnh.
  4. Các loại bị chặn này được khai báo trong "tiêu đề" lớp học chỉ cần được khai báo một lần. Nó có vẻ giống như khai báo chi tiết nhất về các kiểu giới hạn chung có sẵn trong Java.
  5. Bạn có thể khai báo nhiều loại giới hạn trong tiêu đề "lớp".
  6. Nếu bạn sử dụng phương pháp này độc quyền, tất cả các loại giới hạn tiềm năng được khai báo tại cùng một vị trí trong mã của bạn.

Việc khai báo các loại bị chặn trong tiêu đề lớp là giải pháp tốt nhất mà tôi đã chạy qua. Tôi vẫn muốn biết liệu họ có phải là cách để khai báo vĩnh viễn hay không (để nó có thể được truy cập qua các lớp khác nhau) một kiểu bị chặn, thay vì khai báo chúng cho mỗi lớp.

7

Bạn có thể có thể sử dụng một phương pháp chung chung ở đây:

public <T extends Widget & HasText> void fx(T x) 

Trình biên dịch sẽ suy ra các loại T tự động, vì vậy không có cú pháp thêm khi gọi phương pháp này.

1

Cách tôi xử lý việc này là thêm phương thức vào giao diện HasText để trả lại Widget và việc triển khai sẽ chỉ trả về điều này.

public class MyClass extends Widget implements HasText { 

      @Override 
      public Widget getMyWidget() { 
       return this; 
      } 
    } 

Vì vậy, nếu phương thức cần một Widget, bạn chỉ cần gọi phương thức getMyWidget() của HasText. Nó tạo ra một số boilerplate, nhưng nó giúp với việc kiểm tra kiểu tĩnh.

Nếu bạn không quan tâm nhiều đến việc kiểm tra kiểu tĩnh, bạn có thể chỉ cần có hợp đồng (câu lệnh trong JavaDoc) giao diện HasText chỉ được triển khai trên Widgets và sau đó chỉ cần truyền bất cứ khi nào bạn cần Widget.

Sau đó, bạn phương pháp chỉ trông giống như

public void fx(HasText text) //... 
Các vấn đề liên quan