جلسه شماره 19رایگان

OOP in Java Third Section | شی گرایی در جاوا قسمت سوم

01:59:02

توضیحات جلسه

🎥 این ویدیو قسمت نوزدهم از بوت‌کمپ رایگان جاواست. 🧩 آموزش شی‌گرایی در جاوا – قسمت سوم 📝 در این قسمت، مسیر یادگیری شی‌گرایی را با مفاهیم بسیار مهم‌تری ادامه می‌دهیم؛ مفاهیمی که پایه‌گذار طراحی حرفه‌ای نرم‌افزار هستند. 🔒 از کپسوله‌سازی (Encapsulation) شروع می‌کنیم و تفاوت نوع‌های داده‌ی primitive و reference رو بررسی می‌کنیم. 🔧 سپس با کلاس‌های کمکی مثل Wrapper Class آشنا می‌شیم و وارد مباحث تبدیل نوع (Casting)، عملگر instanceof، و در نهایت یکی از مهم‌ترین ویژگی‌های OOP یعنی چندریختی (Polymorphism) می‌شیم. ✅ در ادامه با حل تمرین‌های واقعی، این مفاهیم رو کاملاً در عمل یاد می‌گیریم. این تمرین‌ها به‌گونه‌ای طراحی شدن که دید عمیق‌تری به طراحی و ساختار شی‌گرا بهت بدن. 💻 سورس‌کد این جلسه در گیت‌هاب: 🔗 github.com/farzadafi/ProgrammingByFarzadAfi/tree/master/src/k_oop 👥 گروه پرسش و پاسخ تلگرام: @programmingByFarzadAfi 💬 گروه پرسش و پاسخ بله: @programming_by_farzadafi ❓ هر سوالی داشتی، می‌تونی توی گروه بپرسی؛ من یا مربی‌های گروه راهنماییت می‌کنیم 🎓 بوت‌کمپ رایگان جاوا – آموزش تمرین‌محور برای یادگیری عمیق و ورود به بازار کار.

جزوه و مستندات

مفاهیم کلیدی

  • Encapsulation (کپسوله‌سازی)

کپسوله‌سازی (Encapsulation) به معنای پنهان‌کردن داده‌های حساس یک کلاس از دسترسی مستقیم بیرونی است. این کار با تعریف فیلدها به‌صورت private و فراهم‌کردن متدهای عمومی (public) مانند Getter و Setter برای مدیریت و اعتبارسنجی داده‌ها انجام می‌شود.

  • Primitive Types

نوع‌های داده‌ای پایه (Primitive Types) در جاوا، مانند int، double و boolean، مقادیر را مستقیماً ذخیره می‌کنند و معمولاً عملکرد بالایی دارند.

  • Reference Types

نوع‌های ارجاعی (Reference Types) شامل کلاس‌ها، اینترفیس‌ها و آرایه‌ها هستند. این نوع‌ها به‌جای نگهداری مستقیم مقدار شیء، مرجع یا آدرس شیء ساخته‌شده در حافظه Heap را نگه می‌دارند.

تمام نوع‌های ارجاعی از کلاس Object ارث‌بری می‌کنند.

  • Wrapper Class

کلاس‌های پوششی (Wrapper Classes) نوع‌های داده‌ای پایه را درون یک شیء (Object) کپسوله می‌کنند؛ برای مثال، کلاس Integer نوع int را پوشش می‌دهد.

این کلاس‌ها برای استفاده در Generics و Collections ضروری هستند.

  • Autoboxing & Unboxing

Autoboxing به تبدیل خودکار نوع داده پایه به Wrapper Class متناظر آن گفته می‌شود.

Unboxing نیز تبدیل خودکار Wrapper Class به نوع داده پایه است. این قابلیت‌ها از جاوا نسخه 5 اضافه شده‌اند.

  • Type Casting

Type Casting به تبدیل یک نوع داده به نوعی دیگر گفته می‌شود.

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

در اشیا نیز تبدیل نوع به شکل Upcasting و Downcasting انجام می‌شود.

  • Upcasting

Upcasting تبدیل یک شیء از کلاس فرزند به کلاس والد است. این تبدیل به‌صورت خودکار (Implicit) انجام می‌شود و دسترسی به متدهای اختصاصی کلاس فرزند را محدود می‌کند.

  • Downcasting

