في عالم لغة برمجة دارت (Dart)، يأتي الـ Abstract Class كأداة قوية لتعريف كلاس لا يمكن إنشاء كائنات منه مباشرة. يُستخدم الـ Abstract Class لتحديد سلوك يمكن توريثه واستخدامه وتوريثه من قبل كلاسات أخرى في التطبيق. يعتمد هذا الأسلوب على الكلمة المفتاحية “abstract” التي تُستخدم لتحديد الكلاس بأنه مجرد.
طريقة كتابة الـ Abstract Class في دارت:
يتم تعريف الـ Abstract Class باستخدام الجملة التالية:
abstract class ClassName { // جسم الـ Abstract Class method1(); method2(); }
الوظيفة المجردة (Abstract Method):
الوظيفة المجردة هي دالة يتم تعريفها بدون تنفيذ. يتم تعريفها باستخدام فاصلة منقوطة (;) بدلاً من جسم الدالة.
abstract class ClassName { // جسم الـ Abstract Class method1(); method2(); }
لماذا نحتاج للـ Abstract Class؟
يجب على الكلاسات المشتقة من الـ Abstract Class تنفيذ جميع الوظائف المجردة الموجودة في الـ Abstract Class. ويُستخدم الـ Abstract Class لتحقيق مفهوم التجريد في لغة Dart.
الـ Constructor في الـ Abstract Class:
لا يمكنك إنشاء كائن من الـ Abstract Class. ومع ذلك، يمكنك تعريف الـ Constructor في الـ Abstract Class. يتم استدعاء الـ Constructor الخاص بالـ Abstract Class عند إنشاء كائن من كلاس مشتق.
أمثلة على الـ Abstract Class في دارت:
مثال 1: الـ Abstract Class في Dart
في هذا المثال، لدينا Abstract Class يسمى “Vehicle” يحتوي على دالتين مجردتين وهما “start” و “stop”، ولدينا كلاسين مشتقين هما “Car” و “Bike” يتم تنفيذ الدوال المجردة فيهما وتعريفهما لطباعة رسالة.
abstract class Vehicle { // دالة مجردة void start(); // دالة مجردة void stop(); } class Car extends Vehicle { // تنفيذ دالة start() @override void start() { print('تم تشغيل السيارة'); } // تنفيذ دالة stop() @override void stop() { print('تم إيقاف السيارة'); } } class Bike extends Vehicle { // تنفيذ دالة start() @override void start() { print('تم تشغيل الدراجة'); } // تنفيذ دالة stop() @override void stop() { print('تم إيقاف الدراجة'); } } void main() { Car car = Car(); car.start(); car.stop(); Bike bike = Bike(); bike.start(); bike.stop(); }
نتيجة الكود:
تم تشغيل السيارة تم إيقاف السيارة تم تشغيل الدراجة تم إيقاف الدراجة
مثال 2: الـ Abstract Class في Dart
في هذا المثال، لدينا Abstract Class يسمى “Shape” تحتوي على دالة مجردة تسمى “area”، ولدينا كلاسين مشتقين هما “Rectangle” و “Triangle” يتم تنفيذ دالة “area” في كل منهما لحساب مساحة المستطيل والمثلث على التوالي.
abstract class Shape { int dim1, dim2; // الـ Constructor Shape(this.dim1, this.dim2); // دالة مجردة void area(); } class Rectangle extends Shape { // الـ Constructor Rectangle(int dim1, int dim2) : super(dim1, dim2); // تنفيذ دالة area() @override void area() { print('مساحة المستطيل هي ${dim1 * dim2}'); } } class Triangle extends Shape { // الـ Constructor Triangle(int dim1, int dim2) : super(dim1, dim2); // تنفيذ دالة area() @override void area() { print('مساحة المثلث هي ${0.5 * dim1 * dim2}'); } } void main() { Rectangle rectangle = Rectangle(10, 20); rectangle.area(); Triangle triangle = Triangle(10, 20); triangle.area(); }
نتيجة الكود:
مساحة المستطيل هي 200 مساحة المثلث هي 100.0
مثال 3: الـ Constructor في الـ Abstract Class
في هذا المثال أدناه، هناك Abstract Class يُسمى “Bank” يحتوي على Constructor يأخذ معه مُعاملين وهما الاسم والسعر. يوجد في هذا الكلاس أيضًا دالة مجردة تُسمى “interest()”، وتُمثل هذه الدالة كميزة مجردة. الكلاسات الفرعية هي NBE و CIB ينفذان الدالة المجردة ويعيدان تعريفها لطباعة معدل الفائدة.
abstract class Bank { String name; double rate; // Constructor Bank(this.name, this.rate); // Abstract method void interest(); //Non-Abstract method: It have an implementation void display() { print('اسم البنك: $name'); } } class NBE extends Bank { // Constructor NBE(String name, double rate) : super(name, rate); // Implementation of interest() @override void interest() { print('معدل الفائدة لبنك NBE هو $rate'); } } class CIB extends Bank { // Constructor CIB (String name, double rate) : super(name, rate); // Implementation of interest() @override void interest() { print('معدل الفائدة لبنك CIB هو $rate'); } } void main() { NBE nbe = NBE('NBE', 8.4); CIB cib = CIB ('CIB ', 7.3); nbe.interest(); cib.interest(); cib.display(); }
نتيجة الكود:
معدل الفائدة لبنك NBE هو 8.4 معدل الفائدة لبنك CIB هو 7.3 اسم البنك: CIB
النقاط الرئيسية لتذكرها:
- يمكن تعريف الـ Constructor في الـ Abstract Class.
- يتم استدعاء الـ Constructor الخاص بالـ Abstract Class عند إنشاء كائن من الكلاس المشتق.
- يمكن تنفيذ الوظائف المجردة الأخرى في الكلاس المشتق عند الحاجة.
- يمكن للكلاس المشتق تعريف واستخدام وظائف إضافية خاصة به.
إن استخدام الـ Abstract Class في لغة دارت يُعد أمرًا حيويًا لتنظيم وتوجيه تصميم التطبيقات بشكل فعّال. من خلال تعريف سلوك مجرد وتوريثه لكلاسات أخرى، يمكن للمطورين بناء تطبيقات قوية وسهلة الصيانة. يُظهر هذا المقال أهمية الـ Abstract Class في برمجة دارت وكيفية استفادتك منها في مشاريعك البرمجية.