JavaRush /مدونة جافا /Random-AR /دروس مجردة في جافا مع أمثلة محددة

دروس مجردة في جافا مع أمثلة محددة

نشرت في المجموعة
مرحبًا! في المحاضرات السابقة، تعرفنا على الواجهات وتعرفنا على ما هو مطلوب منها. سيكون لموضوع اليوم شيء مشترك مع الموضوع السابق. دعونا نتحدث عن الطبقات المجردة في جافا. دروس مجردة في جافا مع أمثلة ملموسة - 1

لماذا تسمى الطبقات "مجردة"

ربما تتذكر ما هو "التجريد" - لقد قمنا بتغطيته بالفعل :) إذا نسيت فجأة، فلا بأس، دعنا نتذكر: هذا هو مبدأ OOP ، والذي بموجبه، عند تصميم الفئات وإنشاء الكائنات، من الضروري تسليط الضوء فقط على الخصائص الرئيسية للكيان وتجاهل الخصائص الثانوية. على سبيل المثال، إذا كنا نقوم بتصميم فصل دراسي SchoolTeacher- معلم مدرسة - فمن غير المرجح أن نحتاج إلى خاصية " الارتفاع ". في الواقع: هذه الخاصية ليست مهمة بالنسبة للمعلم. ولكن إذا قمنا بإنشاء فصل دراسي في البرنامج BasketballPlayer- لاعب كرة سلة - فسيصبح الارتفاع أحد الخصائص الرئيسية. لذلك، فإن الطبقة المجردة هي "الفارغة" الأكثر تجريدًا وتقريبًا لمجموعة من الفئات المستقبلية. لا يمكن استخدام هذا المستحضر في شكله النهائي - فهو "خام" للغاية. لكنه يصف حالة وسلوكًا عامًا معينًا ستتمتع به الطبقات المستقبلية - ورثة الطبقة المجردة.

أمثلة على فئة مجردة جافا

دعونا نلقي نظرة على مثال بسيط مع السيارات:
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public abstract void gas();

   public abstract void brake();

   public String getModel() {
       return model;
   }

   public void setModel(String model) {
       this.model = model;
   }

   public String getColor() {
       return color;
   }

   public void setColor(String color) {
       this.color = color;
   }

   public int getMaxSpeed() {
       return maxSpeed;
   }

   public void setMaxSpeed(int maxSpeed) {
       this.maxSpeed = maxSpeed;
   }
}
هذا ما تبدو عليه أبسط فئة مجردة. كما ترون، لا يوجد شيء مميز :) ما الذي قد نحتاج إليه؟ بادئ ذي بدء، يصف الكيان الذي نحتاجه بشكل تجريدي قدر الإمكان - السيارة. كلمة مجردة هنا لسبب ما. لا توجد "آلات فقط" في العالم. هناك الشاحنات وسيارات السباق وسيارات السيدان والكوبيه وسيارات الدفع الرباعي. إن فئتنا المجردة هي ببساطة "مخطط" سنقوم من خلاله لاحقًا بإنشاء فئات السيارات.
public class Sedan extends Car {

   @Override
   public void gas() {
       System.out.println("The sedan accelerates!");
   }

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }

}
وهذا يشبه إلى حد كبير ما تحدثنا عنه في المحاضرات عن الميراث. هناك فقط كان لدينا فصل Carوأساليبه لم تكن مجردة. لكن هذا الحل له عدد من العيوب، والتي يتم تصحيحها في الفصول المجردة. أولاً وقبل كل شيء، لا يمكن إنشاء مثيل لفئة مجردة:
public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
تم تنفيذ هذه "الحيلة" خصيصًا من قبل منشئي Java. مرة أخرى، فقط لنتذكر: الفصل المجرد هو مجرد مخطط للفصول "العادية" المستقبلية . لا تحتاج إلى نسخ من الرسم، أليس كذلك؟ لذلك ليست هناك حاجة لإنشاء مثيلات لفئة مجردة :) وإذا Carلم تكن الفئة مجردة، فيمكننا بسهولة إنشاء كائناتها:
public class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       // some logic
   }

   public  void brake() {
       // some logic
   }
}


public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Everything is OK, the machine has been created
   }
}
الآن لدينا نوع من السيارة غير المفهومة في برنامجنا - ليست شاحنة، وليست سيارة سباق، وليست سيارة سيدان، ولكن شيئًا بشكل عام. نفس "مجرد آلة" غير موجودة في الطبيعة. ويمكن إعطاء نفس المثال مع الحيوانات. تخيل لو ظهرت كائنات في برنامجك Animal- " مجرد حيوان ". ما هو نوعه، وما هي العائلة التي ينتمي إليها، وما هي خصائصه غير واضحة. سيكون من الغريب رؤيته في البرنامج. لا توجد "حيوانات فقط" في الطبيعة. فقط الكلاب والقطط والثعالب والشامات وغيرها. الطبقات المجردة تحررنا من " الأشياء فقط ". أنها تعطينا الحالة والسلوك الأساسي. على سبيل المثال، يجب أن يكون لجميع السيارات طراز ولون وسرعة قصوى ، كما يجب أن تكون قادرة على البنزين والفرامل . هذا كل شئ. هذا مخطط تجريدي عام، ثم تقوم بتصميم الفئات التي تحتاجها بنفسك. يرجى ملاحظة: تم أيضًا تصنيف طريقتين في فئة مجردة على أنهما مجردة ، ولم يتم تنفيذهما على الإطلاق. السبب هو نفسه: الفئات المجردة لا تنشئ "سلوكًا افتراضيًا" لـ "مجرد الأجهزة". يقولون فقط أنهم يجب أن يكونوا قادرين على صنع جميع السيارات. ومع ذلك، إذا كنت لا تزال بحاجة إلى السلوك الافتراضي، فيمكنك تنفيذ الأساليب في فئة مجردة. جافا لا تحظر هذا:
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       System.out.println("Let's go!");
   }

   public abstract void brake();

   //getters and setters
}


