PDA

View Full Version : منظور از متدهای Static چیه؟



Developer Programmer
جمعه 01 شهریور 1387, 16:46 عصر
هرچی میخونم کمتر متوجه میشم که منظور از متدهای Static چیه و چه مزیتی برای تعریف دارن.
کسی میتونه لطفا به صورت واضح و کامل توضیح بده؟


public static double mean(int[] p) {
int sum = 0; // sum of all the elements
for (int i=0; i<p.length; i++) {
sum += p[i];
}
return ((double)sum) / p.length;
}//endmethod mean

Cold.82
جمعه 01 شهریور 1387, 17:35 عصر
دوست عزیز کلمه static باعث میشه که قبل از ایجاد نمونه ای از کلاس بشه از ان استفاده کرد بر فرض مثال باید متد main رو static تعریف کرد
تا قبل از ایجاد هرشی توسط jvm فراخوانی شود.
مثلا یک کاربرد static که من خیلی خوشم میاد الگوی طراحی singleton هست.
البته محدودیتهایی هم دارند تنها سایر متدهای static می تونند انها را فراخوانی کنند.
با داده های static فقط می تونند کارکنند

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


className.method();

در کل میشه گفت اعضایی از کلاس هستند به تنهایی و بدون ارجاع به کلاسی قابل استفاده هستند.

Developer Programmer
جمعه 01 شهریور 1387, 21:37 عصر
دوست عزیز کلمه static باعث میشه که قبل از ایجاد نمونه ای از کلاس بشه از ان استفاده کرد
یعنی نیازی به Create کردن کلاسش نیست؟

Cold.82
جمعه 01 شهریور 1387, 22:00 عصر
یعنی نیازی به Create کردن کلاسش نیست؟

خوب اره دیگه شما شی از کلاس ایجاد نمی کنید در حالت عدی بر فرض مثال شما یک کلاس به نام name1 دارین می خواین به متدهای عمومی اون دسترسی داشته باشین یا کلا اعضای عمومی اون کلاس, میاین یک ابجکتی از اون کلاس می سازین مثلا به این صورت


name1 objname1=new name1();بعد با همین ابجکت به اعضای کلاس دسترسی دارین .

ولی اگه بخواین به اعضای static کلاس name1 دسترسی داشته باشین به این صورت عمل می کنین


name1.staticmember();staticmember در اینجا یک متد static هست .

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

