উত্তর:
সহভেদাংক:
class Super {
Object getSomething(){}
}
class Sub extends Super {
String getSomething() {}
}
সাব # গেটসোমিং কিছুটা সমবায়ীয় কারণ এটি সুপার # গেটসোমথিংয়ের রিটার্ন টাইপের একটি সাবক্লাস প্রদান করে (তবে সুপার.গেটসোমিংথিং () এর চুক্তিটি পূর্ণ পূরণ করে)
Contravariance
class Super{
void doSomething(String parameter)
}
class Sub extends Super{
void doSomething(Object parameter)
}
সাব # ডোসোমিংটি বিপরীত কারণ এটি সুপার # ডসোসমিংয়ের প্যারামিটারের একটি সুপারক্লাসের প্যারামিটার নেয় (তবে, আবার সুপার # ডসোসমিংয়ের চুক্তিটি পূর্ণ করে তোলে)
বিজ্ঞপ্তি: এই উদাহরণটি জাভাতে কাজ করে না। জাভা সংকলক ওভারলোড করবে এবং doSomething () - পদ্ধতিকে ওভাররাইড করবে না। অন্যান্য ভাষা এই শৈলীর বিপরীতে সমর্থন করে।
জেনেরিক্স
জেনারিক্সের পক্ষে এটিও সম্ভব:
List<String> aList...
List<? extends Object> covariantList = aList;
List<? super String> contravariantList = aList;
আপনি এখন covariantList
সেই সমস্ত পদ্ধতিতে অ্যাক্সেস করতে পারেন যা জেনেরিক প্যারামিটার গ্রহণ করে না (যেমন এটি অবশ্যই "অবজেক্ট অবজেক্ট" হতে পারে) তবে গ্রাহকরা ভাল কাজ করবে (যেমন প্রত্যাবর্তিত বস্তু সর্বদা "অবজেক্ট" টাইপের হবে)
বিপরীতটি সত্য contravariantList
: আপনি জেনেরিক প্যারামিটারগুলির সাহায্যে সমস্ত পদ্ধতি অ্যাক্সেস করতে পারেন (আপনি এটি জানেন যে এটি অবশ্যই "স্ট্রিং" এর একটি সুপারক্লাস হতে হবে, যাতে আপনি সর্বদা একটি পাস করতে পারেন), তবে কোনও গেটর নেই (প্রত্যাবর্তিত প্রকারটি স্ট্রিংয়ের অন্য কোনও সুপার টাইপের হতে পারে) )
কো-ভেরিয়েন্স: আইটেবল এবং আইট্রেটার। এটি প্রায়শই সহ-বৈকল্পিক Iterable
বা সংজ্ঞা দেওয়ার জন্য অর্থবোধ করে Iterator
। Iterator<? extends T>
ঠিক তেমন ব্যবহার করা যেতে পারে Iterator<T>
- প্যারামিটার টাইপ করার একমাত্র জায়গাটি next
পদ্ধতি থেকে রিটার্নের ধরণ , তাই এটি নিরাপদে আপ-কাস্ট করা যেতে পারে T
। তবে আপনার যদি S
প্রসারিত হয় তবে আপনি বিভিন্ন ধরণের ভেরিয়েবলকেও T
বরাদ্দ করতে পারেন । উদাহরণস্বরূপ আপনি যদি একটি সন্ধানের পদ্ধতিটি সংজ্ঞায়িত করছেন:Iterator<S>
Iterator<? extends T>
boolean find(Iterable<Object> where, Object what)
আপনি এটির সাথে কল করতে সক্ষম হবেন না List<Integer>
এবং এটি আরও 5
ভাল হিসাবে সংজ্ঞায়িত করা হয়েছে
boolean find(Iterable<?> where, Object what)
বৈসাদৃশ্য: তুলনামূলক। এটি প্রায়শই ব্যবহার করার জন্য বুদ্ধি করে Comparator<? super T>
, কারণ এটি ঠিক যেমন ব্যবহার করা যায় Comparator<T>
। প্রকারের প্যারামিটারটি কেবল compare
পদ্ধতি প্যারামিটারের प्रकार হিসাবে উপস্থিত হয় , তাই T
এটি নিরাপদে প্রেরণ করা যায়। উদাহরণস্বরূপ, যদি আপনার একটি থাকে DateComparator implements Comparator<java.util.Date> { ... }
এবং আপনি List<java.sql.Date>
সেই তুলকটির সাথে একটি সাজানোর ( java.sql.Date
একটি উপ-শ্রেণি java.util.Date
) চান তবে আপনি এটি করতে পারেন:
<T> void sort(List<T> what, Comparator<? super T> how)
কিন্তু সাথে না
<T> void sort(List<T> what, Comparator<T> how)
এ Liskov প্রতিকল্পন নীতি । ফলস্বরূপ, যদি ক্লাস বি শ্রেণি A এর প্রসারিত করে তবে যখনই A এর দরকার হয় আপনার বি ব্যবহার করতে সক্ষম হবেন।
contra variant
বলার মতো ঘটনা নয় । super.doSomething("String")
দ্বারা প্রতিস্থাপন করা যায়নি sub.doSomething(Object)
।