static في Java

18:00 دقائق مجاني

ماذا تعني static؟ ولماذا ترتبط بالكلاس لا بالكائن؟ وكيف نستخدم static variables و static methods بشكل صحيح؟

ما معنى static؟

عندما تنشئ Object من Class، لكل كائن نسخته الخاصة من البيانات — شخصان، لكل واحد اسم وعمر مختلفان.

لكن أحيانًا نحتاج قيمة أو دالة مشتركة بين جميع الكائنات، لا تخص كائناً واحداً. هنا تأتي static.

💬 تشبيه: تخيّل شركة فيها 100 موظف. كل موظف عنده اسم خاص به (non-static). لكن اسم الشركة واحد مشترك للجميع (static) — لا يختلف من موظف لآخر.

👤 بدون static (خاص بكل كائن)

  • كل Object له نسخته الخاصة
  • الوصول عبر: p1.name
  • مثل: اسم الشخص، عمره، عنوانه

🏢 مع static (مشترك للجميع)

  • قيمة واحدة لجميع الكائنات
  • الوصول عبر: Counter.count
  • مثل: عداد الكائنات، اسم الشركة

المتغير static — قيمة مشتركة بين جميع الكائنات

سننشئ كلاساً فيه عدّاد static يُحسب كم كائناً تم إنشاؤه:

Counter.java
class Counter {
    // متغير static — مشترك لجميع الكائنات
    public static int count = 0;

    // Constructor — يزيد العداد عند كل إنشاء
    Counter() {
        count++;
    }
}

// إنشاء ثلاثة كائنات
Counter a = new Counter();   ← count = 1
Counter b = new Counter();   ← count = 2
Counter c = new Counter();   ← count = 3

System.out.println(Counter.count);  ← 3
🖥️ 3

🔍 ماذا يحدث في الذاكرة؟

بعد الكائن Counter.count (مشترك)
البداية 0
new Counter() a 1
new Counter() b 2
new Counter() c 3

لاحظ أن count لا يتكرر — هو نسخة واحدة مشتركة تزيد في كل مرة.

الدالة static — لا تحتاج إنشاء Object

الدوال التي لا تعتمد على بيانات كائن معيّن — مثل الدوال الرياضية — يُفضَّل جعلها static. يمكن استدعاؤها مباشرةً باسم الكلاس بدون إنشاء Object.

MathUtil.java
class MathUtil {

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

    public static int max(int a, int b) {
        return (a > b) ? a : b;
    }

    public static double circleArea(double r) {
        return 3.14159 * r * r;
    }
}
✅ الاستخدام — بدون إنشاء كائن
System.out.println(MathUtil.add(5, 3));          ← 8
System.out.println(MathUtil.max(10, 7));         ← 10
System.out.println(MathUtil.circleArea(5));    ← 78.53975
🖥️
8
10
78.53975
💡

مكتبة Java الشهيرة Math تعمل بنفس الطريقة — Math.sqrt(16) و Math.abs(-5) كلها دوال static تستدعيها مباشرةً!

متى أستخدم static ومتى لا أستخدمه؟

الحالة استخدم مثال
قيمة مشتركة بين جميع الكائنات static عداد الكائنات، اسم الشركة
دالة لا تعتمد على بيانات كائن static MathUtil.add(), Math.sqrt()
بيانات تختلف من كائن لآخر بدون static اسم الشخص، عمره، راتبه
دالة تعتمد على خصائص الكائن بدون static getName(), getAge()

⚠️ تحذير: لا تجعل كل شيء static!

بعض المبتدئين يضعون static على كل متغير ودالة لتجنب بعض الأخطاء — هذا يُفسد تصميم البرنامج ويلغي فكرة الكائنات:

❌ خطأ في التصميم

class Person { static String name; }

كل الأشخاص سيشتركون في نفس الاسم!

✅ صحيح

class Person { String name; }

لكل شخص اسمه الخاص

قاعدة مهمة — static لا تستطيع رؤية non-static

داخل دالة static (مثل main) لا يمكنك استخدام متغيرات غير static مباشرة. السبب: المتغيرات غير static تحتاج كائناً لتوجد، بينما static موجودة قبل أي كائن.

Test.java
class Test {
    int x = 10;   ← متغير عادي (non-static)

    public static void main(String[] args) {

        // خطأ: x غير static — لا يمكن الوصول إليها من static
        System.out.println(x);  ← ERROR!

        // الحل: إنشاء كائن أولًا
        Test t = new Test();
        System.out.println(t.x);   ← 10 ✅
    }
}

🔍 لماذا؟ — شرح مبسّط

1 Java تُشغّل main أولاً قبل أي شيء — وهي static تعمل بدون كائن.
2 المتغير x غير static — يعني يوجد فقط داخل كائن.
3 لا يوجد كائن بعد — لذا Java لا تعرف أيّ x تقصد!
الحل: أنشئ كائناً أولاً ثم استخدم t.x.
💡

هذا يفسّر لماذا كنا نكتب public static void أمام كل دوالنا في main — لأن main نفسها static وتحتاج كل ما تستدعيه أن يكون static أو عبر كائن.

أخطاء شائعة عند المبتدئين ⚠️

خطأ ١

استخدام static في كل مكان

وضع static على متغيرات تختلف من كائن لآخر يجعل جميع الكائنات تتشارك نفس القيمة — وهذا خطأ منطقي خطير.

خطأ ٢

الوصول لمتغير static عبر كائن بدل الكلاس

⚠️ يعمل لكن مُضلِّل

Counter a = new Counter(); a.count; // يعمل لكن محيّر

✅ الأفضل

Counter.count;

واضح أنه تابع للكلاس

خطأ ٣

استخدام متغير non-static داخل دالة static مباشرةً

يجب دائماً إنشاء كائن أولاً للوصول للمتغيرات غير static من داخل static method.

📋 ملخص الدرس

static = تابع للكلاس، مشترك بين جميع الكائنات

الوصول: ClassName.member بدون كائن

static method لا ترى non-static مباشرةً

لا تستخدمها لكل شيء — فقط عند الحاجة الفعلية

⏭️ في الدرس القادم:

سنتعلم المصفوفات (Arrays) — كيف تخزّن مجموعة قيم داخل متغير واحد، والتعامل معها بالحلقات.

الدرس التالي العودة للسابق