البرمجة العامة (Generics) في جافا

Amine
30/09/2024

ما هي البرمجة العامة (Generics) في جافا؟

البرمجة العامة (Generics) هي ميزة في جافا تسمح بإنشاء فئات، واجهات، ودوال تعمل مع أنواع بيانات مختلفة، مع ضمان أمان الأنواع (Type Safety) أثناء وقت الترجمة (Compile Time). Generics تساعد في تجنب الأخطاء الناتجة عن التحويل غير الصحيح للأنواع، وتوفر مرونة أكبر في التعامل مع البيانات.

لماذا نستخدم Generics؟

تساعد Generics في تحقيق الأهداف التالية:

  • **أمان الأنواع (Type Safety):** تمنع الأخطاء الناتجة عن التحويل غير الصحيح للأنواع.
  • **إعادة استخدام الكود:** يمكن استخدام نفس الفئة أو الدالة مع أنواع بيانات مختلفة.
  • **الوضوح:** تجعل الكود أكثر وضوحًا وسهولة في القراءة.

كيفية إنشاء فئات باستخدام Generics

يمكنك إنشاء فئات تحتوي على معلمات عامة (Type Parameters) باستخدام الأقواس الزاوية <T>، حيث T يمثل نوع البيانات الذي سيتم تحديده لاحقًا. الصيغة العامة هي:

class ClassName<T> {
   private T data;

   ClassName(T data) {
      this.data = data;
   }

   public T getData() {
      return data;
   }
}

مثال:

class Container<T> {
   private T value;

   Container(T value) {
      this.value = value;
   }

   public T getValue() {
      return value;
   }
}

public class Main {
   public static void main(String[] args) {
      Container<String> stringContainer = new Container<>("مرحبا");
      Container<Integer> integerContainer = new Container<>(100);

      System.out.println("القيمة النصية: " + stringContainer.getValue());
      System.out.println("القيمة الرقمية: " + integerContainer.getValue());
   }
}

في هذا المثال، قمنا بإنشاء فئة عامة باسم Container تحتوي على معلمة T. يمكننا إنشاء كائنات من هذه الفئة بأنواع بيانات مختلفة، مثل النصوص (String) والأعداد الصحيحة (Integer).

كيفية إنشاء دوال باستخدام Generics

يمكنك إنشاء دوال تحتوي على معلمات عامة (Type Parameters) بنفس الطريقة. الصيغة العامة هي:

<T> returnType methodName(T parameter) {
   // الكود الذي يتم تنفيذه
}

مثال:

public class Main {
   public static <T> void printArray(T[] array) {
      for (T element : array) {
         System.out.print(element + " ");
      }
      System.out.println();
   }

   public static void main(String[] args) {
      Integer[] intArray = {1, 2, 3, 4, 5};
      String[] stringArray = {"مرحبًا", "بك", "في", "جافا"};

      printArray(intArray);  // طباعة مصفوفة الأعداد الصحيحة
      printArray(stringArray);  // طباعة مصفوفة النصوص
   }
}

في هذا المثال، قمنا بإنشاء دالة عامة printArray تقبل مصفوفة من نوع T. يمكننا تمرير أي نوع من المصفوفات، سواءً كانت مصفوفة أعداد صحيحة أو مصفوفة نصوص.

كيفية استخدام Generics مع المجموعات (Collections)

يمكنك استخدام Generics مع المجموعات (Collections) مثل ArrayList، HashMap، و HashSet لتحديد نوع البيانات الذي سيتم تخزينه في هذه المجموعات. مثال:

import java.util.ArrayList;

public class Main {
   public static void main(String[] args) {
      ArrayList<String> names = new ArrayList<>();
      names.add("أحمد");
      names.add("سارة");

      // طباعة الأسماء في القائمة
      for (String name : names) {
         System.out.println(name);
      }
   }
}

في هذا المثال، قمنا بإنشاء قائمة ArrayList لتخزين نصوص فقط باستخدام <String>، مما يضمن أن القائمة لن تحتوي على أي نوع آخر من البيانات.

قيود Generics في جافا

رغم أن Generics توفر مرونة كبيرة، إلا أن هناك بعض القيود التي يجب مراعاتها:

  • لا يمكنك استخدام أنواع بدائية (Primitive Types) مثل int أو char مباشرةً. بدلاً من ذلك، يمكنك استخدام الفئات المغلفة مثل Integer و Character.
  • لا يمكنك إنشاء كائنات من النوع العام داخل الكود مثل new T()، لأن جافا لا تحتفظ بالمعلومات الخاصة بالأنواع العامة أثناء وقت التشغيل.
  • لا يمكنك استخدام static مع المعلمات العامة في الفئات.

