با عرض سلام و وقت بخیر خدمت کاربران سایت پی وی لرن. و کاربرانی که دوره کامل آموزش برنامه نویسی جاوا را دنبال می کنند. تاکنون شما را با چگونگی تعریف و استفاده از کلاس ها در جاوا آشنا کردیم. و با انواع سطوح دسترسی در جاوا نیز آشنا شدیم. گاهی اوقات شما نیاز پیدا می کنید که کلاس هایی را به صورت تو در تو در داخل کلاس های دیگری تعریف کنید. این کلاس های داخلی که nested class نامیده می شوند، نیز در سطوح دسترسی مختلفی قابل تعریف و دسترسی هستند. برای آشنایی بیشتر با کلاس های داخلی در جاوا و کلاس های تو در تو در جاوا ادامه ی مباحث این آموزش را دنبال کنید.
در ادامه ی این مباحث ما شما را با ساختار و انواع کلاس های داخلی در جاوا آشنا خواهیم کرد.
در جاوا، درست مثل متدها، متغیرهای یک کلاس می توانند یک کلاس دیگر را به عنوان عضو خود داشته باشند.
نوشتن یک کلاس درون دیگر کلاس ها در جاوا مجاز است. کلاس نوشته شده در درون کلاس دیگر nested class نامیده می شود
و کلاسی که دارای کلاس داخلی است، outer class یا کلاس بیرونی نامیده می شود.
برای مثال کد زیر نمونه ای از ایجاد یک کلاس داخلی بوده که Outer_Demo کلاس بیرونی و Inner_Demo کلاس داخلی است:
1 2 3 4 | class Outer_Demo { class Inner_Demo { } } |
کلاس های تودرتو در دو نوع تقسیم می شوند:
این شامل اعضای غیر استاتیکی یک کلاس است.
این شامل اعضای ایستا یک کلاس است.
کلاس های داخلی یک مکانیزم امنیتی در جاوا هستند.
ما می توانیم کلاسی را در سطح دسترسی خصوصی یا… در جاوا تعریف کنیم در حالی که کلاس بیرونی عمومی ، خصوصی یا و… باشد.
طبقات داخلی از سه نوع بسته به نحوه و مکان آنها تعریف می شود. آن ها هستند:
ایجاد یک کلاس درونی بسیار ساده است. شما فقط باید یک کلاس را در داخل یک کلاس دیگر بنویسید.
برخلاف یک کلاس والد، یک کلاس داخلی می تواند خصوصی باشد.
هنگامی که کلاس داخلی را خصوصی اعلام می کنید، نمی توان از یک شیء خارج از کلاس به آن دسترسی پیدا کرد.
در ادامه برنامه ای برای ایجاد یک کلاس داخلی و دسترسی به آن آورده ایم.
کلاس داخلی را خصوصی سازی می کنیم و از طریق یک متد به کلاس دسترسی پیدا می کنیم.
مثال:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | class Outer_Demo { int num; // inner class private class Inner_Demo { public void print() { System.out.println("This is an inner class"); } } // Accessing he inner class from the method within void display_Inner() { Inner_Demo inner = new Inner_Demo(); inner.print(); } } public class My_class { public static void main(String args[]) { // Instantiating the outer class Outer_Demo outer = new Outer_Demo(); // Accessing the display_Inner() method. outer.display_Inner(); } } |
در کد فوق می توانید ببینید که Outer_Demo کلاس بیرونی و Inner_Demo یک کلاس داخلی است.
() display_Inner متدی است که ما در آن کلاسی را اکتیو می کنیم، و این متد از متد اصلی فراخوانی می شود.
اگر برنامه فوق را کامپایل و اجرا کنید، نتیجه زیر را خواهید گرفت:
1 | This is an inner class. |
همانطور که قبلا ذکر شد، کلاس های داخلی نیز برای دسترسی به اعضای خصوصی یک کلاس استفاده می شود.
فرض کنید یک کلاس دارای اعضای خصوصی برای دسترسی به آنها است.
با استفاده از کلاس () getValue می توانیم یک کلاس داخلی بنویسیم.
برای ترسیم کلاس درونی، ابتدا باید کلاس بیرونی را در نظر بگیرید.
پس از آن، با استفاده از شیء کلاس بیرونی،می توانید کلاس داخلی را اکتیو کنید:
1 2 | Outer_Demo outer = new Outer_Demo(); Outer_Demo.Inner_Demo inner = outer.new Inner_Demo(); |
برنامه زیر نشان می دهد که چگونه با استفاده از کلاس داخلی به اعضای خصوصی یک کلاس دسترسی پیدا کنیم.
مثال:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class Outer_Demo { // private variable of the outer class private int num = 175; // inner class public class Inner_Demo { public int getNum() { System.out.println("This is the getnum method of the inner class"); return num; } } } public class My_class2 { public static void main(String args[]) { // Instantiating the outer class Outer_Demo outer = new Outer_Demo(); // Instantiating the inner class Outer_Demo.Inner_Demo inner = outer.new Inner_Demo(); System.out.println(inner.getNum()); } } |
پس از کامپایل و اجرای کد فوق در جاوا، نتیجه ی زیر را مشاهده خواهید کرد:
1 | This is the getnum method of the inner class: 175 |
در جاوا، می توانیم یک کلاس را در یک متد بنویسیم و این یک نوع محلی خواهد بود. همانند متغیرهای محلی، محدوده کلاس داخلی در متد محدود می شود.
یک کلاس داخلی متد می تواند فقط در متد تعریف شده در کلاس تعریف شود.
برنامه زیر نشان می دهد که چگونه از یک کلاس درونی متد محلی استفاده کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class Outerclass { // instance method of the outer class void my_Method() { int num = 23; // method-local inner class class MethodInner_Demo { public void print() { System.out.println("This is method inner class "+num); } } // end of inner class // Accessing the inner class MethodInner_Demo inner = new MethodInner_Demo(); inner.print(); } public static void main(String args[]) { Outerclass outer = new Outerclass(); outer.my_Method(); } } |
نتیجه ی کامپایل و اجرای کد فوق در جاوا بصورت زیر خواهد بود:
1 | This is method inner class 23 |
یک کلاس داخلی بدون نام به عنوان یک کلاس داخلی ناشناس (anonymous inner class) شناخته می شود.
از کلاس های ناشناس هر زمان که به لغو یک متد کلاس یا رابط کاربری نیاز دارید می توانید استفاده کنید.
ساختار تعریف یک کلاس داخلی ناشناس بصورت زیر است:
1 2 3 4 5 6 | AnonymousInner an_inner = new AnonymousInner() { public void my_method() { ........ ........ } }; |
برنامه زیر نشان می دهد چگونه با استفاده از یک کلاس داخلی ناشناس متد کلاس را لغو کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | abstract class AnonymousInner { public abstract void mymethod(); } public class Outer_class { public static void main(String args[]) { AnonymousInner inner = new AnonymousInner() { public void mymethod() { System.out.println("This is an example of anonymous inner class"); } }; inner.mymethod(); } } |
نتیجه ی کامپایل و اجرای کد فوق در جاوا بصورت زیر خواهد بود:
1 | This is an example of anonymous inner class |
شما می توانید کلاس داخلی ناشناس را به متد انتقال دهید. در اینجا ساختار ارسال یک کلاس داخلی ناشناس به عنوان یک متد ارائه شده است:
1 2 3 4 5 6 | obj.my_Method(new My_Class() { public void Do() { ..... ..... } }); |
برنامه زیر نشان می دهد که چگونه یک کلاس داخلی ناشناس را به عنوان یک آرگومان متد انتقال دهید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | // interface interface Message { String greet(); } public class My_class { // method which accepts the object of interface Message public void displayMessage(Message m) { System.out.println(m.greet() + ", This is an example of anonymous inner class as an argument"); } public static void main(String args[]) { // Instantiating the class My_class obj = new My_class(); // Passing an anonymous inner class as an argument obj.displayMessage(new Message() { public String greet() { return "Hello"; } }); } } |
نتیجه ی کامپایل و اجریا کد فوق در جاوا بصورت زیر خواهد بود:
1 | Hello, This is an example of anonymous inner class as an argument |
یک کلاس درونی استاتیک در واقع یک کلاس داخلی تودرتو است که به عنوان یک عضو ثابت از کلاس بیرونی است.
این کلاس می تواند بدون اکتیو کردن کلاس بیرونی، با استفاده از سایر اعضای استاتیک قابل دسترسی باشد.
ساختار کلاس داخلی استاتیک بصورت زیر می باشد:
1 2 3 4 | class MyOuter { static class Nested_Demo { } } |
اکتیو کردن یک کلاس استاتیک ، کمی متفاوت از نمونه سازی یک کلاس درونی است.
برنامه زیر نشان می دهد که چگونه از کلاس کششی استاتیک استفاده کنید:
1 2 3 4 5 6 7 8 9 10 11 12 | public class Outer { static class Nested_Demo { public void my_method() { System.out.println("This is my nested class"); } } public static void main(String args[]) { Outer.Nested_Demo nested = new Outer.Nested_Demo(); nested.my_method(); } } |
نتیجه ی کامپایل و اجرای کد فوق در جاوا بصورت زیر خواهد بود:
1 | This is my nested class |
جاوا به شما اجازه می دهد تا همانند تعریف متغیر ، متد ، حلقه های تکرار و … کلاس ها را نیز بصورت تو در تو و داخلی تعریف نمائید. در هنگام تولید و توسعه یک برنامه با جاوا به احتمال زیاد شما به تعریف کلاس های داخلی نیاز خواهی داشت از این رو ر این بخش به مباحث آشنایی با کلاس های داخلی در جاوا پرداختیم.