آموزش متدهای generic در جاوا

آموزش متدهای generic در جاوا
تاریخ بروزرسانی : 08 مرداد 1399 | تعداد بازدید : 4590 | زمان خواندن مقاله : 5 دقیقه
جاوا،

در دوره ای از زمان برنامه نویس ها مجبور بودند برای استفاده از انواع مختلف داده ها در یک متد مشخص، آن متد را overloading کنند. یا برای استفاده از انواع مختلف داده در یک کلاس، باید کلاس های جدا با اسامی مختلف پیاده سازی می کردند که موجب زیاد شدن حجم کد می شد و یافتن باگ ها در برنامه مشکل بود. با پیچیده تر شدن کدها امکان بروز خطای تبدیل انواع داده به یکدیگر در زمان اجرا افزایش یافت. برنامه نویسان آرزو داشتند، کاش کلاس یا متدی بود که انواع مختلف داده ها را پشتیبانی کند و با یکبار پیاده سازی بتوانند از اعداد، رشته ها و یا هر نوع داده ای در آن به کار ببرند. چون با این کار هم حجم کد کم می شد و هم خوانایی برنامه بهتر میشد. در سال 2004 این آرزو با اضافه شدن جنریک ها برآورده شد.

به همین خاطر ما هم یک آموزش متد های generic در جاوا برای شما تدارک دیده ایم. ما را همراهی کنید.


تعریف جنریک:

جنریک ها راهی هستند برای تعریف کلاس یا متدهایی که با یک بار پیاده سازی، می توانند برای انواع داده ها استفاده شوند.


آموزش متدهای generic در جاوا:

همه ی متدهای جنریک یک نوع داده دارند که هنگام تعریف به جای استفاده از انواع داده از یک پارامتر نوع (که نوع داده ی متد به عنوان ورودی است) در بین دو کاراکتر<> استفاده می شود پس بدنه ی یک متد generic مانند بقیه متدهاست با این تفاوت که به جای استفاده از نوع داده از پارامتر نوع استفاده می کنیم.

آموزش جاوا

به مثال زیر توجه کنید:

ما در این مثال مشخص می کنیم که چگونه می توان یک آرایه از داده های مختلف را در خروجی چاپ کرد.

public class GenericMethodTest
{
// generic method printArray 
public static < E > void printArray( E[] inputArray )
{
 // Display array elements 
for ( E element: inputArray ){
System.out.printf( "%s ", element );
}
 System.out.println();
}
public static void main( String args[] )
{
// Create arrays of Integer, Double and Character
Integer[] intArray = { 1, 2, 3, 4, 5 };
 Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
System.out.println( "Array integerArray contains:" );
printArray( intArray); // pass an Integer array
System.out.println( "\nArray doubleArray contains:" );
printArray( doubleArray ); // pass a Double array
System.out.println( "\nArray characterArray contains:" );
printArray( charArray ); // pass a Character array
}
}

 

خروجی برنامه بالا به شکل زیر خواهد بود:

Array integerArray contains:
1 2 3 4 5 6

Array doubleArray contains:
1.1 2.2 3.3 4.4 

Array characterArray contains:
H E L L O

 

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


آموزش کلاس های generic در جاوا:

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


مثال:

یک کلاس به نام Stack ایجاد کرده ایم که برای انواع داده ها قابل استفاده است:

public class MyStack<T> {
2. private T[] item;
...
3. public void push(T input) {
4. item[++top] = input;
5. }
6. public T pop() {
7. return item[top--];
8. }
...
9. } // end of MyStack Class


دقت کنید، متدهایی که در بدنه یک کلاس جنریک نوشته می شوند دیگر نیازی به معرفی به عنوان متدهای مستقل جنریک ندارند و برنامه نویس به راحتی می تواند از پارامترنوع دار به عنوان ورودی برای متد pop و نوع بازگشتی برای تابع pushاز حرف T استفاده کند. توجه کنید که T یک نام دلخواه است و دلیل استفاده مکرر از این حرف به عنوان نام پارامتر نوع دار این است که حرف اول کلمه ی Type می باشد. مثال بالا به عنوان پشته برای تمام انواع داده ها قابل استفاده خواهدبود.

 

بیشتر بخوانید: آیا با مفاهیم تزریق وابستگی در جاوا آشنا هستید؟surprise


آیا می شود پارامترهای نوع را محدود کرد؟

در پاسخ به این سوال باید بگوییم بله، تا در اجرای متدها و کدهایمان در بعضی از مواقع به مشکل برنخوریم. به این صورت که پارامتر نوع در حین فراخوانی اگر نوع داده، شروط مورد نظر را نداشت اجازه اجرا به برنامه را ندهد. برای این کار بعد از تعیین نام پارامتر نوع، از کلمه ی extends استفاده کرده و پس از آن نام کلاس قرار می گیرد.


مثال:

می خواهیم بین 3 شی بزرگترین آنها را برگردانیم:

public class MaximumTest
{
// determines the largest of three Comparable objects
public static <T extends Comparable<T>> T maximum(T x, T y, T z)
{ 
T max = x; // assume x is initially the largest 
if ( y.compareTo( max ) > 0 ){
max = y; // y is the largest so far
}
if ( z.compareTo( max ) > 0 ){
max = z; // z is the largest now
}
return max; // returns the largest object 
}
public static void main( String args[] )
{
System.out.printf( "Max of %d, %d and %d is %d\n\n", 
3, 4, 5, maximum( 3, 4, 5 ) );
System.out.printf( "Maxm of %.1f,%.1f and %.1f is %.1f\n\n",
6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ) );
System.out.printf( "Max of %s, %s and %s is %s\n","pear",
"apple", "orange", maximum( "pear", "apple", "orange" ) );
 }
}

خروجی برنامه بالا به شکل زیر خواهد بود:

maximum of 3, 4 and 5 is 5

maximum of 6.6, 8.8 and 7.7 is 8.8

maximum of pear, apple and orange is pear

 

مزایای genericها:

یکی از مزایای آنها استفاده مجدد از کد است. یعنی اگر متد یا کلاسی را نوشتیم، از آن بتوان در انواع مختلف داده استفاده کرد. از دیگر مزیت جنریک ایمنی انواع داده در زمان کامپایل یا Type-Safety است. به این معنی که انواع داده در متدها و کلاس های جنریک در زمان کامپایل شناسایی شوند. این امر باعث می شود برنامه نویسان در زمان اجرای برنامه با خطاهای Cast مواجه نشوند.
 


کلمات کلیدی :
جاوا