public class Sedan extends Car {

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }

}

public class Main {

   public static void main(String[] args) {

       Sedan sedan = new Sedan();
       sedan.gas();
   }
}
إخراج وحدة التحكم: "احصل على التسريع!" كما ترون، قمنا بتنفيذ طريقة واحدة في الفصل الملخص، لكننا لم ننفذ الطريقة الثانية. ونتيجة لذلك، تم تقسيم سلوك فصلنا Sedanإلى قسمين: إذا قمت باستدعاء طريقة عليه gas()، فسوف "يسحب" من الفئة المجردة الأصل Car، وقمنا brake()بإعادة تعريف الطريقة في الفصل Sedan. اتضح أنها مريحة ومرنة للغاية. ولكن الآن صفنا ليس مجردا جدا ؟ بعد كل شيء، في الواقع، تم تنفيذ نصف أساليبه. في الواقع - وهذه ميزة مهمة جدًا - يكون الفصل مجردًا إذا كانت إحدى طرقه على الأقل مجردة . واحدة على الأقل من اثنتين، أو واحدة على الأقل من بين ألف طريقة - لا يهم. يمكننا أيضًا تنفيذ جميع الطرق وعدم ترك أي طرق مجردة. سيكون هناك فئة مجردة بدون أساليب مجردة. من حيث المبدأ، هذا ممكن، ولن ينتج المترجم أخطاء، ولكن من الأفضل عدم القيام بذلك: ستفقد كلمة مجردة معناها، وسوف يتفاجأ زملائك المبرمجون بشدة برؤية هذا:/ علاوة على ذلك، إذا كانت هناك طريقة تم تمييزها بكلمة مجردة، ويجب على كل فئة فرعية تنفيذها أو الإعلان عنها مجردة. وإلا فإن المترجم سوف يلقي خطأ . بالطبع، يمكن لكل فئة أن ترث من فئة مجردة واحدة فقط، لذلك من حيث الميراث لا يوجد فرق بين الطبقات المجردة والعادية. لا يهم ما إذا كنا نرث من فئة مجردة أو من فئة عادية، لا يمكن أن يكون هناك سوى فئة رئيسية واحدة.

لماذا لا يوجد وراثة متعددة الطبقات في جافا؟

لقد قلنا بالفعل أنه لا يوجد وراثة متعددة في Java، لكننا لم نكتشف السبب حقًا. دعونا نحاول هذا الآن. النقطة المهمة هي أنه إذا كان لدى Java وراثة متعددة، فلن تتمكن الفئات الفرعية من تحديد السلوك الذي يجب اختياره. لنفترض أن لدينا فئتين - Tosterو NuclearBomb:
public class Toster {


 public void on() {

       System.out.println("The toaster is on, the toast is getting ready!");
   }

   public void off() {

       System.out.println("The toaster is off!");
   }
}


public class NuclearBomb {

   public void on() {

       System.out.println("Взрыв!");
   }
}
كما ترون، كلاهما لديه طريقة on(). في حالة محمصة الخبز، تبدأ في طهي الخبز المحمص، وفي حالة القنبلة النووية، فإنها تسبب انفجارًا. أوه:/ الآن تخيل أنك قررت (لا أعرف لماذا فجأة!) إنشاء شيء ما بينهما. وهنا فصلك - MysteriousDevice! هذا الكود بالطبع لا يعمل، ونقدمه ببساطة كمثال على "كيف يمكن أن يكون":
public class MysteriousDevice extends Toster, NuclearBomb {

   public static void main(String[] args) {

       MysteriousDevice mysteriousDevice = new MysteriousDevice();
       mysteriousDevice.on(); // And what should happen here? Will we get a toast, or a nuclear apocalypse?
   }
}
دعونا نرى ما حصلنا عليه. الجهاز الغامض يأتي من المحمصة والقنبلة النووية. كلاهما لهما طريقة on()، ونتيجة لذلك، ليس من الواضح أي طريقة on()يجب أن تطلق النار على الكائن MysteriousDeviceإذا استدعيناه. لن يتمكن الكائن من فهم هذا. حسنًا، مثل حبة الكرز على الكعكة: القنبلة النووية ليس لها طريقة off()، لذلك إذا خمننا خطأ، فلن تكون هناك طريقة لإيقاف تشغيل الجهاز. دروس مجردة في جافا مع أمثلة ملموسة - 2 وبسبب هذا الارتباك بالتحديد، عندما لا يكون الكائن واضحًا ما هو السلوك الذي يجب عليه اختياره، فقد تخلى منشئو Java عن الميراث المتعدد. ومع ذلك، عليك أن تتذكر أن فئات Java تنفذ العديد من الواجهات. بالمناسبة، لقد واجهت بالفعل فصلًا تجريديًا واحدًا على الأقل في دراستك! على الرغم من أنني ربما لم ألاحظ ذلك :)
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
هذا هو صديقك القديم من الدرجة Calendar. إنها مجردة ولها عدة ورثة. واحد منهم هو GregorianCalendar. لقد استخدمته بالفعل في دروس حول التواريخ :) يبدو أن كل شيء واضح، ولم يتبق سوى نقطة واحدة: ما هو الفرق الأساسي بين الفئات المجردة والواجهات ؟ لماذا أضافوا كليهما إلى Java، ولم يقتصروا على واحد فقط؟ وهذا يمكن أن يكون كافيا. سنتحدث عن هذا في المحاضرة القادمة! أرك لاحقًا:)
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION