کلاس های تو در تو در جاوا

کلاس های تو در تو در جاوا

تعریف کلاس های تو در تو (nested class)

اگه یک کلاس رو داخل کلاس دیگه تعریف کنیم بهش کلاس داخلی (inner class) یا کلاس تو در تو (nested class) میگیم.

میتونیم یک کلاس رو به صورت عضو (member) یا static داخل یک کلاس دیگه تعریف کنیم.

در جاوا سطح دسترسی کلاس های داخلی میتونه ‎private, default, protected, public باشه.

کلاس های داخلی کاربرد های متعددی دارند مثلا در MVC میتونن نقش یک کنترلر رو بازی کنن، یا میتونیم یک Iterator باهاشون پیاده‌سازی کنیم و یا در طراحی الگو هایی مثل builder نقش Factory رو بازی کنن.

کلاس های داخلی به صورت Outer$Inner.class کامپایل میشن (در اینجا Outer اسم کلاس بیرونی و Inner اسم کلاس داخلی است).

کلاس داخلی غیر استاتیک

به کلاس های غیر استاتیک که داخل یک کلاس تعریف میکنیم کلاس داخلی عضو (member) میگیم.

این کلاس ها به تمام اعضای کلاس بیرونی دسترسی دارند. بنابراین نیاز نداریم برای دسترسی به اعضای کلاس بیرونی یک نمونه از کلاس بیرونی داخل کلاس داخلی ایجاد کنیم.

فرم کلی:

public class MyOuterClass{ ... public class MyInnerClass{ ... } }

قبل از ایجاد یک نمونه از کلاس داخلی عضو نیاز به یک نمونه از کلاس بیرونی داریم.

public static void main(String[] args){ MyOuterClass outer = new MyOuterClass(); //A new instance of inner class by an object of outer class. MyInnerClass inner = outer.new MyInnerClass(); }

میتونیم اعضای کلاس بیرونی رو در کلاس داخلی صدا بزنیم.

public class MyOuterClass{ private String outerField = "This is an outer data field"; public class MyInnerClass{ public void displayOuterDataField(){ System.out.println(outerField); } } }
public static void main(String[] args){ MyOuterClass outer = new MyOuterClass(); MyInnerClass inner = outer.new MyInnerClass(); inner.displayOuterDataField(); }

مثال

public class StringArray { private String[] elements; public StringArray(String[] elements){ this.elements = elements; } public int size(){ return elements.length; } public Iterator getIterator(){ return new Iterator(); } public class Iterator{ private int currentIndex; public boolean hasNext(){ return currentIndex < elements.length; } public String next(){ return elements[currentIndex++]; } public void reset(){ currentIndex = 0; } } }
public static void main(String[] args){ String[] names = {"Billie", "Jessy", "Jill", "Lura"}; StringArray arr = new StringArray(names); System.out.println("There are " + arr.size() + " elements that array holds"); System.out.println("Here are contents of the array: "); StringArray.Iterator iterator = arr.getIterator(); while (iterator.hasNext()) System.out.print(iterator.next() + " "); }

کلاس داخلی استاتیک

این کلاس ها رو با کلیدواژه ی استاتیک داخل یک کلاس دیگه تعریف میکنیم.

فرم کلی:

public class MyOuterClass{ ... public static class MyInnerClass{ ... } }

این کلاس ها فقط به اعضای استاتیک کلاس بیرونی دسترسی دارن.

public class MyOuterClass{ private static void printMessage(){ System.out.println("A message from static method of outer class"); } public static class MyInnerClass{ public MyInnerClass(){ System.out.println("An object created from Inner class."); printMessage(); } } }

برای ایجاد یک نمونه از کلاس استاتیک داخلی نیاز به نام کلاس بیرونی داریم:

MyOuterClass.MyInnerClass myInnerObject = new MyOuterClass.MyInnerClass();

در زیر الگوی builder رو با کلاس استاتیک Factory برای کلاس TV پیاده‌سازی کردیم.

public class TV { public static final int MAXIMUM_VOLUME_LEVEL = 10; public static final int MINIMUM_VOLUME_LEVEL = 0; public static final int MAXIMUM_CHANNEL_NUMBER = 120; public static final int MINIMUM_CHANNEL_NUMBER = 1; private String panel; private int channel = 1; private int volume = 1; private boolean on; private TV(Factory factory){ this.panel = factory.panel; } public void turnOn(){ on = true; } public void turnOff(){ on = false; } public void setChannel(int channel) { if (channel >= MINIMUM_CHANNEL_NUMBER && channel <= MAXIMUM_CHANNEL_NUMBER) this.channel = channel; } public void setVolume(int volume) { if (on && volume >= MINIMUM_VOLUME_LEVEL && volume <= MAXIMUM_VOLUME_LEVEL) this.volume = volume; } public String getPanel() { return panel; } public int getChannel() { return channel; } public int getVolume() { return volume; } public void channelUp(){ if (on && channel < MAXIMUM_CHANNEL_NUMBER) channel++; } public void channelDown(){ if (on && channel > MINIMUM_CHANNEL_NUMBER ) channel --; } public void volumeUp(){ if (on && volume < MAXIMUM_VOLUME_LEVEL) volume++; } public void volumeDown(){ if (on && volume > MINIMUM_VOLUME_LEVEL) volume --; } public boolean isOn() { return on; } public boolean isMuted(){ return volume == MINIMUM_VOLUME_LEVEL; } public static class Factory{ private String panel = "FLATIRON"; public Factory panel(String panel){ this.panel = panel; return this; } public TV build(){ return new TV(this); } } }

ساخت نمونه و استفاده از TV.

public static void main(String[] args) { TV tv1 = TV.Factory().panel("TFT").build(); tv1.turnOn(); tv1.setChannel(42); tv1.setVolume(6); TV tv2 = TV.Factory().panel("IPS").build(); tv2.turnOn(); tv2.channelUp(); tv2.channelUp(); tv2.volumeUp(); System.out.println("tv1 has been built by " + tv1.getPanel() + " panel"); System.out.println("tv1's channel is " + tv1.channel + " and volume level is " + tv1.volumeLevel); System.out.println("tv2 has been built by " + tv2.getPanel() + " panel"); System.out.println("tv2's channel is " + tv2.channel + " and volume level is " + tv2.volumeLevel); }

خلاصه

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

- در جاوا میتونیم کلاس های تو در تو رو به صورت استاتیک یا غیر استاتیک تعریف کنیم.

- کلاس های داخلی غیر استاتیک (ممبر) به تمام اعضای کلاس بیرونی دسترسی دارند.

برای ایجاد یک نمونه از کلاس های داخلی غیر استاتیک باید ابتدا یک نمونه از کلاس بیرونی ایجاد کنیم.

کلاس های تو در تو استاتیک تنها به اعضای استاتیک کلاس بیرونی دسترسی دارند.

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

arrow_drop_up
کپی شد!