2010-10-01 47 views
6

Tôi có mã kiểm tra sau:Không thể biên dịch một lớp mà thực hiện một giao diện không có loại tham số

public interface Container<I> { 
    public void addClass(Class<?> clazz); 
} 

public class MyContainer implements Container { 
    public void addClass(Class<?> clazz) {} 
} 

và tôi nhận được lỗi sau khi cố gắng biên dịch hai lớp này:

MyContainer. java: 1: MyContainer không trừu tượng và không ghi đè lên phương thức trừu tượng addClass (java.lang.Class) trong vùng chứa

Nếu tôi thêm loại vào giao diện vùng chứa e trong MyContainer (chẳng hạn như <Object>), tôi không gặp lỗi.

Vấn đề là tôi giới thiệu tham số kiểu cho vùng chứa, là một phần của API công khai, do đó, để tương thích, tôi không thể có tất cả các lớp triển khai không thể biên dịch được.

Bất kỳ ai có ý tưởng nào? Đây có phải là vấn đề xóa bỏ loại không? Có cách giải quyết nào không?

Trả lời

7

Tôi nghĩ rằng vấn đề là nếu bạn sử dụng các loại thô ở bất kỳ đâu trong khai báo lớp, bạn sắp loại bỏ ra khỏi generics. Vì vậy, điều này sẽ làm việc - lưu ý thay đổi tham số.

public class MyContainer implements Container { 
    public void addClass(Class clazz) {} 
} 

Từ section 4.8 of the JLS:

Các superclasses (tương ứng, superinterfaces) của một loại nguyên liệu là tẩy xóa của superclasses (superinterfaces) của bất kỳ lời gọi tham số của nó.

tôi tin đó là các bit có liên quan ... xóa bỏ hoàn của Container<T>.addClass(Class<?> clazz)addClass(Class clazz).

Nhưng có, về cơ bản trừ khi đây là mã kế thừa chính hãng, bạn nên xem giới thiệu thông số loại vào giao diện dưới dạng thay đổi đột phá.

+0

@ xây dựng Skeet- sẽ helpful..TIA – hakish

+0

Tôi hiểu rồi, cảm ơn bạn Jon. Đã chấp nhận. –

3

Bắt thoát khỏi nếu <?> sửa nó:

public void addClass(Class clazz) {} 

Các thông báo lỗi không phải là rất mô tả:

Tên đụng độ: Phương pháp addClass (Class) của loại MyContainer có tẩy xoá tương tự như addClass (Class) loại Container nhưng không ghi đè lên nó

Điều này có nghĩa là cả hai phương pháp của bạn đều giống nhau khi thứ các kiểu eir bị xóa, nhưng phương thức lớp con không thực sự thực thi/ghi đè lên một từ lớp siêu lớp/giao diện.Điều này không có ý nghĩa nhiều, và tôi cho rằng đó là vì bạn đã chọn không sử dụng Generics trong phân lớp của bạn, bạn phải dính vào đó (và không tham số Class)

3

Nếu lớp của bạn sử dụng Generics thì một giải pháp đơn giản sẽ làm điều này:

interface Container<I> { 
    public void addClass(Class<?> clazz); 
} 

class MyContainer<I> implements Container<I> { 
    public void addClass(Class<?> clazz) {} 
} 

Hoặc nếu bạn đã biết các loại container mà bạn có,

class MyContainer implements Container<ContainerType> { 
    public void addClass(Class<?> clazz) {} 
} 

Nếu lớp học của bạn không sử dụng Generics (pre 1.5) thì bạn có thể không có phần <?>. Vì vậy, sẽ không có bất kỳ vấn đề thực sự ở đây.

class MyContainer implements Container { 
    public void addClass(Class clazz) {} 
} 
0

Thực hiện giao diện của bạn như sau nên làm việc (theo loại chô bôi):

public class MyContainer implements Container { 
    public void addClass(Class clazz) {} 
} 
Các vấn đề liên quan