একাধিক ক্লাস সহ জাভা জেনারিক্স ওয়াইল্ডকার্ডিং


385

আমি একটি ক্লাস অবজেক্ট রাখতে চাই, তবে আমি ক্লাস এ-এর বিস্তৃতি এবং ইন্টারফেস বি বাস্তবায়নের জন্য যে শ্রেণীর প্রতিনিধিত্ব করে তা বাধ্য করতে চাই B.

আমি করতে পারি:

Class<? extends ClassA>

বা:

Class<? extends InterfaceB>

তবে আমি দুটোই পারি না এই কাজ করতে একটি উপায় আছে কি?

উত্তর:


613

আসলে, আপনি যা করতে পারেন তা করতে পারেন। আপনি যদি একাধিক ইন্টারফেস বা ক্লাস প্লাস ইন্টারফেস সরবরাহ করতে চান তবে আপনার ওয়াইল্ডকার্ডকে দেখতে এমন কিছু দেখতে হবে:

<T extends ClassA & InterfaceB>

পৃষ্ঠার নীচে সূর্য.কমের বিশেষত বাউন্ডেড প্রকারের পরামিতি বিভাগে জেনারিক্স টিউটোরিয়ালটি দেখুন । আপনি যদি প্রয়োজন চান তবে আপনি প্রয়োজনে একাধিক ইন্টারফেসের তালিকা করতে পারেন ।& InterfaceName

এটি নির্বিচারে জটিল হতে পারে। প্রদর্শনের জন্য, জাভাডকের ঘোষণা দেখুন Collections#max, যা (দুটি লাইনে আবৃত):

public static <T extends Object & Comparable<? super T>> T
                                           max(Collection<? extends T> coll)

এত জটিল কেন? জাভা জেনেরিক্স এফএকিউতে যেমন বলা হয়েছে: বাইনারি সামঞ্জস্যতা সংরক্ষণ করার জন্য

দেখে মনে হচ্ছে এটি পরিবর্তনশীল ঘোষণার জন্য কাজ করে না, তবে ক্লাসে জেনেরিক সীমানা লাগানোর সময় এটি কাজ করে। সুতরাং, আপনি যা চান তা করতে আপনাকে কয়েকটি হুপের মধ্য দিয়ে ঝাঁপিয়ে পড়তে হতে পারে। কিন্তু আপনি এটা করতে পারেন। আপনি নিজের ক্লাসে জেনেরিক সীমানা রেখে, এর মতো কিছু করতে পারেন:

class classB { }
interface interfaceC { }

public class MyClass<T extends classB & interfaceC> {
    Class<T> variable;
}

variableআপনি চান যে সীমাবদ্ধতা আছে পেতে । আরও তথ্য এবং উদাহরণের জন্য, জাভা 5.0 এর জেনেরিক্সের পৃষ্ঠা 3 দেখুন । দ্রষ্টব্য, মধ্যে <T extends B & C>, শ্রেণীর নামটি অবশ্যই প্রথম আসবে এবং ইন্টারফেসগুলি অনুসরণ করবে। এবং অবশ্যই আপনি কেবল একটি একক শ্রেণীর তালিকা করতে পারেন।


94
এটি সহায়ক। এটি উল্লেখ করার মতো যে ক্লাসটি অবশ্যই প্রথম আসবে, আপনি বলতে পারবেন না << টি ইন্টারফেসবি এবং ক্লাসএ বিস্তৃত হয় ''।
এরিকস

5
টির জন্য আপনি কীভাবে একইভাবে ক্লাস বাড়িয়ে দিতে পারেন বা একটি ইন্টারফেস প্রয়োগ করতে হবে?
রাগুনাথ জওহর

1
@ রাগুনাথ জওহর: আপনি এ সম্পর্কে খুব বেশি খোলামেলা হতে পারবেন না। আপনার কিছু সীমানা থাকতে হবে এবং তাদের মধ্যে একটি আগে থেকেই জেনে থাকবে আপনার ইন্টারফেসগুলি কোথায় থাকবে এবং কোথায় আপনার ক্লাস হবে এবং আপনি কীভাবে উত্তরাধিকার ব্যবহার করবেন। এটি টাইপ প্যারামিটারের জন্য আপনাকে অনেক বেশি জানতে হবে যদি এটি কোনও শ্রেণি বা ইন্টারফেস হয়।
এডি

4
আপনার উত্তরের প্রথম লাইনটি বলে "আপনার ওয়াইল্ডকার্ডটি দেখতে এমন কিছু হোক"। এই ?অভিব্যক্তির কোনও নেই , তাই এটি কি আসলেই "ওয়াইল্ডকার্ড"? আমি জিজ্ঞাসা করি কারণ টাইপ প্যারামিটারটি সত্যই যখন ওয়াইল্ডকার্ড হয় তখন আমি কাজ করতে ধারণাটি পুরো "একবারে দুটি প্রসারিত" করতে পারি না।
The111

1
হ্যাঁ, এটি আসলে কোনও ওয়াইল্ডকার্ড নয় এবং ওপি ওয়াইল্ডকার্ডের সাথে যা চেয়েছিল তা আপনি করতে পারবেন না। আপনি করতে পারেন মাত্র একটি ওয়াইল্ড কার্ড না, কার্যকরীভাবে কি ওপি চেয়েছিলেন না।
এডি

17

আপনি এটি "বেনামে" টাইপ পরামিতি (যেমন, ওয়াইল্ডকার্ডগুলি ব্যবহার করে ?) দিয়ে করতে পারবেন না, তবে আপনি এটি "নামযুক্ত" টাইপ পরামিতি দিয়ে করতে পারেন। পদ্ধতি বা শ্রেণি পর্যায়ে কেবল টাইপ প্যারামিটারটি ঘোষণা করুন।

import java.util.List;
interface A{}
interface B{}
public class Test<E extends B & A, T extends List<E>> {
    T t;
}

2
কেন ওয়াইল্ডকার্ডের অনুমতি নেই? অর্থাত্ আমি দেখতে পাচ্ছি না কেন এটি বৈধ হবে না: অ্যারেলিস্ট <? ClassA & ইন্টারফেসবি> তালিকা প্রসারিত; এবং তারপরে আপনি যদি কোনও উপাদানটিকে তালিকা থেকে বাইরে নিয়ে যান, আপনি এটিকে শ্রেণিবদ্ধ টাইপের একটি পরিবর্তনশীল বা ইন্টারফেসবি টাইপের জন্য নির্ধারণ করতে পারেন
চিহ্নিত করুন

একটি ভেরিয়েবলের সাথে ওয়াইল্ডকার্ডকে প্রতিস্থাপন করা একটি দুর্দান্ত কৌশল! তবে এটি সবসময় কাজ করে না। উদাহরণস্বরূপ, জাভা টীকাগুলির মান প্রকারভেদে ভেরিয়েবলের নাম মঞ্জুরি দেয় না, যখন এটি ওয়াইল্ডকার্ডকে মঞ্জুরি দেয়।
sigpwned
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.