استخدام Generics مع الواجهات (Interfaces)

يمكنك أيضًا استخدام Generics مع الواجهات (Interfaces) لإنشاء واجهات عامة. مثال:

interface GenericInterface<T> {
   void display(T value);
}

class GenericClass<T> implements GenericInterface<T> {
   public void display(T value) {
      System.out.println("القيمة هي: " + value);
   }
}

public class Main {
   public static void main(String[] args) {
      GenericInterface<String> stringObject = new GenericClass<>();
      stringObject.display("مرحبا");

      GenericInterface<Integer> integerObject = new GenericClass<>();
      integerObject.display(100);
   }
}

في هذا المثال، قمنا بإنشاء واجهة عامة GenericInterface وفئة عامة GenericClass تطبق هذه الواجهة. ثم قمنا بإنشاء كائنات بأنواع بيانات مختلفة، مثل النصوص والأعداد الصحيحة.

استخدام Generics مع عدة أنواع (Multiple Type Parameters)

يمكنك استخدام أكثر من معلمة عامة في الفئات والدوال باستخدام فاصلة بين الأسماء. مثال:

class Pair<K, V> {
   private K key;
   private V value;

   Pair(K key, V value) {
      this.key = key;
      this.value = value;
   }

   public K getKey() {
      return key;
   }

   public V getValue() {
      return value;
   }
}

public class Main {
   public static void main(String[] args) {
      Pair<String, Integer> student = new Pair<>("أحمد", 25);
      System.out.println("اسم الطالب: " + student.getKey());
      System.out.println("عمر الطالب: " + student.getValue());
   }
}

في هذا المثال، قمنا بإنشاء فئة Pair تحتوي على معلمتين عامتين K و V. يمكننا استخدام هذه الفئة لإنشاء أزواج من القيم بأنواع بيانات مختلفة.

تمرين (مستوى متوسط): إنشاء قائمة عامة باستخدام Generics

في هذا التمرين، سنقوم بإنشاء قائمة عامة باستخدام Generics، يمكنها تخزين أنواع بيانات مختلفة وإضافة عناصر جديدة، ثم طباعة جميع العناصر في القائمة.

المتطلبات:

  • إنشاء فئة عامة GenericList تحتوي على مصفوفة عامة لتخزين العناصر.
  • إنشاء دالة add لإضافة عنصر جديد إلى القائمة.
  • إنشاء دالة display لطباعة جميع العناصر في القائمة.
  • إنشاء كائن من الفئة العامة بأنواع بيانات مختلفة، مثل النصوص والأعداد الصحيحة.

الكود:

import java.util.ArrayList;

class GenericList<T> {
   private ArrayList<T> list = new ArrayList<>();

   void add(T element) {
      list.add(element);
   }

   void display() {
      for (T element : list) {
         System.out.println(element);
      }
   }
}

public class Main {
   public static void main(String[] args) {
      GenericList<String> stringList = new GenericList<>();
      stringList.add("مرحبًا");
      stringList.add("بك");
      stringList.add("في");
      stringList.add("جافا");
      System.out.println("قائمة النصوص:");
      stringList.display();

      GenericList<Integer> integerList = new GenericList<>();
      integerList.add(10);
      integerList.add(20);
      integerList.add(30);
      System.out.println("قائمة الأعداد:");
      integerList.display();
   }
}

شرح الكود:

  • قمنا بإنشاء فئة عامة GenericList تحتوي على مصفوفة عامة لتخزين العناصر.
  • قمنا بإنشاء دالة add لإضافة عنصر جديد، ودالة display لطباعة جميع العناصر في القائمة.
  • أنشأنا كائنات من الفئة العامة بأنواع بيانات مختلفة (نصوص وأعداد صحيحة) وقمنا بعرض محتوياتها.

جرّب تنفيذ هذا البرنامج بنفسك، وشارك نتيجتك معنا في التعليقات! إذا واجهتك أي مشكلة أو كان لديك سؤال، لا تتردد في طرحه.

خاتمة

في هذا الدرس، تعرفنا على البرمجة العامة (Generics) في جافا، وكيفية استخدامها لإنشاء فئات ودوال تعمل مع أنواع بيانات مختلفة. كما تعرفنا على كيفية استخدام Generics مع المجموعات والواجهات. نوصي بممارسة التمرين المقدم لاكتساب المزيد من الخبرة في التعامل مع Generics. لا تنسَ ترك تعليق أو مشاركة هذا الدرس مع أصدقائك على وسائل التواصل الاجتماعي إذا وجدته مفيدًا!

التعليقات

اترك تعليقاً