Абстрактный класс против интерфейса [дубликат]


этот вопрос уже есть ответ здесь:

  • Интерфейс против абстрактного класса (общий OO) 35 ответов

Я искал вокруг так же, как и остальная часть сети для хорошего ответа, но я не нашел тот, который я действительно понимаю. Я собираюсь представить это по-другому, и, надеюсь, ответы помогут и другим.

пожалуйста, посмотрите на два фрагмента кода и дайте мне пример того, что я могу сделать с каждым из моих примеров, которые заставили бы меня хотеть или не хотеть использовать другой.

Абстрактный Класс

abstract class Foo {
    abstract public function getValue();
    abstract public function setValue($value); 
}


class myObj extends Foo {
    function getValue() {

    }
    function setValue($value) {

    }
}

интерфейс

interface Foo {
    public function getValue();
    public function setValue($value);
}

class myObj implements Foo {
    function getValue() {

    }
    function setValue($value) {

    }
}
4 56

4 ответа:

чтобы возобновить идею (глобально, а не подробно):

inheritance

- это понятие extend from something, и при необходимости добавить некоторые новые функции или переопределить некоторые существующие функции (чтобы сделать по-другому). Но используя наследование, вы разделяете большую часть кода с родителем. вы родитель + некоторые другие вещи.

interface

представляет некоторые способности (мы говорим, что класс реализация интерфейс говорит, что он имеет такие способности). Взаимодействие может быть реализован двумя классами, которые совершенно разные и не разделяют их код (за исключением методов, которые они реализуют). Когда A и B реализуют интерфейс C, A не является B и B не является A.

и одна из причин interface действительно, чтобы позволить программисту делать то же самое, что они могли бы сделать с несколькими наследованиями, но без проблем с несколькими наследованиями.

это понятие используется в некоторых языках программирования, таких как JAVA, PHP...

Аннотация

абстрактные классы сосредоточены на подобии вещей.

люди считаются типа mammal и как таковой не будет считаться типа vehicle.

интерфейс

интерфейсы фокусируются на Сортировке аналогичной функции.

например: вы человек и принадлежите к типу mammal. Если вы хотите летать, то вам нужно реализовать flying Interface. Если вы хотите стрелять во время полета, то вам также нужно реализовать gun Interface.

смотрите примеры ниже:

abstract class Mammal {
      protected $age_;
      //below are functions I think all mammals will have,including people
      abstract public function setAge($age);
      abstract public function getAge();
      abstract public function eat($food);
}
class Person extends Mammal {
      protected $job_; //Person's feature
      public function setAge($age){
        $this->age_ = $age;
      }

      public function getAge(){
        return $this->age_;
      }

      public function eat($food){
        echo 'I eat ' ,$food ,'today';
      }

      //People only attribute
      public function setJob($job){
         $this->job_ = $job;
      }
      public function getJob(){
         echo 'My job is ' , $this->job_;
      }

}

//Now a person wants to fly, but they are typically not able to do so.
//So we implement an interface
interface Plane{
  public function Fly(); 
}

//I also want shoot enemy
interface Gun{
  public function shoot();
}

class Person2 extends Mammal implements Plane,Gun{

      protected $job_;//Person feature
      public function setAge($age){
        $this->age_ = $age;
      }
      public function getAge(){
        return $this->age_;
      }
      public function eat($food){
        echo '<br/>I eat ' ,$food ,' today<br/>';
      }
      //Only a person has this feature.
      public function setJob($job){
         $this->job_ = $job;
      }
      public function getJob(){
         echo 'My job is ' , $this->job_;
      }

      //-----------------------------------------
      //below implementations from interfaces function. (features that humans do not have).
      //Person implements from other class
      public function fly(){
        echo '<br/>I use plane,so I can fly<br/>';
      }
      public function shoot(){
        echo 'I use gun,so I can shoot<br/>';
      }
}

$People = new Person();
echo '<pre>';
print_r( get_class_methods('People'));
echo '</pre>';

echo '<pre>';
print_r( get_class_methods('People2'));
echo '</pre>';

$People2 = new Person2();
$People2->setAge(24);
echo $People2->getAge();
$People2->eat('egg');
$People2->setJob('PHP devepop');
echo $People2->getJob();

$People2->fly();
$People2->shoot();

коротко говоря, интерфейс заключается в стандартизации набора функций,в то время как абстрактный класс - это определение базового скелета для классов, производных от него.

Я думал об этом раньше, и лучшее, что я мог сделать, это то, что интерфейсы-это логически удобная абстракция чистого абстрактного класса (c++).

Что касается того, почему вы выбрали бы интерфейсы над абстрактными классами, я цитирую ( источник c++ но понятия те же):

обратите внимание, что существует большой соблазн добавить конкретные функции-члены и данные в чистые абстрактные базовые классы. Этому нужно сопротивляться, в вообще это признак того, что интерфейс не очень хорошо учитывается. Данные и конкретные функции-члены, как правило, подразумевают конкретную реализацию и как таковые могут наследовать от интерфейса, но не должны быть этим интерфейсом. Вместо этого, если существует некоторая общность между конкретными классами, хорошо работает создание абстрактного класса, который наследует свой интерфейс от чистого абстрактного класса и определяет общие данные и функции-члены конкретных классов.

дело в том, что когда используя интерфейсы, первое, что приходит на ум, это развязка. При использовании интерфейса пользователь и класс реализации полностью отделены друг от друга. То же самое относится и к тому, когда вы используете чисто абстрактный класс который в основном является интерфейсом.