关于php:抽象类与接口

Abstract Class vs. Interface

本问题已经有最佳答案,请猛点这里访问。

我在网上和其他地方搜索了一个很好的答案,但是我没有找到一个我真正理解的答案。我将以另一种方式呈现这个问题,希望答案也能帮助其他人。

据我所知,这两个概念都有相同的规则,只是抽象类由于方法实现的能力更灵活。另外,我知道您可以实现多个接口,并且只扩展一个类,但是我确信有比我提到的两个更大的区别。

请看这两段代码,并给我一个例子,我可以用我的每一个例子来做什么,这会使我想要或不想使用另一个。

抽象类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
abstract class Foo {
    abstract public function getValue();
    abstract public function setValue($value);
}


class myObj extends Foo {
    function getValue() {

    }
    function setValue($value) {

    }
}

界面

1
2
3
4
5
6
7
8
9
10
11
12
13
interface Foo {
    public function getValue();
    public function setValue($value);
}

class myObj implements Foo {
    function getValue() {

    }
    function setValue($value) {

    }
}


摘要

抽象类关注的是一种事物的相似性。

人们被认为是mammal型,因此不会被认为是vehicle型。

界面

接口集中于类似函数的排序。

例如:你是一个人类,属于mammal型。如果你想飞,那么你需要实现一个flying Interface。如果你想在飞行中射击,那么你还需要执行gun Interface

参见以下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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 '[cc lang="php"]';
print_r( get_class_methods('People'));
echo '

;回声"

1
2
3
';
print_r( get_class_methods('
People2'));
echo '

";$people2=新人员2();$people2->设置(24);echo$people2->getage();$people2->吃("蛋");$people2->setjob("php devepop");echo$people2->getjob();$people2->fly();$people2->shoot();< /代码>


要恢复这一想法(全球范围内,而不是详细说明):

1
inheritance

extend from something的概念,并且可以选择添加一些新特性或覆盖一些现有特性(以做不同的事情)。但是使用继承,您可以与父代码共享很大一部分代码。你是父母+其他一些事情。

1
interface

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

interface的一个原因确实是允许程序员在多继承的情况下做同样的事情,但是没有多继承问题。

这种概念用于一些编程语言,如Java、PHP…


简单地说,接口是标准化一组函数,而抽象类是定义类的基本框架来派生类。


我以前曾考虑过这个问题,最好的结论是接口是一个逻辑抽象的抽象抽象类(C++)。

至于为什么要在抽象类上选择接口,我引用(C++源,但概念是相同的):

Note that there is a great temptation to add concrete member functions and data to pure abstract base classes. This must be resisted, in general it is a sign that the interface is not well factored. Data and concrete member functions tend to imply a particular implementation and as such can inherit from the interface but should not be that interface. Instead if there is some commonality between concrete classes, creation of abstract class which inherits its interface from the pure abstract class and defines the common data and member functions of the concrete classes works well.

问题是,当使用接口时,首先想到的是去耦。当使用接口时,用户和实现类是完全分离的。这同样适用于使用纯抽象类(基本上是一个接口)的情况。