কেউ কেউ বলে এটি এটি টাইপ এবং সাব টাইপগুলির মধ্যে সম্পর্কের বিষয়ে, অন্যরা বলে যে এটি টাইপ রূপান্তর সম্পর্কে এবং অন্যরা বলে যে এটি কোনও পদ্ধতিকে ওভাররাইট করা হয়েছে বা অতিরিক্ত বোঝা কিনা তা সিদ্ধান্ত নিতে এটি ব্যবহৃত হয়।
উপরের সবগুলো.
আন্তরিকভাবে, এই পদগুলি বর্ণনা দেয় যে কীভাবে উপজাতীয় সম্পর্কটি ধরণের রূপান্তর দ্বারা প্রভাবিত হয়। এটি হ'ল, A
এবং B
যদি প্রকারভেদ হয় তবে f
এটি একটি ধরণের রূপান্তর, এবং sub উপপ্রকার সম্পর্ক ( A ≤ B
যার অর্থ এটি A
একটি উপপ্রকার B
)
f
সমবায় হয় যদি A ≤ B
তা বোঝায়f(A) ≤ f(B)
f
যদি A ≤ B
তা বোঝায় তবে তা বিপরীতf(B) ≤ f(A)
f
উপরোক্ত দুটি হোল্ড না থাকলে আক্রমণকারী
আসুন একটি উদাহরণ বিবেচনা করা যাক। f(A) = List<A>
যেখানে List
ঘোষণা করা যাক
class List<T> { ... }
কি f
covariant, contravariant, অথবা পরিবর্তিত? Covariant অর্থ হবে যে একটি List<String>
একটি উপপ্রকার হয় List<Object>
, contravariant করে একটি List<Object>
একটি উপপ্রকার হয় List<String>
এবং পরিবর্তিত যে তন্ন তন্ন অন্যান্য একটি উপপ্রকার, অর্থাত্ List<String>
এবং List<Object>
অবিনিমেয় ধরনের হয়। জাভাতে, দ্বিতীয়টি সত্য, আমরা বলি (কিছুটা অনানুষ্ঠানিকভাবে) যে জেনেরিকগুলি অবিস্মরণীয়।
আরেকটি উদাহরণ. যাক f(A) = A[]
। কি f
covariant, contravariant, অথবা পরিবর্তিত? অর্থাত, স্ট্রিং কি [অবজেক্টের] একটি সাব টাইপ [], অবজেক্ট [] স্ট্রিংয়ের একটি উপপ্রকার [], বা অন্যটির উপপ্রকার নয়? (উত্তর: জাভাতে, অ্যারেগুলি কোভেরিয়েন্ট হয়)
এটি এখনও বিমূর্ত ছিল। এটি আরও কংক্রিট করার জন্য, আসুন দেখে নেওয়া যাক জাভাতে কোন অপারেশনগুলি উপ-টাইপের সম্পর্কের ক্ষেত্রে সংজ্ঞায়িত হয়। সহজ উদাহরণটি হ'ল অ্যাসাইনমেন্ট। বিবৃতি
x = y;
কেবল তখনই সংকলন করবে typeof(y) ≤ typeof(x)
। যে, আমরা ঠিক যে বিবৃতি শিখেছি
ArrayList<String> strings = new ArrayList<Object>();
ArrayList<Object> objects = new ArrayList<String>();
জাভাতে সংকলন করবে না, তবে
Object[] objects = new String[1];
ইচ্ছাশক্তি.
আর একটি উদাহরণ যেখানে সাব-টাইপের সম্পর্কের বিষয়টি হল একটি পদ্ধতির প্রার্থনা অভিব্যক্তি:
result = method(a);
অনানুষ্ঠানিকভাবে বলতে গেলে, এই বিবৃতিটি a
পদ্ধতির প্রথম প্যারামিটারের মান নির্ধারণ করে , তারপরে পদ্ধতির মূল অংশটি নির্বাহ করে এবং তারপরে পদ্ধতিগুলিকে মান ফেরত প্রদান করে মূল্যায়ন করা হয় result
। শেষ উদাহরণে প্লেইন অ্যাসাইনমেন্টের মতো, "ডান হাতের দিক" অবশ্যই "বাম হাতের" উপ-প্রকারের হতে হবে, অর্থাত্ এই বিবৃতিটি কেবলমাত্র যদি typeof(a) ≤ typeof(parameter(method))
ও হয় তবেই বৈধ হতে পারে returntype(method) ≤ typeof(result)
। এটি হল, যদি পদ্ধতি দ্বারা ঘোষণা করা হয়:
Number[] method(ArrayList<Number> list) { ... }
নিম্নলিখিত প্রকাশের কোনওটিই সংকলন করবে না:
Integer[] result = method(new ArrayList<Integer>());
Number[] result = method(new ArrayList<Integer>());
Object[] result = method(new ArrayList<Object>());
কিন্তু
Number[] result = method(new ArrayList<Number>());
Object[] result = method(new ArrayList<Number>());
ইচ্ছাশক্তি.
সাবটাইপিংয়ের বিষয়গুলি যেখানে ওভাররাইড হচ্ছে সেখানে অন্য উদাহরণ। বিবেচনা:
Super sup = new Sub();
Number n = sup.method(1);
কোথায়
class Super {
Number method(Number n) { ... }
}
class Sub extends Super {
@Override
Number method(Number n);
}
অনানুষ্ঠানিকভাবে, রানটাইম এটিকে আবার লিখবে:
class Super {
Number method(Number n) {
if (this instanceof Sub) {
return ((Sub) this).method(n); // *
} else {
...
}
}
}
চিহ্নিত লাইনটি সংকলনের জন্য, ওভাররাইডিং পদ্ধতির মেথড প্যারামিটার অবশ্যই ওভাররাইড হওয়া পদ্ধতির মেথড প্যারামিটারের একটি সুপারটাইপ হতে হবে এবং রিটার্ন টাইপ ওভাররাইড হওয়া পদ্ধতির একটির একটি উপ-টাইপ হতে হবে। সাধারণভাবে বলতে গেলে, f(A) = parametertype(method asdeclaredin(A))
অবশ্যই কমপক্ষে বিপরীত হতে হবে এবং অবশ্যই কমপক্ষে সমবায়ু হতে f(A) = returntype(method asdeclaredin(A))
হবে।
উপরের "কমপক্ষে" নোট করুন। সেগুলি ন্যূনতম প্রয়োজনীয়তাগুলি যে কোনও যুক্তিসঙ্গত স্ট্যাটিকালি টাইপ নিরাপদ বস্তু ভিত্তিক প্রোগ্রামিং ভাষা প্রয়োগ করবে, তবে একটি প্রোগ্রামিং ভাষা আরও কঠোর হতে পারে। জাভা ১.৪-এর ক্ষেত্রে, ওভাররাইডিং পদ্ধতিগুলি, অর্থাৎ ওভাররাইড করার সময় প্যারামিটারের ধরণগুলি এবং পদ্ধতির রিটার্নের ধরণগুলি অভিন্ন হতে হবে (টাইপ মুছে ফেলা ব্যতীত) parametertype(method asdeclaredin(A)) = parametertype(method asdeclaredin(B))
। জাভা ১.৫ থেকে, ওভাররাইড করার সময় কোভারিয়েন্ট রিটার্নের ধরণের অনুমতি রয়েছে, যেমন নীচে জাভা 1.5 তে সংকলন করা হবে তবে জাভা 1.4 এ নয়:
class Collection {
Iterator iterator() { ... }
}
class List extends Collection {
@Override
ListIterator iterator() { ... }
}
আমি আশা করি আমি সমস্ত কিছু আবৃত করেছি - বা বরং, পৃষ্ঠটি আঁচড়ান। তবুও আমি আশা করি এটি বিমূর্ত, তবে ধরণের বৈচিত্রের গুরুত্বপূর্ণ ধারণাটি বুঝতে সহায়তা করবে।