2012-09-27 22 views
5

Tôi có một lớp chung trừu tượng:Java Generics: Yêu cầu chung là lớp con của một loại nhất định

public abstract class AbstractMessageHandler<T extends AbstractMessageHandler> 
{ 
    public abstract List<String> getTypesOfMessages(); 
    public abstract void handleMessage(String message, CometClient client); 

    public T setResponseValues(AbstractMessage request, T response) 
    { 
     response.setCompanyId(request.getCompanyId()); 
     response.setMessageGroup(request.getMessageGroup()); 
     response.setUserId(request.getUserId()); 
     response.setTimeStamp(AbstractMessage.getCurrentTimeStamp()); 

     return response; 
    } 
} 

tôi cần những lớp con chung là một lớp con của lớp này. Trong các otherwords, generic phải là một lớp con của AbstractMessageHandler. Tuy nhiên điều này mang lại cho tôi các vấn đề biên dịch. Bất cứ ai có thể cho tôi biết những gì tôi đang làm sai?

Cảm ơn

+0

Đăng lỗi trình biên dịch. Và, hy vọng, bạn thực sự chỉ muốn yêu cầu một lớp con chung, 'T', là của' giao diện' mà 'AbstractMessageHandler' thực hiện về mặt lý thuyết, cái mà tôi tưởng tượng có tên là' MessageHandler'. Có liên quan, 'setResponseValues' rất có thể sẽ lấy tham số của nó là' Message' chứ không phải 'AbstractMessage'. Đây là những yêu cầu hạn chế không cần thiết, trừ khi chỉ đơn giản là không có 'giao diện' mà chúng thực thi. – pickypg

+0

Nếu không có ngữ cảnh, tôi sẽ tưởng tượng rằng AbstractMessageHandler trong ràng buộc kiểu của bạn yêu cầu một đối số kiểu. Bạn có chắc đây là thiết kế tốt nhất cho vấn đề của bạn không? Hoặc bạn có nghĩa là 'AbstractMessageHandler ? ' –

Trả lời

7

Bạn cần phải làm theo tấm gương của lớp Enum:

public abstract class AbstractMessageHandler<T extends AbstractMessageHandler<T>> 
+0

Tôi không đồng ý. Tôi không thấy bất kỳ lợi ích kiểu nào của điều này qua '>' cho mã mà anh ta đã đưa ra. Trong mọi trường hợp, 'Enum' là một trường hợp đặc biệt bởi vì các lớp con của' Enum' được tạo ra bởi ngôn ngữ và buộc phải phân lớp 'Enum' với tham số chung của chính nó. Điều đó không đúng với bất kỳ tình huống nào khác. Bạn không thể ép buộc điều đó trong bất kỳ tình huống nào khác. – newacct

+0

@newacct - thực sự, bạn có thể. bạn đã thử à? đây thực sự là một mô hình rất tiện dụng. Tôi đã sử dụng nó trong mã của tôi vì vậy tôi biết nó hoạt động. – jtahlborn

+0

Nếu bạn có 'lớp Foo mở rộng AbstractMessageHandler {...}' thì bạn có thể có 'lớp Bar mở rộng AbstractMessageHandler {...}'. Vì vậy, những gì thực sự làm điều này ràng buộc thực hiện? – newacct

0

Trong định nghĩa chung chung của bạn, bạn có thể làm <T extends SomeClass>

Ví dụ:

abstract class Processor<T extends String> { 
    abstract T process(); 
} 

Trong trường hợp của bạn, có vẻ như T nên mở rộng một số lớp Response, và không AbstractMessageHandler.

+1

Lưu ý: anh ấy đang ở hàng đầu tiên. Anh ấy đang gặp phải một số vấn đề khác. – pickypg

+0

Vâng, anh ấy nói thêm rằng trong khi tôi đang viết nó. –

0

Từ mã nhất định, nó không có vẻ như có bất kỳ cần phải làm cho lớp generic. Làm thế nào về một phương pháp chung chung thay vì (Tôi thậm chí đã làm cho nó tĩnh, vì nó dường như không phải là bạn cần phải sử dụng các đối tượng hiện tại tất cả):

public abstract class AbstractMessageHandler 
{ 
    public static <T extends AbstractMessageHandler> T setResponseValues(AbstractMessage request, T response) 
    { 
     response.setCompanyId(request.getCompanyId()); 
     response.setMessageGroup(request.getMessageGroup()); 
     response.setUserId(request.getUserId()); 
     response.setTimeStamp(AbstractMessage.getCurrentTimeStamp()); 

     return response; 
    } 
} 

Hoặc thậm chí tốt hơn, chỉ cần xác định một phương thức trên AbstractMessageHandler hoạt động trên đối tượng hiện tại. Sau đó, bạn không cần phương thức tĩnh này và bạn không có tham số lạ này mà bạn luôn quay trở lại.

public abstract class AbstractMessageHandler 
{ 
    public void setResponseValues(AbstractMessage request) 
    { 
     setCompanyId(request.getCompanyId()); 
     setMessageGroup(request.getMessageGroup()); 
     setUserId(request.getUserId()); 
     setTimeStamp(AbstractMessage.getCurrentTimeStamp()); 
    } 
} 
Các vấn đề liên quan