Giả sử một lúc bạn có thể làm những gì bạn mô tả:
class B extends A { ... }
Collection<A> collecA;
List<B> listB;
collecA = listB; // normally an error, but lets pretend its allowed
collecA.add(new A()); // PROBLEM!
Phương pháp gọi collecA.add(new A())
vẻ ổn kể từ collecA
là một bộ sưu tập chứa A
s. Tuy nhiên, nếu việc gán ở trên được cho phép, thì chúng tôi gặp vấn đề vì collecA
thực sự tham chiếu đến cá thể List<B>
- Tôi chỉ thêm A
vào danh sách chỉ có thể giữ B
s!
Người hỏi cũng cho biết:
Tôi không thể hiểu tại sao từ Bộ sưu tập được thực hiện bởi danh sách.
Không quan trọng Bộ sưu tập là siêu lớp của Danh sách. Bài tập này là bất hợp pháp ngay cả khi bạn sử dụng hai danh sách.
class B extends A { ... }
List<A> listA;
List<B> listB;
listA = listB; // still an error, still leads to the same problem
Điều quan trọng là các List<A>
biến có thể tham khảo chỉ List
s có thể chứa A
s. Tuy nhiên, một ví dụ List<B>
không được giữ A
s. Do đó, một biến số List<A>
như listA
không thể được chỉ định tham chiếu đến List<B>
phiên bản được gọi bằng listB
.
Hoặc nói tổng quát hơn: B
là một lớp con của A
không không ngụ ý rằng SomeGenericClass<B>
là một lớp con của SomeGenericClass<A>
(JLS §4.10: subtyping không mở rộng thông qua các loại generic: T <: U
không có nghĩa là C<T> <: C<U>
.)
Đó là ví dụ này/loại suy từ Java Generics Tutorial đã giúp tôi hiểu điều này:
http://java.sun.com/docs/books/tutorial/java/generics/subtyping.html
"Hiểu tại sao trở nên dễ dàng hơn nhiều nếu bạn nghĩ về đối tượng hữu hình - những thứ bạn có thể thực sự hình ảnh - ví dụ như một cái lồng:
// A cage is a collection of things, with bars to keep them in.
interface Cage<E> extends Collection<E>;
...
Cage<Lion> lionCage = ...;
Cage<Butterfly> butterflyCage = ...;
Nhưng những gì về một "lồng động vật"? Anh là mơ hồ, vì vậy để được chính xác chúng ta hãy giả sử chúng ta đang nói về một "lồng tất cả động vật" :
Cage<Animal> animalCage = ...;
Đây là một cái lồng được thiết kế để giữ tất cả các loại động vật, pha trộn với nhau. Nó phải có các thanh đủ mạnh để giữ trong sư tử, và khoảng cách đủ gần để giữ trong những con bướm.
...
Vì sư tử là một loại động vật (Sư tử là một loại động vật), câu hỏi sau đó sẽ trở thành "Lồng sư tử là một loại lồng động vật? Cage<Lion>
là loại phụ của Cage<Animal>
?". Theo định nghĩa trên của lồng động vật, câu trả lời phải là "không". Điều này thật đáng ngạc nhiên! Nhưng nó làm cho cảm giác hoàn hảo khi bạn nghĩ về nó: Một cái lồng sư tử không thể được giả định để giữ trong bướm, và một cái lồng bướm không thể được giả định để giữ trong sư tử. Do đó, không phải lồng có thể được coi là một "tất cả động vật" lồng:..
animalCage = lionCage; // compile-time error
animalCage = butterflyCage; // compile-time error
"
Tốt dễ hiểu giải thích Bert Tôi luôn đánh giá cao ngớ ngẩn suy khi cố gắng tìm hiểu Generics và thừa kế Kartoch nên – tgai
@Tamon - Rất vui khi bạn (và hy vọng những người khác) thấy dễ hiểu. Tôi đã có cùng một vấn đề hiểu biết về generics và thừa kế (chưa đề cập đến các ký tự chung), vì vậy nó lấy một ví dụ mới như trong Java Generics Tutorial để lấy nó trong đầu của tôi.Tôi lấy một tìm kiếm cho 'java generic cast animal cage' để nhớ chính xác nơi tôi đọc tương tự này. :-) –
Rất tốt lời giải thích thực sự ... – Kartoch