📦 Wrapper Classes في الجافا: الجسر بين الأنواع البدائية والكائنات! 🚀

مرحباً بك في درس جديد ومهم جداً! اليوم سنتعرف على مفهوم Wrapper Classes أو "فئات التغليف" في لغة الجافا. إذا كنت تتساءل عن سبب حاجتنا لهذه الفئات وكيف تعمل، فأنت في المكان الصحيح. هيا نبدأ!


🤔 ما هي Wrapper Classes؟ ولماذا نحتاجها؟

في الجافا، لدينا نوعان رئيسيان من البيانات:

  1. الأنواع البدائية (Primitive Types): مثل int, double, char, boolean. هذه الأنواع بسيطة وسريعة، لكنها ليست كائنات (Objects).
  2. أنواع المرجع (Reference Types): مثل String أو أي كائن ننشئه من كلاس. هذه هي كائنات حقيقية.

المشكلة: هناك العديد من الميزات في الجافا (مثل المجموعات - Collections التي سندرسها لاحقاً) التي تتعامل فقط مع الكائنات ولا تقبل الأنواع البدائية. هنا يأتي دور أبطالنا، فئات التغليف!

الحل: وفرت جافا لكل نوع بدائي "فئة تغليف" تقوم بتحويل هذا النوع البدائي إلى كائن. Think of it like putting a simple gift (primitive) inside a fancy box (object) so it can be handled in a more sophisticated way.

النوع البدائي (Primitive) فئة التغليف المقابلة (Wrapper Class)
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

لاحظ أن أسماء فئات التغليف تبدأ بحرف كبير، تماماً مثل أي كلاس آخر في الجافا.


🔄 العمليتان الأساسيتان: Boxing و Unboxing

لفهم كيفية عمل فئات التغليف، يجب أن نتعرف على مفهومين رئيسيين:

1. التغليف (Boxing)

هي عملية تحويل النوع البدائي إلى كائن من فئة التغليف المقابلة. (وضع القيمة في الصندوق).

2. إزالة التغليف (Unboxing)

هي عملية عكسية،تحويل كائن فئة التغليف مرة أخرى إلى نوع بدائي. (إخراج القيمة من الصندوق).

دعنا نرى مثالاً يوضح الفرق بين الطريقة القديمة (يدوياً) والطريقة الحديثة (تلقائياً).


💻 أمثلة عملية على Boxing و Unboxing

المثال 1: Boxing يدوي (طريقة قديمة)

في الإصدارات الأولى من الجافا، كان علينا إجراء التغليف يدوياً باستخدام المُنشئ (Constructor) أو الطريقة valueOf.

public class WrapperExample {
    public static void main(String[] args) {
        // نوع بدائي
        int number = 10;

        // 1. Boxing يدوي باستخدام المُنشئ (ملاحظة: أصبح غير مستحب في الجافا الحديثة)
        Integer integerObj1 = new Integer(number);

        // 2. Boxing يدوي باستخدام valueOf (الطريقة المفضلة)
        Integer integerObj2 = Integer.valueOf(number);

        System.out.println("القيمة البدائية: " + number); // الناتج: 10
        System.out.println("كائن Integer: " + integerObj2); // الناتج: 10
    }
}

المثال 2: Autoboxing (التغليف التلقائي) 🎁

بدءاً من Java 5، أصبحت الجافا ذكية بما يكفي لإجراء عملية التغليف تلقائياً! هذا ما نسميه Autoboxing. لم نعد نحتاج لاستدعاء valueOf بشكل صريح.

public class AutoboxingExample {
    public static void main(String[] args) {
        int primitiveInt = 5;
        double primitiveDouble = 7.99;

        // Autoboxing: الجافا تحول البدائي إلى كائن تلقائياً!
        Integer wrappedInt = primitiveInt;
        Double wrappedDouble = primitiveDouble;

        System.out.println(wrappedInt); // الناتج: 5
        System.out.println(wrappedDouble); // الناتج: 7.99
    }
}

المثال 3: Unboxing (إزالة التغليف) التلقائي

بالمثل، يمكن للجافا إخراج القيمة من الكائن وتحويلها إلى نوع بدائي تلقائياً. هذا هو Unboxing.

public class UnboxingExample {
    public static void main(String[] args) {
        // إنشاء كائنات من فئات التغليف
        Integer wrappedInt = Integer.valueOf(20);
        Boolean wrappedBool = Boolean.valueOf(true);

        // Unboxing تلقائي: الجافا تحول الكائن إلى بدائي تلقائياً!
        int primitiveInt = wrappedInt;
        boolean primitiveBool = wrappedBool;

        System.out.println(primitiveInt); // الناتج: 20
        System.out.println(primitiveBool); // الناتج: true

        // يمكننا حتى إجراء عمليات حسابية مباشرة
        int result = wrappedInt + 5; // Unboxing ثم جمع!
        System.out.println(result); // الناتج: 25
    }
}

🌟 فوائد واستخدامات هامة لـ Wrapper Classes

  1. التعامل مع المجموعات (Collections): كما ذكرنا، هياكل البيانات مثل ArrayList يمكنها تخزين الكائنات فقط، وليس الأنواع البدائية. لذا نستخدم ArrayList<Integer> بدلاً من ArrayList<int>.
  2. الوظائف المساعدة (Utility Methods): توفر فئات التغليف العديد من الطرق المفيدة. على سبيل المثال، تحويل String إلى رقم.

مثال: تحويل String إلى int باستخدام Integer.parseInt()

هذه من أكثر الاستخدامات العملية والشائعة.

public class ParseExample {
    public static void main(String[] args) {
        String userInput = "12345"; // رقم مكتوب كنص

        // تحويل النص إلى نوع بدائي int
        int number = Integer.parseInt(userInput);

        System.out.println("الرقم بعد التحويل: " + number); // الناتج: 12345
        System.out.println("يمكننا جمعه الآن: " + (number + 10)); // الناتج: 12355

        // يمكننا أيضاً تحويله إلى كائن Integer
        Integer numberObj = Integer.parseInt(userInput);
    }
}

كل فئة تغليف لديها طريقة parseXxx مقابلة، مثل Double.parseDouble() و Boolean.parseBoolean().


🧠 خلاصة الدرس

  • فئات التغليف (Wrapper Classes) هي كائنات تمثل الأنواع البدائية في الجافا.
  • نحتاجها للتعامل مع الميزات التي تتطلب كائنات، مثل المجموعات.
  • Boxing هو تحويل البدائي إلى كائن، و Unboxing هو تحويل الكائن إلى بدائي.
  • تقوم الجافا تلقائياً بعمليتي Autoboxing و Unboxing لتسهيل الكتابة.
  • توفر فئات التغليف طرقاً مساعدة مفيدة مثل parseInt() لتحويل النصوص إلى أرقام.