CodeGym /وبلاگ جاوا /Random-FA /کلاس های داخلی جاوا
John Squirrels
مرحله
San Francisco

کلاس های داخلی جاوا

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

طبقات تو در تو و درونی

بنابراین تمام کلاس هایی که در داخل کلاس های دیگر قرار دارند، کلاس های تودرتو نامیده می شوند.

class OuterClass {
    ...
    class NestedClass {
        ...
    }
}
کلاس‌های تودرتو که ایستا نیستند، کلاس‌های داخلی و آنهایی که ساکن هستند، کلاس‌های تودرتو استاتیک نامیده می‌شوند . کلاس های داخلی جاوا - 1

class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
    class InnerClass {
        ...
    }
}
بنابراین، همه کلاس‌های داخلی تودرتو هستند، اما همه کلاس‌های تودرتو درونی نیستند. اینها تعاریف اصلی هستند. کلاس های داخلی نوعی مکانیزم امنیتی در جاوا هستند. ما می دانیم که یک کلاس معمولی نمی تواند با یک اصلاح کننده دسترسی خصوصی مرتبط شود. با این حال، اگر کلاس ما عضو کلاس دیگری باشد، کلاس داخلی را می توان خصوصی کرد. از این ویژگی برای دسترسی به اعضای کلاس خصوصی نیز استفاده می شود.

نمونه کلاس داخلی

بنابراین، بیایید سعی کنیم یک کلاس ایجاد کنیم، و در داخل آن - یک کلاس دیگر. نوعی کنسول بازی ماژولار را تصور کنید. خود یک "جعبه" وجود دارد و ماژول های خاصی را می توان به آن متصل کرد. به عنوان مثال، یک کنترلر بازی، یک فرمان، یک کلاه VR، که، به عنوان یک قاعده، بدون خود کنسول کار نمی کند. در اینجا ما کلاس GameConsole را داریم. دارای 2 فیلد و 1 متد - start() . تفاوت GameCosole با کلاسی که به آن عادت کرده ایم این است که یک کلاس GameController داخلی دارد .

public class GameConsole {
    private String model;
    private int weight;

    public void run() {
        System.out.println("Game console is on");
    }


    public class GameController {

        private String color;

        public void start() {
            System.out.println("start button is pressed");
        }

        public void x() {
            System.out.println("x button is pressed");
        }

        public void y() {
            System.out.println("y button is pressed");
        }
        public void a() {
            System.out.println("a button is pressed");
        }

        public void b() {
            System.out.println("b button is pressed");
        }
        public void mover() {
            System.out.println("mover button is pressed");
        }

    }

}
در این مرحله، ممکن است تعجب کنید: چرا این کلاس ها را "جدا" نمی کنیم؟ لازم نیست آنها را تودرتو کنید. در واقع ممکن است. بلکه در مورد طراحی صحیح طبقات از نظر کاربرد آنهاست. کلاس های داخلی برای برجسته کردن موجودیتی در برنامه ایجاد می شوند که به طور جدایی ناپذیری با موجودیت دیگری مرتبط است. یک کنترلر یا مثلاً کلاه VR اجزای کنسول هستند. بله، آنها را می توان جدا از کنسول خریداری کرد، اما بدون آن نمی توان از آنها استفاده کرد. اگر همه این کلاس ها را کلاس های عمومی جداگانه قرار دهیم، برنامه ما می تواند برای مثال کد زیر را داشته باشد:

public class Main {

   public static void main(String[] args) {
       GameController controller = new GameController();
       controller.x();
   }
}
آنچه در این مورد اتفاق می افتد مشخص نیست، زیرا خود کنترلر بدون کنسول کار نمی کند. ما یک شی کنسول بازی ایجاد کرده ایم. ما شیء فرعی آن را ایجاد کردیم - کنترلر بازی. و اکنون می توانیم بازی کنیم، فقط کلیدهای مناسب را فشار دهید. متدهایی که ما نیاز داریم بر روی اشیاء مناسب فراخوانی می شوند. همه چیز ساده و راحت است. در این مثال، استخراج کنترلر بازی، کپسوله سازی را افزایش می دهد (جزئیات قطعات کنسول را در کلاس مربوطه پنهان می کنیم)، و امکان انتزاع دقیق تری را فراهم می کند. اما اگر به عنوان مثال، برنامه ای ایجاد کنیم که فروشگاهی را شبیه سازی کند که در آن بتوانید به طور جداگانه یک کلاه ایمنی یا کنترلر VR خریداری کنید، این مثال با شکست مواجه می شود. در آنجا بهتر است یک کنترلر بازی جداگانه ایجاد کنید. بیایید مثال دیگری بزنیم. در بالا ذکر کردیم که می‌توانیم کلاس داخلی را خصوصی کنیم و همچنان آن را از کلاس بیرونی فراخوانی کنیم. در زیر نمونه ای از این کلاس ها آورده شده است.