d68715
شنبه 02 خرداد 1394, 14:27 عصر
میتونید در php با کلاس یاب print_r(get_declared_classes()); تست کنید . (http://grease-trap.ir)

manoto1371
شنبه 02 خرداد 1394, 18:26 عصر
شما وقتی یک متغیر داخل یه کلاس تعریف میکنید، اون متغیر به اشیایی که از اون کلاس درست خواهند شد متعلق هست. یعنی هر شی جدیدی که درست کنید یه نسخه واسه خودش از اون متعیر داره توی حافظه خودش. که این اتفاق نرمالیست که میفته و واسه همین به متغیر ها میگن Member variable یا Property (چون مال شی هستن).
اما زمانی که یه متغیر رو Static تعریف کنید. اون متغیر رو بیرون از فضای هر شی تعریف میکنه. در واقع متغیر میشه متغیر کلاس! و نه شی! یعنی متغیر به جای اینکه واسه هر شی توی حافظه اون شی جداگانه وجود داشته باشه، بک بار، یک جا و اونم توی حافظه سراسری کلاس تغریف شده است.
اگه این مطلب مهم رو گرفته باشید می توانید تا آخرش حدس بزنید:
خوب متغیری که static هستش نیازی به ساختن شی برای دسترسی و استفاده شدن نداره! چون تو کلاس وجود دارد.
متغیری که static هستش فقط یه نسخه ازش وجود داره به ازای تمام اشیای کلاس! بازم چون تو کلاس وجود دارد.
متغیری که static هستش مثل متغیر های سراسری (global) توی زبان های برنامه نویسی دیگه می ماند.

بر همین اساس Static یه جورایی دقیقن متضاد با مفهوم this و اشیا (شی گرایی) هستش. واسه همین استفاده ازش تا جایی که بشه توصیه نمیشه. مگر جاهایی که مجبوریم.
حالا به متد هم بسط بدیدش.

محمد فدوی
شنبه 02 خرداد 1394, 21:34 عصر
البته محدودیتهایی هم دارند تنها سایر متدهای static می تونند انها را فراخوانی کنند.

اینجوری نیست. متدهای static اگر public باشن، همه‌جا قابل دسترسی‌اند. به نوعی می‌شه گفت متدهای static و public جایگزین توابع Global (عمومی) در زبان‌هایی مثل ++C و PHP هست.
مثلا کلاس Math کلاسیه که پر از متدهای static هست که برای فراخوانیشون نیازی به ساختن یک شیء نیست. مثلا می‌خوام کلاسی بنویسم برای اعمال ریاضی:

public class MyMath {
public static double add(double a, double b) {
return a + b;
}
}

متد add همه‌جا و بدون هیچ‌محدودیتی و بدون نیاز به ساختن یک شیء از MyMath قابل دسترسیه:
double ten = MyMath.add(8, 2);
و کلاس‌هایی مثل Math و MyMath و SwingUtils و BorderFactory و... که همه‌ی متدهاشون بصورت static تعریف شدن و قرار نیست هیچ نمونه‌ای (Instance) از روش ساخته بشه معمولا یه سازنده‌ی private دارن که باعث می‌شه دیگه نشه هیچ نمونه‌ای از روشون ساخت:

public class MyMath {
private MyMath() { /* Do Nothing... */ }

public static double add(double a, double b) {
return a + b;
}
}

-سیّد-
یک شنبه 03 خرداد 1394, 08:40 صبح
اینجوری نیست. متدهای static اگر public باشن، همه‌جا قابل دسترسی‌اند.
فکر می‌کنم منظورشون این بود که تنها متدهای static رو می‌تونن فراخوانی کنن (یعنی برعکس گفتن). که در واقع درستش اینه که تنها متدهای static همون کلاس رو می‌تونن فراخوانی کنن (چون شیئی یا this ای وجود نداره).



و کلاس‌هایی مثل Math و MyMath و SwingUtils و BorderFactory و... که همه‌ی متدهاشون بصورت static تعریف شدن و قرار نیست هیچ نمونه‌ای (Instance) از روش ساخته بشه معمولا یه سازنده‌ی private دارن که باعث می‌شه دیگه نشه هیچ نمونه‌ای از روشون ساخت:

public class MyMath {
private MyMath() { /* Do Nothing... */ }

public static double add(double a, double b) {
return a + b;
}
}

البته جمله‌تون دقیق‌ترش این می‌شه: باعث می‌شه دیگه نشه با روش معمولی هیچ نمونه‌ای از روشون ساخت.
یعنی با new کردن نمی‌شه ساخت. ولی با Reflection می‌شه.
در واقع از طریق Reflection همه کار می‌شه کرد و تقریباً هیچ محدودیتی نمی‌شه توی زبان ایجاد کرد که با Reflection نشه دورش زد.


در تکمیل صحبت‌های دوستان هم دو تا نکته اضافه کنم:
یکی این که وقتی یه متغیر یا تابع static تعریف می‌شه، می‌تونیم از طریق یه شیء ازش استفاده کنیم:

public class X {
public static void foo() {
...
}

public static void main(String[] args) {
X.foo(); // ‫استفاده‌ی مستقیم از تابع بدون ساختن شیئی از X - مشکلی نیست
X z = new X();
z.foo(); // ‫استفاده از تابع به واسطه‌ی یک شیء از X - باز هم مشکلی نیست، فقط یک warning هست که تابع static رو روی شیء فراخوانی نکنید
}
}

در واقع اون warning ای که به شما می‌ده به خاطر اینه که حواستون باشه که روش درستی رو انتخاب نکردید و الکی دارید از شیء کلاس برای فراخوانی تابع استفاده می‌کنید. واقعیتش اینه که اون خط ()z.foo رو کامپایلر تبدیل می‌کنه به ()X.foo و به خاطر همین به شما warning می‌ده.

نکته‌ی دوم این که مفهوم static همونطور که دوستمون گفتن یه مفهوم عمومی هست که هم در مورد متغیرها وجود داره، هم در مورد توابع. این مفهوم در مورد کلاس‌ها هم وجود داره. وقتی شما یه inner class تعریف می‌کنید:

public class A {
...
public class B {
public B() {
}
...
}

B y = new B();
}

در اینجا یه کلاس B داریم که داخل کلاس A تعریف شده. دقیقاً مانند توابع، چون این کلاس داخلی static تعریف نشده، پس برای دسترسی به هر شیء از این کلاس باید یه شیء از A وجود داشته باشه. یعنی:

public static void main(String[] args) {
A x = new A();
x.y // ‫دسترسی به شیء B به واسطه‌ی شیء A - مشکلی نیست
B z = new B(); // ‫دسترسی مستقیم به کلاس B بدون حضور یک شیء از کلاس A - اینجا خطا داریم
}

در واقع خود زبان توی سازنده‌ی B میاد یه نمونه از A رو اضافه می‌کنه. یعنی سازنده‌ای که تعریف کردیم در واقع اینجوری تعریف شده:

public B(A a_this) {
}

و به خاطر همین توی main نمی‌تونیم همینطوری یه دونه از B بسازیم.

اما اگه همین inner class رو static تعریف کنیم، دیگه وابستگی‌اش به یه شیء از A رو از دست می‌ده و متعلق به کل کلاس A می‌شه:

public class A {
...
public static class C {
public C() {
}
...
}

C y = new C();
}

حالا توی main هم می‌تونیم از این inner class بسازیم:

public static void main(String[] args) {
A x = new A();
x.y // ‫دسترسی به شیء C به واسطه‌ی شیء A - مشکلی نیست
C z = new C(); // ‫دسترسی مستقیم به کلاس C بدون حضور یک شیء از کلاس A - چون کلاس C به صورت static تعریف شده مشکلی نیست
}

یعنی خلاصه‌اش می‌شه این: وقتی یه inner class به صورت static تعریف می‌کنید، انگار فقط کلاستون رو بردید داخل اون یکی کلاس و فقط از نظر نامگذاری تأثیر داره. یعنی انگار کلاس بالا رو اینطوری تعریف کرده باشید:

public class A.C {
public A.C() {
}
...
}


این قضیه یه مقدار پیچیده هست، امیدوارم تونسته باشم مفهوم رو درست منتقل کنم.