Hãy hiển thị một ví dụ điển hình cho hiệp phương sai và đối nghịch trong Java.Chứng minh hiệp phương sai và contravariance trong Java?
Trả lời
Hiệp phương sai:
class Super {
Object getSomething(){}
}
class Sub extends Super {
String getSomething() {}
}
Sub # getSomething là hiệp biến vì nó trả về một lớp con của kiểu trả về của Siêu # getSomething (nhưng fullfills hợp đồng Super.getSomething())
Contravariance
class Super{
void doSomething(String parameter)
}
class Sub extends Super{
void doSomething(Object parameter)
}
Sub # doSomething là contrava riant bởi vì nó có một tham số của một superclass của tham số của Super # doSomething (nhưng, một lần nữa, fullfills hợp đồng của Super # doSomething)
Lưu ý: ví dụ này không hoạt động trong Java. Trình biên dịch Java sẽ quá tải và không ghi đè phương thức doSomething() - Method. Các ngôn ngữ khác hỗ trợ kiểu đối nghịch này.
Generics
Đây cũng là có thể cho Generics:
List<String> aList...
List<? extends Object> covariantList = aList;
List<? super String> contravariantList = aList;
Bây giờ bạn có thể truy cập vào tất cả các phương pháp covariantList
mà không mất một tham số chung (vì nó phải được một cái gì đó "mở rộng đối tượng"), nhưng getters sẽ hoạt động tốt (vì đối tượng trả về sẽ luôn là loại "Đối tượng")
Điều ngược lại là đúng với contravariantList
: Bạn có thể truy cập tất cả các phương thức với các tham số chung (bạn biết nó phải là siêu lớp của "Chuỗi", vì vậy bạn luôn có thể vượt qua một), nhưng không có getters (Loại trả về có thể là bất kỳ siêu loại nào khác của Chuỗi)
Nhìn vào số Liskov substitution principle. Trong thực tế, nếu lớp B mở rộng lớp A thì bạn sẽ có thể sử dụng B bất cứ khi nào A được yêu cầu.
này không trả lời câu hỏi và gây hiểu nhầm. Sẽ hoàn toàn có thể thiết kế một hệ thống biến thể phá vỡ tính chính xác ngữ nghĩa và do đó vi phạm LSP. –
đây không phải là trường hợp của 'biến thể contra'. 'super.doSomething (" String ")' không thể được thay thế bằng 'sub.doSomething (Object)'. – zinking
Đồng phương sai: Iterable và Iterator. Nó hầu như luôn luôn có ý nghĩa để xác định một biến thể Iterable
hoặc Iterator
. Iterator<? extends T>
có thể được sử dụng chỉ là Iterator<T>
- nơi duy nhất mà thông số loại xuất hiện là loại trả về từ phương thức next
, do đó, nó có thể được chuyển an toàn lên T
. Nhưng nếu bạn có S
mở rộng T
, bạn cũng có thể gán Iterator<S>
cho một biến loại Iterator<? extends T>
. Ví dụ, nếu bạn đang xác định một phương pháp tìm:
boolean find(Iterable<Object> where, Object what)
bạn sẽ không thể gọi nó với List<Integer>
và 5
, vì vậy nó tốt hơn định nghĩa là
boolean find(Iterable<?> where, Object what)
Contra-sai: sánh. Nó hầu như luôn luôn có ý nghĩa để sử dụng Comparator<? super T>
, bởi vì nó có thể được sử dụng giống như Comparator<T>
. Thông số loại chỉ xuất hiện dưới dạng loại tham số phương thức compare
, vì vậy, T
có thể được chuyển an toàn đến thông số đó.Ví dụ nếu bạn có một DateComparator implements Comparator<java.util.Date> { ... }
và bạn muốn sắp xếp một List<java.sql.Date>
với so sánh đó (java.sql.Date
là một sub-class của java.util.Date
), bạn có thể làm với:
<T> void sort(List<T> what, Comparator<? super T> how)
nhưng không phải với
<T> void sort(List<T> what, Comparator<T> how)
- 1. Hiệp phương sai và contravariance trong ngôn ngữ lập trình
- 2. đại biểu Action, Generics, hiệp phương sai và contravariance
- 3. C# Đúc generics (hiệp phương sai và contravariance?)
- 4. Hiệp phương sai/Contravariance với một biểu thức linq
- 5. generics java hiệp phương sai
- 6. IList sử dụng hiệp phương sai và contravariance trong C#, điều này có khả thi không?
- 7. NET Hiệp phương sai
- 8. hiệp phương sai trong C#
- 9. Hiệp phương sai so với contravariance liên quan đến thừa kế lớp
- 10. Hiệp phương sai/contravariance: làm thế nào để làm cho đoạn mã sau biên dịch
- 11. đại biểu hiệp phương sai và Contavariance
- 12. Hiệp phương sai chung và đối nghịch
- 13. Java sưu tập hiệp phương sai vấn đề
- 14. Hiệp phương sai và suy luận tương ứng trong C# 4.0
- 15. vọt Scala thấp hơn loại và hiệp phương sai
- 16. Tính toán ma trận hiệp phương sai
- 17. Câu hỏi về C# hiệp phương sai
- 18. Tính hiệp phương sai với Python và Numpy
- 19. Tại sao khái niệm "hiệp phương sai" và "Contravariance" được áp dụng trong khi thực hiện các phương thức của một giao diện?
- 20. Delegate Hiệp phương sai lầm Confusion!
- 21. Sự khác biệt giữa hiệp phương sai và Contra-phương sai
- 22. Tại sao khai báo hiệp phương sai này?
- 23. Ma trận hiệp phương sai LARGE trong R
- 24. Hiệp phương sai trong lập trình loại cấp
- 25. "Hiệp phương sai" của System.Nullable <> struct
- 26. Khi nào C++ hiệp phương sai giải pháp tốt nhất?
- 27. Chứng minh và giải quyết BigO
- 28. Xác minh chứng chỉ PKCS # 7 trong Java
- 29. Không hiệp phương sai/contravariance áp dụng cho các loại chuyển đổi ngầm mà không thực hiện một giao diện chung?
- 30. ICA - Độc lập thống kê và giá trị riêng của ma trận hiệp phương sai
Ví dụ đầu tiên về contravariance không hoạt động trong Java. doSomething() trong lớp Sub là quá tải, không phải là ghi đè. –
Thật vậy. Java không hỗ trợ đối số contravariant trong subtyping. Chỉ hiệp phương sai cho các kiểu trả về phương thức quan tâm (như trong ví dụ đầu tiên). –
Câu trả lời hay. Hiệp phương sai có vẻ hợp lý với tôi. Nhưng bạn có thể chỉ cho tôi một đoạn trong JLS mô tả contravariance? Tại sao Sub.doSomething được gọi? – Mikhail