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

کلید واژه ی static در جاوا

تعریف استاتیک

از کلید واژه static در جاوا میشه برای تعریف فیلد، متد و کلاس های داخلی (Inner class) استاتیک استفاده کرد.

هنگامی که از کلید واژه ی static در جاوا برای یک عضو از کلاس استفاده بشه عضو مورد نظر وابسته به کلاس میشه و ربطی به نمونه (آبجکت) های ایجاد شده از کلاس نداره و در طی زمان اجرای برنامه بدون نیاز به نمونه سازی در دسترسه.

مقدار عضو استاتیک یک کلاس در جاوا، بین تمام آبجکت های ایجاد شده از کلاس مشترک است. و متغیر تا پایان زمان اجرای برنامه وجود دارد.

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

نکته:

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

فیلد های استاتیک

این متغیر ها وابسته به کلاس هستند و مقدار آنها تا پایان زمان اجرای برنامه میتونه بین تمام آبجکت های ایجاد شده از کلاس به اشتراک گذاشته بشه

زمانی که در کلاس میخوایم یک داده با مقدار یکسان و مشترک بین تمام اعضای کلاس تعریف کنیم، برای بهینه‌سازی در حافظه ی برنامه دیتا فیلد رو استاتیک (static) تعریف میکنیم.

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

به عنوان مثال میتونیم فیلد PI رو در کلاس Math در نظر بگیریم، چون مقدار PI همیشه 3.14 است نیاز نیست در هر آبجکت این مقدار به طور مجزا ایجاد بشه بنابراین PI رو به صورت فیلد استاتیک در Math تعریف کرده اند.

تعریف دیتافیلد استاتیک در کلاس:

public class MyClass{ ... public static Type myStaticField = ...; ... }

صدا زدن فیلد:

Type type = MyClass.myStaticField;

مثال

public class Log{ public static String label = "Log"; }
public static void main(String[] args){ System.out.println(label); }

متد های استاتیک

متد main که کد های جاوا رو داخلش اجرا میکنیم استاتیک (static) است.

این متد ها مانند فیلد های استاتیک (static) وابسته به کلاس هستند و بدون نیاز به نمونه سازی با استفاده از اسم کلاس صداشون می زنیم.

فرم کلی:

public class MyClass { public static void myStaticMethod(Type0 p0, Type1 p1, …, TypeN pN){ ... } }

صدا زدن متد:

Type0 type0 = new Type0(); Type1 type1 = new Type1(); ... TypeN typeN = new TypeN(); MyClass.myStaticMethodName(type0, type1, … , typeN)

مثال

public class Log{ private static String label = "Log"; public static void e(String message){ System.err.println(label + " error message: " + message) } public static void d(String message){ System.out.println(label + " debug message: " + message); } }
public static void main(String[] args){ Scanner input = newScanner(System.in); System.out.println("Enter radius"); double radius = input.nextDouble(); if(radius < 0) Log.e("Radius must not be negative"); else Log.d("Radius is " + radius); }

داخل کلاس یک متد استاتیک رو میتونیم داخل متد معمولی صدا بزنیم اما متد و فیلد های معمولی رو نمیتونیم داخل متد استاتیک صدا بزنیم؛ فیلد و متد هایی که میخوایم داخل متد استاتیک صدا بزنیم خودشون باید استاتیک باشن.

class MyClass{ private Type myMemberField; private Type1 myStaticField; public myMemberMethod(){ //... } public static myStaticSecondMethod(){ ... } public static myStaticMethod(){ //خطای کامپایل myMemberField = ...; //خطای کامپایل myMemberMethod(); //بدون خطا myStaticField = ...; //بدون خطا myStaticSecondMethod(); } }

مثال ها

در مثال زیر هربار یک آبجکت از کلاس دایره ایجاد بشه یک واحد به فیلد numberOfObjects اضافه میشه و با این کار تعداد آبجکت های ایجاد شده از کلاس Circle رو میشماریم.

public class Circle { double radius; private static int numberOfObjects = 0; public Circle(){ this.radius = 1; numberOfObjects ++; } public Circle(double radius){ this.radius = radius; numberOfObjects++; } public double getArea(){ return radius * radius * Math.PI; } public static int getNumberOfObjects(){ return Circle.numberOfObjects; } }

TestCircle.java

public class TestCircle { public static void main(String[] args){ System.out.println("Before creating new instance from Circle number of objects are " + Circle.getNumberOfObjects()); Circle c0 = new Circle(4); System.out.println("After creating c0: (radius: " + c0.radius + ", " + "area: " + c0.getArea() + ")" + " number of objects are " + Circle.getNumberOfObjects()); Circle c1 = new Circle(); System.out.println("After creating c1: (radius: " + c1.radius + ", " + "area: " + c1.getArea() + ")" + " number of objects are " + Circle.getNumberOfObjects()); } }

در مثال بالا یک فیلد استاتیک داریم به اسم numberOfObjects که تعداد نمونه های ایجاد شده از کلاس Circle رو میشماره و با متد استاتیک getNumberOfObjects این فیلد رو صدا میزنیم.

نمونه های ایجاد شده از کلاس Circle هرکدوم ویژگی های مختص به خودشونو دارن اما مقدار فیلد numberOfObjects بین تمام نمونه ها مشترکه.

مثال

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

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; public TV(String panel){ this.panel = panel; } public TV(){ this("FLATIRON"); } public void turnOn(){ on = true; } public void turnOff(){ on = false; } public void setChannel(int channel) { if (on && 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; } }

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

public static void main(String[] args){ TV tv1 = new TV(); tv1.turnOn(); tv1.setChannel(21); tv1.setVolume(4); TV tv2 = new TV(); 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.getChannel() + " and volume level is " + tv1.getVolume()); System.out.println("tv2 has been built by " + tv2.getPanel() + " panel"); System.out.println("tv2's channel is " + tv2.getChannel() + " and volume level is " + tv2.getVolume()); }

کلاس های استاتیک

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

نکته:

فقط کلاس های داخلی در جاوا یا همون Inner Class ها رو میشه به صورت استاتیک تعریف کرد

فرم کلی:

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

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

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

در مورد کلاس های داخلی استاتیک در قسمت کلاس های تو در تو بیشتر توضیح دادیم.

خلاصه:

-کلید واژه ی استاتیک در جاوا برای اعضای داخل کلاس استفاده میشه

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

- فیلدها ، متد ها و کلاس های داخل کلاس رو میتونیم به صورت استاتیک تعریف کنیم

- مقدار یک فیلد استاتیک میتونه بین تمام کلاس های پروژه تا زمان اجرای برنامه به اشتراک گذاشته بشه

- برای صدا زدن فیلد ها و متد های کلاس نام کلاس رو مینویسیم ، نقطه میزاریم و اسم متد یا فیلد رو می نویسیم

- برای نمونه سازی از کلاس های استاتیک new رو می نویسیم نام کلاس اصلی رو می نویسیم نقطه میزاریم و نام کلاس استاتیک داخل کلاس اصلی رو مینویسیم و مانند سایر کلاس ها نمونه سازی یا همون شی سازی می کنیم

موفق باشید

arrow_drop_up
کپی شد!