واجهة في جافا قليلا مثل فئة، ولكن مع فارق كبير: و `interface` يمكن أن يكون _فقط_ تواقيع طريقة والحقول والطرق الافتراضية. منذ Java 8 ، يمكنك أيضًا إنشاء [طرق افتراضية](https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html) . في الجزء التالي ، يمكنك مشاهدة مثال على الواجهة:
تحتوي الواجهة أعلاه على حقلين وطريقتين وطريقة افتراضية. وحدها ، ليست ذات فائدة كبيرة ، ولكنها تستخدم عادة مع الفصول. ماذا؟ بسيطة ، عليك أن تتأكد من أن بعض الصف يقوم `implements` .
الآن ، هناك **قاعدة أساسية** : يجب على الفئة تنفيذ **كافة** الطرق في الواجهة. يجب أن تحتوي الطرق _على نفس_ التوقيع _بالضبط_ (الاسم والمعلمات والاستثناءات) كما هو موضح في الواجهة. الفئة _لا_ تحتاج إلى إعلان الحقول رغم ذلك ، فقط الطرق.
## مثيلات واجهة
بمجرد إنشاء فئة Java تقوم `implements` أي واجهة ، يمكن الإشارة إلى مثيل الكائن كمثيل للواجهة. هذا المفهوم مشابه لمبدأ إنشاء الوراثة.
**لا يمكن أن** تحتوي واجهة على أساليب منشئ ، لذلك **لا يمكنك** إنشاء مثيل لواجهة بنفسها. يجب إنشاء مثيل لفئة معينة تقوم بتطبيق واجهة للرجوع إليها. فكر في الواجهات على أنها نموذج عقد فارغ ، أو نموذج.
ما الذي يمكنك القيام به مع هذه الميزة؟ تعدد الأشكال! يمكنك استخدام الواجهات فقط للإشارة إلى مثيلات الكائن!
نعم ، يمكنك تنفيذ واجهات متعددة في فصل واحد. أثناء [تواجدك](//forum.freecodecamp.com/t/java-docs-inheritance) في [التوارث](//forum.freecodecamp.com/t/java-docs-inheritance) داخل الصفوف ، تم تقييدك في فئة واحدة فقط ، يمكنك هنا توسيع أي عدد من الواجهات. ولكن لا ننسى تنفيذ _جميع_ أساليب جميع واجهات ، وإلا سوف تفشل التجميع!
* يمكنك وضع المتغيرات داخل واجهة ، على الرغم من أنه لن يكون قرارًا معقولًا لأن الفئات غير مرتبطة بالمتغير نفسه. باختصار ، تجنب وضع المتغيرات!
* تكون جميع المتغيرات والطرق في الواجهة عامة ، حتى إذا تركت الكلمة الرئيسية `public` .
* لا يمكن للواجهة تحديد تنفيذ طريقة معينة. ما يصل إلى فئات للقيام بذلك. على الرغم من وجود استثناء حديث (انظر أدناه).
* إذا قامت فئة بتطبيق واجهات متعددة ، فهناك احتمال بعيد لتداخل توقيع الأسلوب. بما أن Java لا تسمح بطرق متعددة من نفس التوقيع بالضبط ، فقد يؤدي هذا إلى حدوث مشكلات. انظر [هذا السؤال](http://stackoverflow.com/questions/2598009/method-name-collision-in-interface-implementation-java) لمزيد من المعلومات.
## طرق الواجهة الافتراضية
قبل Java 8 ، لم يكن لدينا طريقة لتوجيه واجهة لتطبيق طريقة معينة. هذا يؤدي إلى الكثير من الارتباك وفواصل التعليمات البرمجية إذا تم تغيير تعريف واجهة فجأة.
لنفترض أنك كتبت مكتبة مفتوحة المصدر تحتوي على واجهة. لنفترض أن عملاءك ، أي جميع المطورين تقريبًا في جميع أنحاء العالم ، يستخدمونها بكثافة ويسعدون. الآن كان عليك ترقية المكتبة بإضافة تعريف أسلوب جديد إلى الواجهة لدعم ميزة جديدة. ولكن هذا من شأنه أن يكسر _جميع عمليات_ البناء لأن كل الطبقات التي تقوم بتنفيذ هذه الواجهة يجب أن تتغير الآن. يا لها من كارثة!
لحسن الحظ ، توفر لك Java 8 الآن الطرق `default` للواجهات. _يمكن أن_ تحتوي الطريقة `default` على التنفيذ الخاص بها _مباشرة_ داخل الواجهة! لذا ، إذا لم يقم تطبيق Class بتنفيذ طريقة افتراضية ، فسيأخذ المترجم التنفيذ المذكور داخل الواجهة. جميل أليس كذلك؟ لذلك في مكتبتك ، يمكنك إضافة أي عدد من الطرق الافتراضية في واجهات دون الخوف من كسر أي شيء!
### ولكن ، ماذا يحدث إذا كان للواجهتين نفس توقيع الطريقة؟
سؤال رائع. في هذه الحالة ، إذا لم تقدم التطبيق في الصف ، فسوف يتم خلط المترجم الضعيف ويفشل ببساطة! يجب عليك توفير تنفيذ طريقة افتراضية داخل الفئة أيضًا. هناك أيضًا طريقة رائعة تستخدم ميزة `super` للاتصال بأي تطبيق تريده:
جديد أيضا إلى Java 8 هو القدرة على إضافة أساليب ثابتة إلى واجهات. تتشابه الطرق الثابتة في الواجهات تقريبًا مع الطرق الثابتة في الفصول الخرسانية. الاختلاف الكبير الوحيد هو أن الأساليب `static` غير موروثة في الفئات التي تقوم بتطبيق الواجهة. وهذا يعني أنه يتم الإشارة إلى الواجهة عند استدعاء الأسلوب الثابت وليس الفئة التي تقوم بتطبيقه.
`interface MusicPlayer {
public static void commercial(String sponsor) {
System.out.println("Now for a message brought to you by " + sponsor);
}
public void play();
}
class Smartphone implements MusicPlayer {
public void play() {
System.out.println("Playing from smartphone");
}
}
class Main {
public static void main(String[] args) {
Smartphone motoG = new Smartphone();
MusicPlayer.commercial("Motorola"); // Called on interface not on implementing class
// motoG.commercial("Motorola"); // This would cause a compilation error