أدناه نستمر في الغوص في نموذج البرمجة الوظيفية Java8
الفئة العامة test1 {public static void main (string [] args) {list <integer> list = arrays.aslist (1،2،3،5،5،7،7،8،9،10) ؛ list.foreach (مستهلك جديد <integer> () {Override public void قبول (integer integer) {system.out.println (integer) ؛}}) ؛ }}هذا البرنامج بسيط ، قم أولاً بتهيئة مجموعة من نوع عدد صحيح ثم إخراج كل عنصر إلى وحدة التحكم. من بينها ، لاحظنا طريقة foreach ، وهي الطريقة الافتراضية المضافة حديثًا في Java 8.
الواجهة العامة ITERBLE <T> {. . حذف. void void foreach (المستهلك <؟ super t> الإجراء) {objects.requirenonnull (Action) ؛ لـ (t t: this) {action.accept (t) ؛ }}}يتم إعلانه في الواجهة الجاهزة ويتم تعديله بواسطة الكلمة الرئيسية الافتراضية. وبهذه الطريقة ، يمكن لأي نوع فرعي لهذه الواجهة أن يرث تنفيذ طريقة foreach ، وبالتالي فإن واجهة القائمة هي واجهة فرعية غير مباشرة من iTERBAL ، لذلك فإنها ترث الطريقة الافتراضية أيضًا. يعتمد Java8 هذه الطريقة الذكية لتوسيع وظائف الواجهة وهي متوافقة مع الإصدار القديم.
بعد ذلك ، نقوم بتحليل تنفيذ foreach. أولاً ، نتلقى إجراءً معلمة من نوع المستهلك ، وأداء حكم غير فارغ ، ثم اجتياز جميع العناصر الحالية وتسليمها إلى طريقة قبول الإجراء للمعالجة. إذن ما هو المستهلك بحق الجحيم؟ انظر إلى رمز المصدر
FunctionalInterFacepublic Interface Consumer <T> { /*** يؤدي هذه العملية على الوسيطة المحددة. * * param t وسيطة الإدخال */ void قبول (t t) ؛ . . يتم تعديل واجهة ، مع طريقة مجردة واحدة فقط ، بواسطة functionalInterface ، واجهة وظيفية نموذجية.
حسنًا ، نعلم الآن أن المعلمة من نوع المستهلك الذي تم استلامه بواسطة Foreach هو واجهة وظيفية. تستقبل الطريقة المجردة الوحيدة في الواجهة معلمة ولا تُرجع قيمة. من المقالة السابقة ، نعلم أن إحدى طرق إنشاء مثيلات من أنواع الواجهة الوظيفية هي استخدام تعبيرات Lambda ، بحيث يمكنك تحويل البرنامج العلوي.
الفئة العامة test1 {public static void main (string [] args) {list <integer> list = arrays.aslist (1،2،3،5،5،7،7،8،9،10) ؛ // Lambda Expression يتلقى معلمة دون إرجاع قائمة القيمة. }} عنصر تعبير Lambda -> system.out.println (العنصر) يتلقى معلمة دون إرجاع قيمة ، ويلبي متطلبات توقيع طريقة القبول ويتم تجميعها وتمريرها.
وهذا يعني ، إذا تم استخدام تعبير Lambda لإنشاء مثيل واجهة وظيفية ، فيجب أن تتوافق معلمات الإدخال وإرجاع تعبير Lambda هذا مع توقيع الطريقة للطريقة التجريدية الوحيدة في هذه الواجهة الوظيفية.
بعد ذلك ، سيتم تعديل البرنامج
الفئة العامة test1 {public static void main (string [] args) {list <integer> list = arrays.aslist (1،2،3،5،5،7،7،8،9،10) ؛ // Method Reference List.foreach (system.out :: println) ؛ }} رأيت اثنين من كولونس خلفهم ، لكنني كنت في حالة من الفوضى على أي حال. . . هذه هي الطريقة الثانية لإنشاء مثيل واجهة وظيفية: Method Method Method Reference Syntax هو كائن :: اسم الطريقة
وبالمثل ، يجب أن يلتزم طريقة مرجع الطريقة لإنشاء مثيلات الواجهة الوظيفية أيضًا بتعريف توقيع الطريقة. انظر رمز مصدر طريقة println هنا
public void println (object x) {string s = string.valueof (x) ؛ متزامن (هذا) {print (s) ؛ NewLine () ؛ }} تلقي معلمة ولا تُرجع القيمة ، وتجميعها من خلال.
أخيرًا ، دعونا نلقي نظرة على النوع الأخير من إنشاء واجهة وظيفية. الطريقة الثالثة: إنشاء طريقة بناء وتواصل تعديل البرنامج.
الفئة العامة test1 {public static void main (string [] args) {list <integer> list = arrays.aslist (1،2،3،5،5،7،7،8،9،10) ؛ // constructor method list.foreach (test1 :: new) ؛ } test1 (integer i) {system.out.println (i) ؛ }} بناء الجملة المشار إليه من قبل المنشئ هو: اسم الفصل :: الجديد
لقد أضفنا مُنشئًا جديدًا إلى Test1 ، الذي يتلقى معلمة ، لا يعيد قيمة ، ويجمع من خلال. (لإظهار استخدام اقتباسات المنشئ فقط)
بناءً على المقالة السابقة ، يمكننا تلخيص ثلاث طرق لإنشاء أنواع الواجهة الوظيفية:
1. تعبير لامدا
2. طريقة الاقتباس
3. مرجع طريقة المنشئ
ملاحظة: بغض النظر عن الطريقة ، يجب أن يكون توقيع الطريقة متوافقًا مع الطريقة التجريدية.