CodeGym /مدونة جافا /Random-AR /أمثلة محددة للفئات المجردة في Java
John Squirrels
مستوى
San Francisco

أمثلة محددة للفئات المجردة في Java

نشرت في المجموعة
أهلاً! في الدروس السابقة، تعرفنا على الواجهات واكتشفنا الغرض منها. موضوع اليوم سوف يردد الموضوع السابق. دعونا نتحدث عن الطبقات المجردة في جافا. أمثلة محددة للفئات المجردة في Java - 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 is accelerating!");
   }

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

}
وهذا مشابه جدًا لما تحدثنا عنه في دروس الميراث. لكن في تلك الدروس، كان لدينا فصل دراسي عن السيارات ولم تكن أساليبه مجردة. لكن هذا الحل له عدد من العيوب التي تم إصلاحها في الفئات المجردة. أولاً وقبل كل شيء، لا يمكنك إنشاء مثيل لفئة مجردة :
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 fine. A car is created.
   }
}
الآن يحتوي برنامجنا على نوع من السيارات غير المفهومة - إنها ليست شاحنة، وليست سيارة سباق، وليست سيارة سيدان، ومن غير الواضح تمامًا ما هي. هذه هي "السيارة المجردة" التي لا وجود لها في الطبيعة. يمكننا تقديم نفس المثال باستخدام الحيوانات. تخيل لو Animalالطبقات ( الحيوانات المجردة ). من غير الواضح ما هو نوع هذا الحيوان، وما هي العائلة التي ينتمي إليها، وما هي الخصائص التي يتمتع بها. سيكون من الغريب أن نرى ذلك في برنامجك. لا توجد "حيوانات مجردة" في الطبيعة. فقط الكلاب والقطط والثعالب والشامات وما إلى ذلك. الطبقات المجردة تنقذنا من الأشياء المجردة. يعطوننا الحالة والسلوك الأساسيين. على سبيل المثال، يجب أن يكون لجميع السيارات طراز ولون وسرعة قصوى ، ويجب أن تكون قادرًا على استخدام البنزين والفرامل . هذا كل شيء. هذه خطة مجردة عامة. بعد ذلك تقوم بتصميم الفصول التي تحتاجها. ملاحظة: هناك طريقتان في فئة الملخص تم تصنيفهما أيضًا على أنهما مجردان ، وليس لهما أي تطبيق. السبب هو نفسه: لا تُنشئ الفئات المجردة سلوكًا افتراضيًا للسيارات المجردة. إنها تشير فقط إلى ما يجب أن تكون كل سيارة قادرة على فعله. ومع ذلك، إذا كنت بحاجة إلى السلوك الافتراضي، فيمكنك تنفيذ الأساليب في فئة مجردة. Java لا تحظر هذا:
public abstract class Car {

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

   public void gas() {
       System.out.println("Gas!");
   }

   public abstract void brake();

   // Getters and setters
}


public class Sedan extends Car {

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

}

public class Main {

   public static void main(String[] args) {

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

لماذا لا تحتوي Java على وراثة متعددة للفئات

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


 public void on() {

       System.out.println("The toaster is on. Toast is being prepared!");
   }

   public void off() {

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


public class NuclearBomb {

   public void on() {

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

   public static void main(String[] args) {

       MysteriousDevice mysteriousDevice = new MysteriousDevice();
       mysteriousDevice.on(); // So what should happen here? Do we get toast or a nuclear apocalypse?
   }
}
دعونا نلقي نظرة على ما لدينا. يرث الجهاز الغامض محمصة الخبز والقنبلة النووية في نفس الوقت. كلاهما لديه on()أساليب. ونتيجة لذلك، إذا قمنا باستدعاء on()الطريقة، فليس من الواضح أي منها يجب استدعاؤه على MysteriousDeviceالكائن. لا توجد طريقة يمكن أن يعرفها الكائن على الإطلاق. وفوق كل ذلك: لا تملك القنبلة النووية off()طريقة، لذلك إذا لم نقم بالتخمين بشكل صحيح، فسيكون من المستحيل تعطيل الجهاز. أمثلة محددة للفئات المجردة في Java - 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