2012-01-01 24 views
7

Với đoạn mã sau:Không thể sử dụng so sánh với cha-con trai-cháu trai thừa kế

public abstract class Participant { 
    private String fullName; 

    public Participant(String newFullName) { 
     this.fullName = new String(newFullName); 
    } 

    // some more code 
} 


public class Player extends Participant implements Comparable <Player> {  
    private int scoredGoals; 

    public Player(String newFullName, int scored) { 
     super(newFullName); 
     this.scoredGoals = scored; 
    } 

    public int compareTo (Player otherPlayer) { 
     Integer _scoredGoals = new Integer(this.scoredGoals); 
     return _scoredGoals.compareTo(otherPlayer.getPlayerGoals()); 
    } 

    // more irrelevant code 
} 

public class Goalkeeper extends Player implements Comparable <Goalkeeper> { 
    private int missedGoals;   

    public Goalkeeper(String newFullName) { 
     super(newFullName,0); 
     missedGoals = 0; 
    } 

    public int compareTo (Goalkeeper otherGoalkeeper) { 
     Integer _missedGoals = new Integer(this.missedGoals); 
     return _missedGoals.compareTo(otherGoalkeeper.getMissedGoals()); 
    } 

    // more code 
} 

Vấn đề là Goalkeeper sẽ không complie.

Khi tôi cố gắng để biên dịch mã Eclipse ném:

The interface Comparable cannot be implemented more than once with 
different arguments: Comparable<Player> and Comparable<Goalkeeper> 

Tôi không cố gắng để so sánh với Player, nhưng với Goalkeeper, và chỉ với anh ta.

Tôi đang làm gì sai?

+0

Xin vui lòng bạn có thể sửa chữa các vết lõm và khoảng trắng trong mã ví dụ của bạn. Rất khó đọc. –

+0

Xong, xin lỗi! Tôi hy vọng nó không sao. – ron

+0

Tại sao 'new String()' trong các hàm tạo? Chuỗi là bất biến! – fge

Trả lời

4

Theo như logic của thiết kế của bạn, bạn không làm gì sai. Tuy nhiên, Java có một hạn chế ngăn cản bạn thực hiện cùng một giao diện chung với các tham số kiểu khác nhau, đó là do cách nó thực hiện Generics (thông qua loại tẩy xóa).

Trong mã của bạn, Goalkeeper được kế thừa từ Player việc triển khai Comparable <Player> và cố gắng tự thêm Comparable <Goalkeeper>; Điều này không được phép.

Cách đơn giản nhất để giải quyết hạn chế này là để ghi đè Comparable <Player> trong Goalkeeper, đúc người chơi thông qua vào Goalkeeper, và so sánh nó với this thủ môn.

Sửa

public int compareTo (Player otherPlayer) { 
    Goalkeeper otherGoalkeeper = (Goalkeeper)otherPlayer; 
    Integer _missedGoals = new Integer(this.missedGoals); 
    return _missedGoals.compareTo(otherGoalkeeper.getMissedGoals()); 
} 
+0

Bạn có nghĩa là để làm điều này: "public class Thủ môn kéo dài chơi thực hiện tương đương " ... \t public int compareTo (Thủ môn otherGoalkeeper) \t { \t \t _missedGoals Integer = new Integer (this.missedGoals); \t \t return _missedGoals.compareTo (otherGoalkeeper.getMissedGoals()); \t} "?? – ron

+2

@ron Bạn thậm chí không phải thực hiện' thực hiện so sánh ': nó có bởi vì bạn mở rộng' Trình phát'. Chỉ cần làm như sau: '@Override public int compareTo (Player otherGoalkeeper) {...} ' – dasblinkenlight

+0

đó là vấn đề: xin vui lòng nhận thấy rằng lớp Player không có missedGoals lĩnh vực, và lớp Goalkepper làm tôi đã làm điều này:. public int compareTo (Thủ môn otherGoalkeeper) \t { \t \t _missedGoals Integer = new Integer (this.missedGoals); \t \t return _missedGoals.compareTo (otherGoalkeeper.getMissedGoals()); \t} – ron

11

Vấn đề được mô tả trong Generics FAQ #401 Angelika Langer của:

thể một lớp thực hiện instantiations khác nhau của cùng một giao diện chung ?

Không, loại không được trực tiếp hoặc gián tiếp lấy được từ hai phiên âm khác nhau của cùng một giao diện chung.

Lý do cho hạn chế này là bản dịch theo loại xóa. Sau khi nhập xóa các cảnh báo khác nhau của cùng một giao diện chung thu gọn thành cùng một loại thô. Khi thời gian chạy không có sự phân biệt giữa các phiên âm khác nhau nữa.

(tôi khuyên bạn nên kiểm tra ra các mô tả toàn bộ các vấn đề:. Nó thú vị hơn những gì tôi đã trích dẫn)

Để làm việc xung quanh hạn chế này, bạn có thể thử như sau:

public class Player<E extends Player> extends Participant implements Comparable<E> { 
    // ... 
    public int compareTo(E otherPlayer) { 
     Integer _scoredGoals = this.scoredGoals; 
     return _scoredGoals.compareTo(otherPlayer.getPlayerGoals()); 
    } 
    // ... 
} 


public class Goalkeeper extends Player<Goalkeeper> { 
    // ... 
    @Override 
    public int compareTo(Goalkeeper otherGoalkeeper) { 
     Integer _missedGoals = this.missedGoals; 
     return _missedGoals.compareTo(otherGoalkeeper.getMissedGoals()); 
    } 
    // ... 
} 
+0

+1 để đề cập đến nguồn thông tin đầy đủ về chủ đề này từ Angelika Langer. – Kjellski

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