Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

الواجهات الوظيفية (Functional Interfaces)

جزء من قسم البرمجة كائنية التوجه في رحلة Java على Coddy. الدرس 39 من 87.

إنَّ functional interface هي interface تحتوي على method واحدة abstract بالضبط. ويجعل هذا القيد الخاص بالـ method الواحدة من functional interfaces شيئًا مميزًا، إذ يمكن تنفيذها باستخدام تعبيرات lambda، مما يتيح أسلوبًا أكثر إيجازًا في كتابة التعليمات البرمجية.

توفر Java التعليق التوضيحي @FunctionalInterface لوضع علامة صراحةً على interface باعتبارها functional. وعلى الرغم من أن هذا التعليق التوضيحي اختياري، فإنه يساعد المترجم على اكتشاف الأخطاء إذا أضفت عن طريق الخطأ method ثانية من نوع abstract:

@FunctionalInterface
public interface Calculator {
    int calculate(int a, int b);
}

يمكنك تنفيذ functional interface بالطريقة التقليدية باستخدام class، أو بشكل أكثر إيجازًا باستخدام تعبير lambda:

// التنفيذ التقليدي
Calculator adder = new Calculator() {
    @Override
    public int calculate(int a, int b) {
        return a + b;
    }
};

// Lambda expression (much shorter!)
Calculator adder = (a, b) -> a + b;

System.out.println(adder.calculate(5, 3));  // 8

لا يزال بإمكان الواجهات الوظيفية أن تحتوي على أساليب افتراضية وأساليب ثابتة، لأن هذه الأساليب لا تُحتسب ضمن قاعدة الأسلوب المجرد الوحيد. توفّر حزمة Java‏ java.util.function العديد من الواجهات الوظيفية المضمّنة، مثل Predicate وFunction وConsumer، وستصادفها كثيرًا عند العمل مع التدفقات والمجموعات.

challenge icon

التحدي

سهل

لنبنِ نظامًا لتحويل السلاسل النصية باستخدام functional interfaces وlambda expressions. ستنشئ معالجًا مرنًا للنصوص يمكنه تطبيق تحويلات مختلفة على السلاسل النصية: وكل ذلك مدعومًا بواجهة functional واحدة.

ستنظّم الكود عبر ثلاثة ملفات:

  • StringTransformer.java: Define واجهة functional تمثّل أي operation لتحويل سلسلة نصية. ميّزها بالتعليق التوضيحي @FunctionalInterface لضمان بقائها functional. يجب أن تعلن واجهتك عن method abstract واحدة تُسمى transform، تأخذ String وتُعيد String.
  • TextProcessor.java: Create class تستخدم واجهتك functional لمعالجة النص. يجب أن تحتوي على field للاحتفاظ بـ StringTransformer وconstructor لتهيئته. أدرج method تُسمى process(String text) وتطبّق transformer على النص المحدد وتُعيد Result. يتيح لك هذا التصميم حقن أي سلوك للتحويل من خلال constructor.
  • Main.java: اجمع كل شيء معًا من خلال إنشاء تحويلات مختلفة باستخدام lambda expressions. ستتلقى inputين: سلسلة نصية وعملية operation (upper أو lower أو reverse).

    استنادًا إلى نوع operation، أنشئ TextProcessor باستخدام lambda المناسبة:

    • upper: تحوّل النص إلى أحرف uppercase
    • lower: تحوّل النص إلى أحرف lowercase
    • reverse: تعكس النص (hint: استخدم StringBuilder)

    ثم استدعِ process() باستخدام input النص واطبع Result بهذا format: Result: [transformed text]

ستتلقى inputين: النص المراد تحويله (String) ونوع operation (String).

لاحظ كيف يمكن للفئة TextProcessor نفسها تنفيذ operations مختلفة تمامًا اعتمادًا على lambda التي تمررها إليها: تلك هي قوة functional interfaces!

جرّب بنفسك

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String text = scanner.nextLine();
        String operation = scanner.nextLine();
        
        TextProcessor processor;
        
        // TODO: بناءً على نوع العملية، أنشئ TextProcessor باستخدام تعبير lambda المناسب:
        // - "upper": يحول النص إلى أحرف كبيرة
        // - "lower": يحول النص إلى أحرف صغيرة
        // - "reverse": يعكس النص (تلميح: استخدم StringBuilder)
        
        // TODO: استدعِ process() مع النص المدخل واطبع النتيجة
        // تنسيق الإخراج: "Result: [transformed text]"
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Java عبر الإنترنت