اذهب إلى المحتوى

السؤال

نشر

أواجهة مشكلة في فهم الفرق بين الواجهة interface والصنف المجرد abstract class ومتى أستخدم كلًا منهما

ما هو الفرق الجوهري بين الواجهة interface والصنف المجرد abstract class؟ ومتى يجب أن أستخدم أحدهما بدلًا من الآخر؟

Recommended Posts

  • 0
نشر

الواجهات و الأصناف المجردة مختلفات في بعض الجزئيات:

  1. أنه لا يمكننا تعريف خواص properties ضمن الواجهات بينما في الأصناف يمكننا ذلك.
  2. جميع دوال الواجهات يجب أن تكون Public فيما دوال الأصناف المجردة من الممكن أن تكون public | protected
  3. جميع دوال الواجهات تكون Abstract أي لا يوجد جسم للدالة فقط تعريفها
  4. يمكن للواجهات الوراثة من أكثر من واجهة extends
  5. الأصناف يمكن أن تعمل implement لأكثر من واجهة و ترث صنف آخر واحد فقط

لكل نقطة من السابق سنضيف مثال:

  1. تعريف الخواص فقط ضمن الصنف المجرد
    <?php
    interface Animal {
      
        private sound = "Meow";   // خطأ
    
      public function makeSound();
    }
    
    abstruct class Cat implements Animal {
      protected sound = "Meow";      // صحيح
      public function makeSound() {
        echo $this.sound;
      }
    }

     

  2. دوال الواجهات عامة، أما الأصناف المجردة عامة أو محمية
    <?php
    interface Animal {
      
      public function makeSound();
      ^^^^^^ إجبارية
    }
    
    abstruct class Cat implements Animal {
      protected sound = "Meow";      // صحيح
      public function makeSound1() {
      ^^^^^^
        echo $this.sound;
      }
      protected function makeSound2() {
      ^^^^^^^^^
        echo $this.sound;
      }
    }

     

  3. نكتب الترويسة عند تعريف دالة في الواجهة و جسمها في الصنف
    <?php
    interface Animal {
      public function makeSound();   // ترويسة فقط
    }
    
    class Cat implements Animal {
      public function makeSound() {  // تعريف كامل
        echo "Meow";
      }
    }

     

  4. الوراثة المتعددة في الواجهات تستعمل الكلمة المفتاحية extends أما الصنف يحقق واجهة implements
    <?php 
    
    interface MyInterface1{
      public function method1();
    }
    
    interface MyInterface2{
      public function method2();
    }
    
    
    interface MyInterfaceName extends MyInterface1, MyInterface2{
    
    }
    
    class MyClassName implements MyInterfaceName{
    
      public function method1(){
        echo "Method1 Called" . "\n";
      }
    
      public function method2(){
        echo "Method2 Called". "\n";
      }
    } 
    
    $obj = new MyClassName;
    $obj->method1();
    $obj->method2();
    
    ?>

     

  5. يمكننا وراثة صنف واحد، وتطبيق عدة واجهات
    <?php
    
    // صنف عادي
    class A {
      public function insideA() {
          echo "I am in class A";
      }
    }
    // واجهة
    interface B {
    	public function insideB();
    }
    // واجهة
    
    interface C {
    	public function insideC();
    }
    
    class D extends A implements B,C {
    
      function insideB() {
        echo "I am in interface B";
      }
      function insideC() {
        echo "I am in interface C";
      }
    
      public function insideD() {
        echo "I am in inherited class";
      }
    }
    
    $hsoub = new D();
    $hsoub->insideA();
    $hsoub->insideB();
    $hsoub->insideC();
    $hsoub->insideD();
    ?>
    
    // output
    
    I am in class A
    I am in interface B
    I am in interface C
    I am in inherited D

     

 

  • 0
نشر

الأمر بسيط 

  1. Interface بيكون بداخله أكثر من methods و functions بيتم الاعتماد عليهم في أكثر من ملف كما يُرى في ملفات laravel انه ال controller بتعمل extends من global Interface، وبيتم من خلاله اخذ ال methods والتعامل معها. 
  2. Class بيتم فيه عمل methods مختلفه نستخدمها مره واحده في ملف واحد. 

  • 0
نشر

الواجهة interface والصنف المجرد Abstract Class متشابهين لحد كبير الفرق الوحيد بينهما هو احتواء الصف المجرد على تضمين فعلي للتوابع، بينما في الواجهة تكتفي بذكر شكل التوابع ومسؤولية وطريقى التضمين تقع على الصنف الذي يطبق تلك الواجهة

استخدام الواجهة

من حالات استخدام الواجهات interfaces

  • عند وجود أكثر من تضمين للتابع
    interface Logger {
     function log(string $); 
    }
    
    // عدة تضمينات للواجهة
    
    class DBLogger implements Logger {
      function log(string $){
        // تسجيل ضمن قاعدة البيانات
      }
    }
    
    class FileLogger implements Logger {
      function log(string $){
        // تسجيل ضمن الملفات
      }
    }

     

  • لتحقيق تعدد الأشكال Polymorphism
    interface Logger {...}
    interface Database {...}
    
    class MyClass implements Logger, Database {
      ...
    }
    
    class App{
     public __construct(Logger $logger, Database $database){
       ...
     }
    }
     
    // يمكن التعامل مع الصنف نفسه بأكثر من شكل
    new App(new MyClass(), new MyClass());

     

استخدام الصنف المجرد

استخدم الصنف المجرد:

  • لإعادة استخدام الشيفرة عند استخدام الوراثة
  • عند تطبيق نمط تصميم الاستراتيجية Strategy Design Pattern
abstract class BaseClass {
 abstract function calculate() {
   $data = $this->getData();
   ...
 }
 abstract function getData();
}

class MyClass extends BaseClass {

  function getData() {
    // نمط الاستراتيجية
    return ...
  }

  function myCalculate(){
    // إعادة استخدام الشيفرة
    $this->calculate();
  }
}

يمكنك الاستفادة من قراءة المقالات التالية يمكن تطبيق نفس الأفكار في أي لغة برمجة تدعم النمط كائني التوجه:

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...