برای آزمون جاوا کاپ چه چیزهایی آموختم – قسمت سوم


ویژگیهای جاوا - علیرضا پیر

ایمپورت پکیج ها و کلاس های دیگر به کلاس مورد نظر

 

برای استفاده از کلاس های موجود در پیکیج های دیگر، نیاز است تا آنها را به کلاس خودمان ایمپورت کنیم، برای اینکار، نام کامل آن پکیج را با کلیدواژه import به بالای کلاس اضافه می کنیم.

توجه کنید که اولین خطِ موجود در کلاس، باید نشان دهنده ی پکیجِ کلاس باشد و نمی توانید قبل از آن هیچ دستور دیگری (حتی دستورات import) را قرار دهید.

مثلا اگر دو پکیج با نام های ir.amulay.package1 و ir.amulay.package2 داشته باشیم، بری استفاده از کلاس های موجود در پکیج دوم در یکی از کلاس های پیک اول باید بنویسیم:

 

آن ستاره، به معنیِ این است که هرچه که در پکیجِ 1 هست، به این کلاس اضافه کن، اگر بخواهیم صرفا یک کلاسِ خاص از آن پکیج به این کلاس اضافه شود، می نویسیم:

 

ایمپورت توابع و متغیرهای استاتیک

برای استفاده از کلاس ها و متغیر های استاتیکِ یک کلاس در کلاس های دیگر، یک راه این است که ابتدا نامِ کلاس را آورده و سپس نام متغیر یا تابع استاتیک را می آوریم:

 

اما می توانیم نیاز به آوردنِ پیشوند را برطرف کنیم، این کار را با ایمپورت استاتیک انجام دهیم:

final

متغیر final

متغیرهای final حتما باید “فقط یک بار” مقدار دهی شوند، حالا این مقداردهی یا به صورت inline و یا در سازنده ها انجام می گیرد.

توجه کنید که متغیر استاتیک، با مفهوم متغیر final متفاوت است، متغیر استاتیک، مربوط به کلاس (و نه شیء است) و مقدارِ آن قابلِ تغییر است. متغیر می تواند همزمان static و final باشد. و در مجموع توجه کنید این مفاهیم مستقل از یکدیگر هستند:

  • سطح دسترسی
  • استاتیک بودن
  • final بودن

 

تابع final

توابع final در کلاس های فرزند قابل بازنویسی (override) نیستند.

کلاس های final

کلاس های final قابل extend شدن نیستند. (توجه کنید که کلاس های abstract قابل extend شدن هستند ولی نمی توان از آنها شیء ای ساخت)

 

مفهوم final، به معنیِ هویت ثابت است، و نمیتواند به اشیاء دیگر اشاره کند. اما مفهومِ دیگری نیز داریم به نام immutable که با مفهوم فاینال متفاوت است. (کلاس String نمونه ای از این مفهوم است که برای آشنایی بیشتر پیشنهاد می کنم مطالعه کنید در مورد آن)

 

فراخوانی تابع سازنده پدر

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

توجه کنید که نمیتوانیم به تابع سازنده کلاسِ پدر، متغیری از کلاسِ فرزند را پاس کنیم، یعنی این دستور در تابع سازنده معتبر نیست:

دلیلِ این امر، این است که ساخت اشیاء از بالاترین سطحِ خود آغاز می شود، یعنی برای یک کلاس، ابتدا اجداد ریشه ساخته می شوند تا نوبت به خودِ کلاس برسد. بنابراین در دستورِ بالا، فیلد های مربوط به کلاس فرزند هنوز ساخته نشده اند که بخواهند به پدر ارسال شوند.

 

UpCasting و DownCasting

upcasting به معنیِ cast کردن (سعی کنید cast  را به فارسی ترجمه نکنید! چون هیچ ترجمه ای مفهومِ آن را نمی رساند، فقط سعی کنید بفهمیدش!) یک کلاس به یکی از کلاس های پدرش است. به کدِ زیر توجه کنید:

اینکار همواره معتبر است. در واقع هر فرزندی، حتما از نوعِ پدر هم می تواند در نظر گرفته شود.

 

برعکسِ اینکار، یعنی downcasting، گاهی معتبر (به شرطی که صراحتا این cast انجام بگیرد) و گاهی نا معتبر است و کامپایلر جلوی آن را می گیرد. مثلا با فرض اینکه Package1Class2 فرزند Package1Class1 است، کد زیر معتبر خواهد بود:

 

اما کدِ زیر در زمانِ اجرا دچارِ خطا می شود:

 

 

قسمت بعد


یک دیدگاه بگذارید