Downcasting تبدیل یک ارجاع از نوع کلاس والد به نوع کلاس فرزند است. این تبدیل باید به‌صورت صریح (Explicit) انجام شود و ممکن است در زمان اجرا باعث خطا شود.

  • instanceof

عملگر instanceof بررسی می‌کند که آیا یک شیء در زمان اجرا (Runtime) نمونه‌ای از یک کلاس مشخص است یا خیر.

کاربرد اصلی آن جلوگیری از خطای ClassCastException پیش از انجام Downcasting است.

  • Polymorphism (چندریختی)

چندریختی (Polymorphism) توانایی انجام یک کار به روش‌های مختلف است.

این مفهوم شامل دو نوع است: Static Polymorphism که در زمان کامپایل و با Method Overloading انجام می‌شود، و Dynamic Polymorphism که در زمان اجرا و با Method Overriding انجام می‌شود.

نکات مهم مصاحبه‌ای

  • تفاوت اصلی Primitive Types و Reference Types چیست؟

نوع‌های داده پایه (Primitive Types) مقدار را مستقیماً نگه می‌دارند، مقدار پیش‌فرض دارند و نمی‌توانند مقدار null بپذیرند.

نوع‌های ارجاعی (Reference Types) مرجع شیء را نگه می‌دارند، اشیای آن‌ها در حافظه Heap ساخته می‌شوند و می‌توانند مقدار null داشته باشند.

  • چرا به Wrapper Classes نیاز داریم؟

ساختارهای داده‌ای جاوا، مانند ArrayList، و مفاهیمی مانند Generics فقط با اشیا (Objects) کار می‌کنند و نمی‌توانند نوع‌های داده پایه را مستقیماً بپذیرند.

  • تفاوت Static Polymorphism و Dynamic Polymorphism چیست؟

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

Dynamic Polymorphism با Method Overriding و ارث‌بری انجام می‌شود و JVM رفتار متد را در زمان اجرا تعیین می‌کند.

  • چگونه از خطای ClassCastException جلوگیری کنیم؟

پیش از انجام Downcasting، باید با استفاده از عملگر instanceof بررسی کنیم که شیء موردنظر واقعاً از نوع کلاس مقصد است یا خیر.

  • مزیت اصلی Encapsulation چیست؟

Encapsulation یک نقطه کنترل برای اعتبارسنجی (Validation) داده‌های ورودی ایجاد می‌کند.

برای مثال، می‌توان در متد Setter بررسی کرد که سن واردشده منفی نباشد.

مثال یا سناریوی کاربردی

سناریوی Encapsulation:

فرض کنید کلاسی با نام Student دارید. اگر فیلد age به‌صورت public باشد، ممکن است مقدار منفی، مانند -10، به آن اختصاص داده شود.

با استفاده از Encapsulation، فیلد را private می‌کنیم و در متد setAge شرط اعتبارسنجی قرار می‌دهیم:

public void setAge(int age) {
    if (age > 0 && age < 100) {
        this.age = age;
    } else {
        this.age = 0; // مقدار پیش‌فرض در صورت ورودی نامعتبر
    }
}

سناریوی Polymorphism و Casting:

فرض کنید یک کلاس والد با نام Animal و دو کلاس فرزند با نام‌های Dog و Cat داریم. هر دو کلاس فرزند، متد makeSound را Override کرده‌اند:

Animal myDog = new Dog(); // Upcasting خودکار
myDog.makeSound(); // خروجی: صدای سگ؛ Dynamic Polymorphism

if (myDog instanceof Dog) {
    Dog realDog = (Dog) myDog; // Downcasting صریح
    realDog.wagTail(); // دسترسی به متد اختصاصی سگ
}

بیشتر بدانید

  • نکته در مورد حروف بزرگ و کوچک:

در جاوا، تمام نوع‌های داده پایه با حرف کوچک شروع می‌شوند؛ مانند int.

همچنین، نوع‌های ارجاعی یا نام کلاس‌ها طبق قرارداد با حرف بزرگ شروع می‌شوند؛ مانند String و Integer.

  • پسوند اعداد:

برای تعریف مقادیر اعشاری، از پسوند f برای نوع float و از پسوند d برای نوع double استفاده کنید؛ برای مثال، 10.5f.

  • حذف متدها در Upcasting:

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