في هذا المقال، سنستكشف مفهوم الـ Interface في لغة دارت (Dart) وسنتعرف على كيفية تنفيذه باستخدام أمثلة توضيحية. تعتبر الواجهة في دارت مفهومًا مهمًا حيث يُمكن استخدامه لتحديد السلوك الذي يجب تنفيذه بواسطة الكلاسات. على الرغم من عدم وجود كلمة مفتاحية خاصة للواجهات في دارت، إلا أن كل كلاس يعتبر واجهة ضمنية، مما يتيح لك تنفيذ واجهات مخصصة. قبل أن نبدأ في استكشاف الواجهات، سنضع الأساسات من خلال فهم مفاهيم الكلاسات والكائنات والتوريث والـ Abstract Class في دارت.
مفهوم الـ Interface في دارت:
الـ Interface تحدد بناءً يجب على الكلاس اتباعه. إنها عقد يحدد قدرات الكلاس. تُستخدم الـ Interface لتحقيق التجريد Abstract في لغة برمجة دارت. عندما تنفذ الـ Interface، يجب أن تنفذ جميع الخصائص والدوال المعرفة في الـ Interface. يُستخدم الكلمة المُفتاحية “implements” لتنفيذ الـ Interface.
طريقة كتابة الـ Interface في دارت:
Syntax:
class InterfaceName { // code } class ClassName implements InterfaceName { // code }
طريقة تعريف الـ Interface في دارت:
في دارت، لا يوجد كلمة مفتاحية للـ Interface ولكن يمكنك استخدام الكلاس (class) أو الكلاس الأبستراكت (abstract class) لتعريف الـ Interface. جميع الكلاسات تعرف واجهة ضمنية. وعادةً ما يتم استخدام الكلاس الأبستراكت لتعريف الـ Interface.
// إنشاء الـ Interface باستخدام الكلاس الأبستراكت abstract class Person { canWalk(); canRun(); }
طريقة تنفيذ الـ Interface في دارت:
يجب عليك استخدام الكلمة المفتاحية “implements” لتنفيذ الـ Interface. يجب أن يقوم الكلاس الذي ينفذ الـ Interface بتنفيذ جميع الأساليب (الدوال) والخصائص المعرفة في الـ Interface.
class Student implements Person { // تنفيذ الأسلوب أو الدالة canWalk() @override canWalk() { print('Student can walk'); } // تنفيذ الأسلوب canRun() @override canRun() { print('Student can run'); } }
الوراثة المتعددة في دارت (Multiple Inheritance In Dart)
الوراثة المتعددة تعني أن الكلاس يمكنه أن ترث من أكثر من كلاس. في دارت، لا يمكنك أن ترث من أكثر من كلاس واحد، ولكن يمكنك تنفيذ الـ Interface بشكل متعدد في كلاس واحد.
بنية تنفيذ Interface متعددة في دارت:
class ClassName implements Interface1, Interface2, Interface3 { // code }
أمثلة على الـ Interface في دارت:
مثال 1: الـ Interface في دارت
في هذا المثال، يوجد Interface يسمى “Laptop” به أسلوبين أو دالتين محددين هما “turnOn()” و “turnOff()”. ينفذ الكلاس “MacBook” هذه الـ Interface ويقوم بتجاوز (override) الأساليب لطباعة الرسالة.
// إنشاء الـ Interface باستخدام الكلاس الملموس (concrete class) class Laptop { // الأسلوب turnOn() { print('Laptop turned on'); } // الأسلوب turnOff() { print('Laptop turned off'); } } class MacBook implements Laptop { // تنفيذ الأسلوب turnOn() @override turnOn() { print('MacBook turned on'); } // تنفيذ الأسلوب turnOff() @override turnOff() { print('MacBook turned off'); } } void main() { var macBook = MacBook(); macBook.turnOn(); macBook.turnOff(); }
نتيجة الكود:
MacBook turned on MacBook turned off
مثال 2: الـ Interface في دارت
في هذا المثال، يوجد كلاس أبستراكت يسمى “Vehicle” يحتوي على أسلوبين أبستراكت محددين هما “start()” و “stop()”. ينفذ الكلاس “Car” واجهة “Vehicle” ويقوم بتنفيذ الأساليب “start()” و “stop()”.
// كلاس الأبستراكت كواجهة الـ Interface abstract class Vehicle { void start(); void stop(); } // تنفيذ الـ Interface class Car implements Vehicle { @override void start() { print('Car started'); } @override void stop() { print('Car stopped'); } } void main() { var car = Car(); car.start(); car.stop(); }
نتيجة الكود:
Car started Car stopped
مثال 3: الـ Interface في دارت مع واجهات متعددة
في هذا المثال، هناك كلاسين أبستراكت يسميان “Area” و “Perimeter”. يحتوي كلاس “Shape” على تنفيذ لكلا الواجهتين “Area” و “Perimeter”. يجب على كلاس “Shape” تنفيذ الأساليب “area()” و “perimeter()”.
// كلاس الأبستراكت كواجهة abstract class Area { void area(); } // كلاس الأبستراكت كواجهة abstract class Perimeter { void perimeter(); } // تنفيذ واجهات متعددة class Rectangle implements Area, Perimeter { // الخصائص int length, breadth; // الـ constructor Rectangle(this.length, this.breadth); // تنفيذ الأسلوب area() @override void area() { print('مساحة المستطيل هي ${length * breadth}'); } // تنفيذ الأسلوب perimeter() @override void perimeter() { print('محيط المستطيل هو ${2 * (length + breadth)}'); } } void main() { Rectangle rectangle = Rectangle(10, 20); rectangle.area(); rectangle.perimeter(); }
نتيجة الكود:
مساحة المستطيل هي 200 محيط المستطيل هو 60
في هذا المثال، قمنا بتعريف واجهتين أبستراكت هما “Area” و “Perimeter”، وتم تنفيذهما في الكلاس “Rectangle”. الكلاس “Rectangle” يحتوي على خصائص الطول والعرض، ويقوم بتنفيذ الأساليب “area()” و “perimeter()” لحساب مساحة ومحيط المستطيل على التوالي.
عند تشغيل البرنامج، ستتم طباعة النتائج كما يلي:
مساحة المستطيل هي 200 محيط المستطيل هو 60
يتم حساب المساحة بضرب الطول في العرض، وبالتالي في هذا المثال يكون المساحة 200. أما بالنسبة للمحيط، فيتم حسابه بجمع ضعف الطول والعرض، وبالتالي في هذا المثال يكون المحيط 60.
إن تنفيذ الـ Interface في دارت يسمح بتحقيق التجريد وإعادة استخدام الأكواد، حيث يمكنك تعريف واجهات مخصصة وتنفيذها في الكلاسات لتحقيق السلوك المطلوب.
مثال 4: الـ Interface في دارت
في المثال أدناه، هناك كلاس مجرد اسمه “Person”. كلاس “Person” يحتوي على خاصية واحدة تُدعى “name” ودالتين مجردتين واحدة تسمى “run” والأخرى تسمى “walk”. كلاس “Student” ينفذ واجهة الكلاس “Person”. يتوجب على الكلاس “Student” تنفيذ الدوال “run” و “walk”.
// abstract class as interface abstract class Person { // properties String? name; // abstract method void run(); void walk(); } class Student implements Person { // properties String? name; // implementation of run() @override void run() { print('Student is running'); } // implementation of walk() @override void walk() { print('Student is walking'); } } void main() { var student = Student(); student.name = 'John'; print(student.name); student.run(); student.walk(); }
نتيجة الكود:
John Student is running Student is walking
مثال 5: الـ Interface في دارت
في المثال أدناه، هناك 2 كلاس مجرد “CalculateTotal” و”CalculateAverage”. كلاس “CalculateTotal” يحتوي على دالة مجردة تسمى “total()”، وكلاس “CalculateAverage” يحتوي على دالة مجردة تسمى “average()”. كلاس الطالب (Student) ينفذ كل من كلاس “CalculateTotal” وكلاس “CalculateAverage”. يتوجب على كلاس الطالب تنفيذ الدوال “total()” و”average()”.
// abstract class as interface abstract class CalculateTotal { int total(); } // abstract class as interface abstract class CalculateAverage { double average(); } // implements multiple interfaces class Student implements CalculateTotal, CalculateAverage { // properties int marks1, marks2, marks3; // constructor Student(this.marks1, this.marks2, this.marks3); // implementation of average() @override double average() { return total() / 3; } // implementation of total() @override int total() { return marks1 + marks2 + marks3; } } void main() { Student student = Student(90, 80, 70); print('Total marks: ${student.total()}'); print('Average marks: ${student.average()}'); }
نتيجة الكود:
Total marks: 240 Average marks: 80.0
إن مفهوم الواجهات الـ Interface في دارت هو أداة قوية لتنظيم وتحديد سلوك الكلاسات في تطبيقاتك. من خلال هذا المقال، ستكتسب المعرفة اللازمة لفهم كيفية تنفيذ الواجهات الـ Interface والاستفادة منها في برمجتك. تحقيق تفاعل وتكامل أكثر سهولة وكفاءة في تطوير تطبيقات دارت سيكون أمرًا ممكنًا بفضل فهمك لهذا المفهوم الأساسي.