class OuterClass {
 
   // inner class
   private class InnerClass {
       public void print() {
           System.out.println("We are in the inner class...");
       }
   }

   // method of outer class. We are create an inner class from the method of outer one
   void display() {
       InnerClass inner = new InnerClass();
       inner.print();
   }
}
در اینجا OuterClass کلاس خارجی است، InnerClass کلاس داخلی است، display() متدی است که در آن یک شی از کلاس داخلی ایجاد می کنیم. حالا بیایید یک کلاس دمو با یک متد main بنویسیم که در آن متد display() را فراخوانی می کنیم .

public class OuterDemoMain {

       public static void main(String args[]) {
           // create an object of the outer class
           OuterDemo outer = new OuterDemo();

           outer.display();
       }
}
اگر این برنامه را اجرا کنید، نتیجه زیر را دریافت خواهید کرد:
ما در کلاس داخلی هستیم ...

طبقه بندی طبقات داخلی

خود کلاس های داخلی یا کلاس های غیر استاتیک تو در تو به سه گروه تقسیم می شوند.
  • کلاس داخلی همانطور که هست همانطور که در بالا با مثال GameConsole و GameController نشان دادیم فقط یک کلاس غیر استاتیک در کلاس دیگر وجود دارد .
  • Method-local Inner class یک کلاس درون یک متد است.
  • کلاس داخلی ناشناس
کلاس های داخلی جاوا - 2

روش کلاس داخلی محلی

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

public class OuterDemo2 {
  
   //instance method of the outer class OuterDemo2
   void myMethod() {
       String str = "and it's a value from OuterDemo2 class' myMethod ";

       // method-local inner class
       class methodInnerDemo {
           public void print() {
               System.out.println("Here we've got a method inner class... " );
               System.out.println(str);

           }
       }
      
       // Access to the inner class
       methodInnerDemo inn = new methodInnerDemo();
       inn.print();
   }
}
حال می‌خواهیم یک کلاس دمو با متد main بنویسیم که در آن متد outer() را فراخوانی می‌کنیم .

public class OuterDemoMain {


   public static void main(String args[]) {
       OuterDemo2 outer = new OuterDemo2();
       outer.myMethod();
   }
}
خروجی این است:
در اینجا ما یک کلاس داخلی متد داریم... و مقداری از کلاس OuterDemo2 myMethod است.

طبقه داخلی ناشناس

یک کلاس داخلی اعلام شده بدون نام کلاس، یک کلاس داخلی ناشناس نامیده می شود. وقتی یک طبقه داخلی ناشناس را اعلام می کنیم، بلافاصله آن را نمونه سازی می کنیم. به طور معمول، هر زمان که شما نیاز به لغو یک کلاس یا متد رابط داشته باشید، از چنین کلاس هایی استفاده می شود.

abstract class OuterDemo3 {
   public abstract void method();

}
   class outerClass {

       public static void main(String args[]) {
           OuterDemo3 inner = new OuterDemo3() {
               public void method() {
                   System.out.println("Here we've got an example of an  anonymous inner class");
               }
           };
           inner.method();
       }
   }
خروجی اینجاست:
در اینجا ما نمونه ای از یک کلاس داخلی ناشناس را داریم...

طبقه داخلی ناشناس به عنوان استدلال

همچنین می توانید یک کلاس داخلی ناشناس را به عنوان آرگومان به متد ارسال کنید. به عنوان مثال.

interface OuterDemo4 {
       String hello();
   }

   class NewClass {
       // accepts the object of interface
       public void displayMessage(OuterDemo4 myMessage) {
           System.out.println(myMessage.hello());
           System.out.println("example of anonymous inner class as an argument");
       }

       public static void main(String args[]) {
           NewClass newClass = new NewClass();

           //here we pass an anonymous inner class as an argument
           newClass.displayMessage(new OuterDemo4() {
               public String hello() {
                   return "Hello!";
               }
           });
       }
}
خروجی اینجاست:
سلام! مثالی از کلاس داخلی ناشناس به عنوان یک آرگومان
برای تقویت آموخته هایتان، پیشنهاد می کنیم یک درس ویدیویی از دوره جاوا ما تماشا کنید
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION