سبد (0)

مفهوم ابهام در overload کردن متدهای جاوا

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

اگر یک اپلیکیشن بنویسیم به طوری که در آن یک متغیر به نام doubleValue  از نوع double و یک متغیر به نام intValue  از نوع int تعریف کرده باشیم(به تصویر 4.14 دقت کنید)، و سپس متد های (simpleMethod(doubleValue و (simpleMethod(intValue را فراخوانی کنیم، برای هر دو مورد، خروجی زیر چاپ می شود: 

Method receives double parameter

و متد به درستی مورد فراخوانی قرار می گیرد، زیرا وقتی که این متد را با استفاده از یک آرگومان از نوع integer(عدد صحیح) فراخوانی کنیم، این عدد صحیح به یک عدد از نوع double تبدیل(متحد سازی) می شود. خروجی عکس 4.14 در تصویر 4.15 نشان داده شده است: 

 

 

 نکته: توجه کنید که اگر متد (void simpleMethod(double d وجود نداشت و به جای آن متد (void simpleMethod(int i وجود داشت، آنگاه اگر دستور (simpleMethod(doubleValue را اجرا می کردیم، با شکست مواجه می شدیم. زیرا با اینکه یک مقدار از نوع int می تواند به یک مقدار از نوع double تبدیل(متحد سازی) شود، اما یک مقدار از نوع double نمی تواند به یک int تبدیل شود. 

 

وقتی که به درستی یک متد را overload کنید، می توانید با دادن آرگومان های متفاوت، آن را فراخوانی کنید، و خواهید دید که نسخه ی مناسب این متد اجرا می شود. 

به کدهای تصویر 4.14 توجه کنید. فرض کنید بخواهیم به این کدها، یک متد overload دیگر، یعنی یک ()simpleMethod اضافه کنیم که یک پارامتر integer را بپذیرد(به عکس 4.16 توجه کنید) ، حالا اگر دستور (simpleMethod(intValue را فراخوانی کنیم، خروجی ما تغییر خواهد کرد. پس به جای اینکه بخواهیم آرگومان از نوع integer را به نوع double تبدیل(متحد سازی) کنیم، یک چنین متدی می نویسیم، و هنگامی که یک آرگومان integer به این متد بدهیم و آن را فراخوانی کنیم، کامپایلر این متد را تشخیص می دهد و از آن استفاده می کند. تصویر 4.17 خروجی را نشان می دهد:

  

 (تصویر 4.16)

(تصویر 4.17)

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

متدها:

public static void calculateInterest(int bal, double rate)
public static void calculateInterest(double bal, int rate)

 حالا اگر متد ()calculateInterest را به همراه یک آرگومان از نوع int و یک آرگوامان از نوع double فراخوانی کنیم، اولین نسخه از متدهای بالا اجرا می شود. و اگر متد ()calculateInterest را به همراه یک آرگومان از نوع double و یک آرگومان از نوع int فراخوانی کنیم، دومین نسخه از متدهای بالا اجرا خواهد شد. 

در هر یک از این فراخوانی ها، کامپایلر قادر است تا بر اساس آرگومان های داده شده، متد مناسب را انتخاب کند. اما اگر متد ()calculateInterest را با استفاده از دو آرگومان از نوع int مثل(calculateInterest(300, 6 فراخوانی کنیم، برای کامپایلر یک ابهام ایجاد می شود، زیرا هیچ متدی با این فراخوانی تطابق ندارد. 

 به دلیل اینکه این دو عدد integer در متد اول می توانند به یک عدد integer و یک عدد double تبدیل شوند، بنابراین با این متد تطابق دارند، و همچنین به دلیل اینکه این دو عدد integer در متد دوم، می توانند به یک عدد double و یک عدد integer تبدیل شوند، بنابراین با متد دوم نیز تطابق دارند. بنابراین کامپایلر نمی تواند تشخیص دهد که کدام نسخه از متد ()calculateInterest را مورد استفاده قرار دهد و برنامه ی ما کامپایل نخواهد شد. 

 


متدهایی که نام و آرگومان های یکسانی دارند اما نوعِ برگشتی آنها متفاوت است، overload محسوب نمی شوند و غیرقانونی هستند. بعنوان مثال، اگر متدهای زیر در یک کلاس قرار گیرند، غیرقانونی محسوب می شوند: 

متدها:

int aMethod(int x)
void aMethod(int x)

 

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