2011-09-15 37 views
9

Tôi có muốn tạo một giao diện:Có thể có một phương thức giao diện được định nghĩa với kiểu trả về chung và việc triển khai cụ thể xác định kiểu trả về không?

public interface OperandValue 
{ 
    <T> T getValue(); 
} 

Sau đó tôi muốn có một thực hiện cụ thể như thế này:

public class NumberOperandValue implements OperandValue 
{ 
    @Override 
    public <Integer> Integer getValue() 
    { 
     // some integer value that is set elsewhere 
     return 1; 
    } 
} 

Eclipse được nhấn mạnh <Integer> đem lại cho tôi một cảnh báo nói rằng:

Thông số loại Số nguyên đang ẩn loại Integer

Tôi đánh giá cao bất kỳ đề xuất nào về việc liệu điều này có thể hoạt động bằng cách nào đó hay không. Tôi nhận ra rằng tôi có thể xác định loại chung ở cấp độ giao diện và không phải là mức phương thức, nhưng muốn thử làm việc này nếu có thể.

Trả lời

22

Bạn có thể muốn thay đổi giao diện cho:

public interface OperandValue<T> 
{ 
    T getValue(); 
} 

Và việc thực hiện để:

public class NumberOperandValue implements OperandValue<Integer> 
{ 
    @Override 
    public Integer getValue() 
    { 
     // some integer value that is set elsewhere 
     return 1; 
    } 
} 

Bây giờ bạn đang nói giao diện kiểu bạn muốn phương pháp đó để quay trở lại. Nói cách khác, bạn đang tạo kiểu giao diện chung chung, chứ không phải là khai báo phương thức. Nhưng đó có vẻ là những gì bạn muốn.

Như một mặt lưu ý:

public <Integer> Integer getValue() 

Trên thực tế có nghĩa là, 'xác định một tham số kiểu generic với tên 'Integer'' nơi getValue trả về "Integer" kiểu đó bạn vừa xác định.

Đáp Để Steve Comments Dưới:

khi tôi loại bỏ các <Integer> từ việc thực hiện phương pháp của tôi mà tôi thì nhận được một cảnh báo nói rằng: Type safety: The return type Integer for getValue() from the type NumberOperandValue needs unchecked conversion to conform to T from the type OperandValue

Đó thông điệp cảnh báo chỉ ra rằng bạn phá vỡ các quy tắc khi sử dụng Generics Java. Để xem lý do tại sao, hãy xem xét chữ ký phương thức có nghĩa là gì trước khi bạn xóa thông số loại <Integer>.

public <Integer> Integer getValue() 

chữ ký này có nghĩa là phương pháp getValue trả về một giá trị kiểu Integer nơi Integer được định nghĩa là tham số kiểu generic bạn xác định giữa các dấu ngoặc nhọn. Ý nghĩa của chuỗi Integer là hoàn toàn tùy ý và sẽ phải hoàn toàn tương đương như:

public <T> T getValue() 

Để rõ ràng, chúng ta hãy gắn bó với phiên bản này của phương pháp chữ ký của bạn cho các mục đích của câu hỏi của bạn. Điều gì sẽ xảy ra khi chúng tôi xóa thông số loại?

public T getValue() 

Bây giờ nếu bạn cố gắng biên dịch, bạn sẽ gặp lỗi T không xác định. Tuy nhiên, vì loại chữ ký ban đầu của bạn tuyên bố tham số kiểu với tên Integer, khi bạn gỡ bỏ nó, bạn chỉ còn lại:

public Integer getValue() 

Integerđã một loại được xác định trước, chữ ký phương pháp vẫn còn hợp pháp về mặt kỹ thuật . Tuy nhiên, nó chỉ là một tai nạn mà tên của tham số kiểu của bạn xảy ra giống như một kiểu đã tồn tại.

Hơn nữa, vì giao diện của bạn đã khai báo chữ ký phương thức với số generics, trình biên dịch Java tạo ra cảnh báo khi bạn xóa nó khỏi quá trình triển khai. Cụ thể, trình biên dịch lo ngại rằng trong lớp cơ sở, kiểu trả về của phương thức là tham số generic (loại-xóa thành Object) có tên là Integer, không phải là cùng loại (cũng không được biết là kiểu tương thích với) lớp hệ thống có tên là Integer (hoặc java.lang.Integer chính xác).

+0

Có thể có chính phương thức giao diện chung không? Nếu vậy, làm thế nào bạn sẽ đạt được nó? – Kal

+1

@Kal, vâng, có thể. Nhưng không thể "cắm vào" loại cụ thể trong lớp triển khai. Nếu phương thức là generic có nghĩa là * người gọi * của phương thức có trách nhiệm cung cấp đối số kiểu. –

+0

Cảm ơn Kirk. Tôi hiểu rồi. Nếu định nghĩa giao diện được định nghĩa bởi OP, thì việc triển khai sẽ có phương thức được định nghĩa là '@Override public T getValue()' cũng. Chính xác? – Kal

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