دوره‌ها / JAVA / کلاس‌های داخلی (Java Inner Classes)

کلاس‌های داخلی (Java Inner Classes)

15 دقیقه Article

کلاس‌های داخلی (Inner Classes): طبقه‌بندی تو در تو 🪆📦

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

۱. چرا کلاس داخلی؟

  • گروه‌بندی منطقی: اگر یک کلاس فقط و فقط برای استفاده در یک کلاس دیگر باشد، آن را داخلِ آن می‌گذاریم.
  • کپسوله‌سازی بیشتر: کلاس داخلی می‌تواند به تمام متغیرهای کلاسِ بیرونی (حتی private) دسترسی داشته باشد.
  • خوانایی کد: کدهای مرتبط در یک جا جمع می‌شوند.

۲. نحوه دسترسی

برای ساخت شیء از کلاس داخلی، ابتدا باید شیئی از کلاس بیرونی داشته باشید:

{code_block('OuterClass myOuter = new OuterClass();\nOuterClass.InnerClass myInner = myOuter.new InnerClass();')}

۳. کلاس‌های داخلی استاتیک (Static Inner Classes)

برخلاف کلاس‌های داخلی معمولی، کلاس‌های استاتیک نیازی به شیءِ کلاسِ بیرونی ندارند (اما به متغیرهای غیر استاتیکِ کلاس بیرونی هم دسترسی ندارند):

{code_block('OuterClass.StaticInnerClass myStaticInner = new OuterClass.StaticInnerClass();')}

مثال کامل:

{code_block('class Outer {\n int x = 10;\n class Inner {\n int y = 5;\n }\n}')}
کلاس‌های محلی: شما حتی می‌توانید داخل یک "متد" هم کلاس تعریف کنید! به این‌ها Local Classes می‌گویند.
نکته فنی: کلاس‌های داخلی ابزار اصلی برای پیاده‌سازی Event Handling در برنامه‌های دسکتاپ (Java Swing/JavaFX) هستند.
<hr style="margin: 50px 0; border: 0; border-top: 1px dashed rgba(255,255,255,0.1);">

بخش تخصصی: معماری سیستم‌های شیءگرا 🏗️💎

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

۱. کد تمیز و اصل ابزارمندی (Abstraction)

در پروژه‌های بزرگ صنعتی، ما سعی می‌کنیم تا حد امکان وابستگی‌ها (Dependencies) را کاهش دهیم. استفاده درست از Interface و Abstract Class باعث می‌شود کدهای ما انعطاف‌پذیر باشند. به قولی: "برنامه‌نویسی برای اینترفیس، نه برای پیاده‌سازی".

۲. مدیریت پکیج‌ها و جلوگیری از تداخل

پکیج‌بندی حرفه‌ای فقط برای نظم نیست؛ بلکه برای کنترلِ Visibility است. با استفاده درست از سطوح دسترسی (مثل protected و default) در سطح پکیج، می‌توانید از دسترسی‌های غیرمجاز به متدهای داخلی کلاس‌ها جلوگیری کنید.

۳. ترکیب به جای وراثت (Composition over Inheritance)

وراثت (Inheritance) ابزار قدرتمندی است، اما استفاده بیش از حد از آن باعث ایجاد "زنجیره‌های سفت‌وسخت" (Tight Coupling) می‌شود. در بسیاری از موارد، استفاده از ترکیب (داشتنِ یک شیء داخل شیء دیگر) راه‌حل منعطف‌تری برای گسترشِ کدهای شماست.

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

نکته تکمیلی: دسترسی به فیلدهای کلاسِ بیرونی 🔍

یکی از قابلیت‌های شگفت‌انگیز کلاس‌های داخلی در جاوا این است که آن‌ها به تمام متغیرهای کلاس بیرونی، حتی اگر private باشند، دسترسی مستقیم دارند. این به این دلیل است که شیءِ کلاس داخلی "در دلِ" شیءِ کلاس بیرونی زندگی می‌کند. این قابلیت باعث می‌شود کلاس‌های داخلی برای ساختنِ ابزارهایی مثل "Iterator"ها یا "Handler"ها که نیاز به دسترسیِ امن به داده‌های داخلی کلاس اصلی دارند، بی‌رقیب باشند.

تمرین‌های عملی

برای تثبیت یادگیری این درس تمرین‌های زیر را حل کنید

دسترسی به کلاس داخلی Medium
سوال تمرین

ساختار کلاس تو در تو آماده است. در متد main، یک شیء از Inner (که داخل Outer است) بسازید و متغیر y آن را چاپ کنید.

پاسخ تمرین
JAVA
class Outer {
  class Inner {
    int y = 7;
  }
}

public class Main {
  public static void main(String[] args) {
    Outer out = new Outer();
    Outer.Inner in = out.new Inner();
    System.out.println(in.y);
  }
}

آماده رفتن به درس بعدی هستید؟

این درس را به پایان رساندید و می‌توانید به درس بعدی بروید.