抽象类与接口

时间:2013-04-11 23:40:22

标签: php interface abstract-class conceptual

我搜索了SO以及网络的其他部分以获得一个好的答案,但我找不到一个我真正理解的内容。我将以不同的方式呈现这一点,希望答案也能帮助其他人。

据我所知,这两个概念具有相同的规则,但由于方法实现能力,抽象类更灵活。另外,我知道你可以实现多个接口,只扩展一个类,但我确信与我提到的两个接口有更多不同。

请查看代码的两个片段,并举例说明我可以对我的每个示例做些什么,这些示例会让我想要或不想使用另一个。

抽象类

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 个答案:

答案 0 :(得分:148)

摘要

摘要课程侧重于一种事物的相似性。

人们被视为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();

答案 1 :(得分:29)

要恢复这个想法(全球,不详细):

inheritance

extend from something的概念,可选择添加一些新功能或覆盖某些现有功能(以不同方式执行)。但是使用继承,您可以与父代共享大部分代码。 父母+其他一些事情。

interface

表示一些能力(我们说一个类是实现一个接口,表示它具有这些能力)。接口可以由2个类实现,这两个类完全不同并且不共享它们的代码(它们实现的方法除外)。当A和B实现接口C时,A不是B而B不是A。

interface的原因之一确实是允许程序员像处理多继承那样做,但没有多继承问题。

这个概念用于一些编程语言,如JAVA,PHP ......

答案 2 :(得分:22)

简而言之,接口是标准化一组函数,而抽象类是为要派生的类定义基本框架。

答案 3 :(得分:3)

我之前已经考虑过这个问题,我能得出的最好的结论是接口是纯抽象类(c ++)的逻辑上方便的抽象。

至于为什么你会选择接口而不是抽象类,我引用(a c++ source,但概念是相同的):

  

请注意,将具体成员函数和数据添加到纯抽象基类有很大的诱惑力。这必须被抵制,一般来说,这表明界面没有很好的分解。数据和具体成员函数倾向于暗示特定的实现,因此可以从接口继承但不应该是该接口。相反,如果具体类之间存在某种共性,那么从纯抽象类继承其接口并定义具体类的公共数据和成员函数的抽象类的创建效果很好。

问题是,当使用接口时,首先想到的是解耦。使用接口时,用户和实现类完全分离。当您使用基本上是接口的纯抽象类时,同样适用。