آموزش قدم به قدم جاوا – قسمت بیست و چهارم – بخش دوم

متدهای جنریک (Generic Methods)

همانگونه که می‌توانستیم کلاس‌ها را به صورت جنریک تعریف کنیم متدها را نیز می‌توانیم به صورت جنریک بنویسیم. متدهای جنریک می‌توانند نوع داده پارامترهای خود را به عنوان یک پارامتر جنریک دریافت کنند. متدهای جنریک را هم در کلاس‌های جنریک و هم در کلاس‌های غیر جنریک می‌توان تعریف کرد.

مثال:

در این متد جنریک دو پارامتر دریافت می‌شود:

اولی آرایه‌ای از نوع E به نام array

دومی آرایه لیستی (که در قسمت قبل با آن آشنا شدید) از نوع E به نام list

بنابراین نوع داده آرایه و آرایه لیست باید مثل هم باشد.

سپس همانطور که می‌بینید حلقه‌ای نوشته شده که عناصر آرایه array را به list اضافه می‌کند. بین کلمات public و void هم پارامتر جنریک این متد نوشته شده است.

مثالی برای استفاده از این متد:

فرض می‌کنیم متد بالا را در کلاسی به نام Main تعریف کرده‌ایم. آرایه‌ای به نام arr از نوع Integer با سه مقدار داریم. (با کلاس Integer در قسمت قبل آشنا شدید) سپس آرایه لیستی به نام list هم از نوع Integer تعریف کردیم. سپس متد arrayToArrayList را از شی obj فراخوانی کردیم و arr و list را به آن دادیم.

شاید این سوال پیش بیاید که با اینکه مقادیری که Integer نگهداری می‌کند در واقع همان مقادیر از نوع int هستند چرا نوع داده آرایه arr را int تعریف نکردیم؟

نکته اینجاست که بر خلاف کلاس‌های جنریک که نوع پارامتر جنریک آن را هنگام ساختن شی از آن صراحتا اعلام می‌کردیم، در متدهای جنریک نوع پارامتر جنریک را صراحتا مشخص نمی‌کنیم بلکه نوع پارامتر جنریک با توجه به نوع داده پارامترهای متد تعیین می‌شود. پس همانطور که هنگام تعریف شی از کلاس‌های جنریک باید حتما نوع پارامتر جنریک را یکی از Reference Type ها تعریف می‌کردیم، پارامترهای این متد هم باید حتما از نوع یکی از Reference Type ها باشد.

چون پارامترهایی که به این متد داده‌ایم از نوع Integer هستند بنابراین پارامتر جنریک متد هم Integer در نظر گرفته می‌شود.

نکته دیگر اینکه در تعریف متدهای جنریک فقط محدود به تعریف یک پارامتر جنریک نیستیم.

همچنین مانند کلاس‌های جنریک، پارامتر جنریک متدهای جنریک را نیز می‌توان محدودسازی کرد. مثلا arrayToArrayList را می‌توان به این صورت نوشت:

سازنده‌های جنریک (Generic Constructors)

یک سازنده می‌تواند جنریک باشد حتی اگر کلاسی که در آن تعریف شده غیر جنریک باشد.

مثال:

همانطور که می‌بینید کلاس Main فیلدی به نام number از نوع int دارد. کلاس Number که کلاس پدر تمام کلاس‌های wrapper مربوط به اعداد است دارای متدهایی است و بنابراین کلاس‌هایی که از Number ارث‌بری دارند نیز این متدها را دارند. مثلا متد intValue که در این کد از آن استفاده کردیم، مقدار صحیح عددی که در متغیر T ذخیره شده است را بر‌می‌گرداند. حال متد intValue اگر T از نوع اعداد صحیح باشد که همان عدد و اگر از نوع اعداد اعشاری باشد مقدار صحیح آن عدد را برمی‌گرداند.

البته نکته‌ای که باید توجه داشت این است که اگر در یک کلاس غیر جنریک یک سازنده جنریک داشته باشیم آنگاه از پارامتر جنریک آن سازنده فقط در همان سازنده می‌توان استفاده کرد چون آن پارامتر جای دیگری در کلاس تعریف نشده است.

اینترفیس‌های جنریک (Generic Interfaces)

اینترفیس‌ها نیز در جاوا قابلیت جنریک‌شدن دارند.

مثال:

در استفاده از اینترفیس‌های جنریک باید به چند نکته توجه داشت:

1 – کلاس جنریکی که یک اینترفیس جنریک را پیاده‌سازی می‌کند باید حداقل به تعداد پارامترهای جنریک آن اینترفیس پارامتر جنریک داشته باشد و نوع آن نیز باید با نوع پارامتر جنریک اینترفیس برابر باشد. البته کلاس می‌تواند پارامترهای جنریک مختص به خود را نیز داشته باشد.

مثال:

مثلا این کلاس جنریک تنها یک پارامتر جنریک دارد و آن‌ هم همان پارامتر جنریک اینترفیس GenericInterface است. واضح است که هنگام تعریف شی از این کلاس هر نوع داده‌ای که به عنوان T به کلاس داده شود همان نوع هم به عنوان T به اینترفیس GenericInterface داده خواهد شد.

کلاس زیر علاوه بر پارامتر جنریک T که باید داشته باشد یک پارامتر دیگر به نام V نیز دارد:

اما کلاس زیر صحیح نیست چون اینترفیسی که پیاده‌سازی کرده دو پارامتر جنریک دارد اما کلاس فقط یکی از پارامترهای آن را برای خود تعریف کرده است:

چند نکته راجع به جنریک‌ها

1 – از پارامترهای جنریک نمی‌توان شی ساخت. مثلا کد زیر اشتباه است و کامپایل نمی‌شود:

2 – اعضای استاتیک کلاس نمی‌توانند به پارامترهای جنریک کلاس دسترسی پیدا کنند. مثلا کد زیر اشتباه است:

البته می‌توان متدهای جنریک استاتیک تعریف کرد که پارامترهای جنریک مخصوص خود را داشته باشند.

مصطفی نصیری

دانشجوی نرم افزار هستم و علاقه شدیدی به برنامه نویسی مخصوصا با زبان جاوا دارم! در حال حاضر تمرکزم روی اندرویده. دوست دارم چیزایی که یاد میگیرم رو با بقیه به اشتراک بگذارم :)

همچنین ممکن است دوست داشته باشید ...

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *