web-dev-qa-db-ja.com

抽象クラスとインターフェース

SOおよびその他のWebを検索して適切な答えを探しましたが、実際に理解しているものは見つかりませんでした。答えは他の人にも役立ちます。

私の知る限り、2つの概念には同じ規則がありますが、メソッドの実装機能により抽象クラスがより柔軟である点が異なります。また、複数のインターフェイスを実装し、単一のクラスのみを拡張できることは承知していますが、前述した2つよりも多くの違いがあると確信しています。

コードの2つのスニペットを見て、他のサンプルを使用したい、または使用したくない各サンプルでできることを例を示してください。

抽象クラス

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) {

    }
}
57
nathanjosiah

アイデアを再開するには(グローバルで、詳細ではありません):

inheritance

extend from somethingの概念であり、オプションで新しい機能を追加したり、既存の機能を上書きしたりします(異なる方法で)。ただし、継承を使用すると、コードの大部分を親と共有できます。 You are親+その他.

interface

はいくつかの能力を表しています(クラスはimplementingと言います)インターフェイスは、完全に異なり、コードを共有しない2つのクラスによって実装できます(実装するメソッドを除く)。 AとBがインターフェースCを実装している場合、AはBではなく、BはAではありません。

そして、interfaceの理由の1つは、プログラマーが多重継承でできることと同じことをできるようにすることですが、多重継承の問題はありません。

この概念は、Java、PHPなどの一部のプログラミング言語で使用されます...

29
MatRt

要約

抽象クラスは、類似性のようなものに焦点を当てています。

人々は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();
148
Liuqing Hu

簡単に言えば、インターフェイスは一連の関数を標準化することであり、抽象クラ​​スは派生するクラスの基本的なスケルトンを定義することです。

22
user655000

これについては以前考えていましたが、インターフェイスは、純粋な抽象クラスの論理的に便利な抽象化であると結論付けられました(c ++)。

抽象クラスよりもインターフェースを選択する理由については、引用します( c ++ソース ですが、概念は同じです):

具体的なメンバー関数とデータを純粋な抽象基本クラスに追加したいという誘惑があることに注意してください。これは抵抗する必要があります。一般的には、インターフェイスが十分にファクタリングされていないことを示しています。データおよび具象メンバー関数は、特定の実装を暗示する傾向があるため、インターフェースから継承できますが、そのインターフェースであってはなりません。代わりに、具象クラス間に何らかの共通性がある場合、そのインターフェースを純粋な抽象クラスから継承し、具象クラスの共通データとメンバー関数を定義する抽象クラスの作成がうまく機能します。

問題は、インターフェイスを使用する場合、最初に頭に浮かぶのはdecoupleです。インターフェイスを使用する場合、ユーザーと実装クラスは完全に分離されます。 純粋な抽象クラスを使用している場合も同様です。これは基本的にインターフェースです。

3
Mohamed Tarek