2009-04-08 51 views
5

Tôi có một lớp cơ sở có phương thức getType() trừu tượng. Tôi muốn các lớp con có thể triển khai phương thức này và cung cấp lớp thực tế để sử dụng.Trả về loại lớp lồng nhau trong Java

Trong mã, giống như sau:

public abstract class A { 
    public static interface Tile; 

    protected abstract Class<Tile> getTileClass(); 
} 

public class B extends A { 
    public static class MyTile implements A.Tile { } 

    @Override 
    protected abstract Class<A.Tile> getTileClass() { 
     MyTile t = new MyTile(); // WORKS 
     return MyTile;   // ERROR HERE 
    } 
} 

Vấn đề ở đây là tôi nhận được "MyTile không thể giải quyết" trong dòng đánh dấu. Vì vậy, tôi đang cố gắng để trở lại này thay vì:.

trở MyTile mới() getClass()

nhưng bây giờ Eclipse nói với tôi:

Loại không phù hợp: không thể chuyển đổi từ Lớp < chụp # 1 trong số? mở rộng B.MyTile > Class < A.Tile >

mà tôi thậm chí không chắc chắn nếu có có thể là một lỗi trong Eclipse đây nhất (capture # 1?).

Tiếp theo, tôi sẽ từ bỏ các giao diện và cố gắng sử dụng lớp Gạch nền trừu tượng. Với sự giúp đỡ của Eclipse, tôi kết thúc với đoạn mã sau đó dường như biên dịch:

public abstract class A { 
    public static abstract class Tile; 

    protected abstract Class<? extends Tile> getTileClass(); 
} 

public class B extends A { 
    public static class MyTile exends A.Tile { } 

    @Override 
    protected abstract Class<? extends A.Tile> getTileClass() { 
     return new MyTile().getClass(); // WORKS 
     return MyTile;     // "Cannot be resolved" 
    } 
} 

Vì vậy, tôi về cơ bản dường như có ba câu hỏi:

1) Có thể được điều này để làm việc với A .Tile là một giao diện?

2) Khi sử dụng lớp cơ sở, là Class<? extends X> thực sự là con đường chính xác?

3) Và làm cách nào tôi có thể trả về tham chiếu lớp B.MyTile lồng nhau của tôi từ bên trong phương thức? Phải làm new MyTile().getClass() không thể đúng, phải không?

+0

Có thể trả lại một 'Lớp' thay vì đối tượng không phản chiếu là một ý tưởng tồi. –

+0

@Tom Trả về một lớp trong ngữ cảnh của các loại được chọn là một mẫu rất phổ biến, cho phép bạn kiểm tra kiểu * đã chọn *, ví dụ, một bộ sưu tập, tại thời gian chạy. Tôi biết không có cách nào khác, trên thực tế ... – Varkhan

Trả lời

6

Ghi đè kiểu biến thể và biến thể không hoạt động tốt với nhau. Bạn phải khai báo rõ ràng getTileClass() khi trả về một lớp có thể là một lớp con của A.Tile.

Bạn cũng có thể truy cập đối tượng lớp của MyTile mà không cần instanciating nó, với MyTile.class.

Hãy thử điều này thay vì:

public abstract class A { 
    public static interface Tile; 

    protected abstract Class<? extends Tile> getTileClass(); 
} 

public class B extends A { 
    public static class MyTile implements A.Tile { } 

    @Override 
    protected Class<MyTile> getTileClass() { 
     return MyTile.class; 
    } 
} 

Thậm chí tốt hơn sẽ là để thực hiện chương generic. Bạn vẫn phải sử dụng kéo dài trong định nghĩa kiểu lớp, nhưng bạn có thể có một chút cụ thể hơn:

public abstract class A<T extends A.Tile> { 
    public static interface Tile; 

    protected abstract Class<? extends T> getTileClass(); 
} 

public class B extends A { 
    public static class MyTile implements A.Tile { } 

    @Override 
    protected Class<MyTile> getTileClass() { 
     return MyTile.class; 
    } 
} 
+0

có thể sao chép và dán lỗi, nhưng có thể một phương pháp trừu tượng có một cơ thể? chính xác phải là "Lớp bảo vệ getTileClass {..." –

+0

@Carlos yes, đó là một câu trả lời quá mức c/p – Varkhan

+0

Câu trả lời hay. Đây có phải là vấn đề chỉ vì hiệp phương sai hay nói chung không? – Uri

-1
public abstract class A { 
    public static interface Tile {}; 

    // I return something that is-a Tile 
    protected abstract Tile getTileClass(); 
} 

public class B extends A { 
    public static class MyTile implements A.Tile { } 

    @Override 
    protected abstract Tile getTileClass() { 
     return new MyTile(); 
    } 
} 

Không cần cho generics, bạn chỉ muốn nói rằng bạn quay trở lại một Tile hoặc Tile lớp con.

Ngẫu nhiên, một giao diện tĩnh công khai trong một lớp là "mùi mã"; hoặc làm cho nó được bảo vệ, vì vậy chỉ có các lớp con của A mới có thể triển khai Tile hoặc đặt nó trong giao diện cấp cao nhất của nó. Đặt trong một nhưng cho phép bất cứ ai thực hiện nó sẽ gửi một thông điệp hỗn hợp.

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