php 抽象类与接口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15960729/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 10:15:41  来源:igfitidea点击:

Abstract Class vs. Interface

phpinterfaceabstract-classconceptual

提问by nathanjosiah

I have searched around SO as well as the rest of the web for a good answer but I have't found one that I really understand. I am going to present this in a different way and hopefully the answers will help others as well.

我已经在 SO 以及网络的其他部分搜索了一个很好的答案,但我还没有找到一个我真正理解的答案。我将以不同的方式呈现这个,希望答案也能帮助其他人。

As far as I understand, the two concepts have the same rules except an abstract class is more flexible due to the method implementation ability. Also, I am aware you can implement multiple interfaces and only extend a single class but I'm sure there are more differences than the two I mentioned.

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

Please look at the two snippets of code and give me an example what I can do with each of my examples that would make me want or not want to use the other.

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

Abstract Class

抽象类

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


class myObj extends Foo {
    function getValue() {

    }
    function setValue($value) {

    }
}

Interface

界面

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

class myObj implements Foo {
    function getValue() {

    }
    function setValue($value) {

    }
}

采纳答案by MatRt

To resume the idea (globally, not in detail):

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

inheritance

is the notion to extend from something, and optionally add some new feature or override some existing feature (to do differently). But using inheritance, you share a big part of code with the parent. You area parent + some other things.

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

interface

is representing some abilities (we says a class is implementingan interface to says that it has these abilities). An interface can be implemented by 2 classes which are completely different and do not share their code (except for methods they implements). When A and B are implementing interface C, A is not a B and B is not a A.

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

And one of the reason for interfaceis indeed to allow programmer to do the same as they could do with multi-inheritance, but without multi-inheritance problems.

原因之一interface确实是让程序员可以像使用多继承一样做,但没有多继承问题。

This notion is used in some programming languages like JAVA, PHP...

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

回答by Liuqing Hu

Abstract

抽象的

Abstract Classes focus on a kind of things similarity.

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

People are considered of type mammaland as such would not be considered of type vehicle.

人们被视为类型mammal,因此不会被视为类型vehicle

Interface

界面

Interfaces focus on collation of similar function.

接口侧重于类似功能的整理。

For example: You are a human being and are of type mammal. If you want to fly then you will need to implement a flying Interface. If you want to shoot while flying, then you also need to implement the gun Interface.

例如:你是一个人,属于 类型mammal。如果你想飞,那么你需要实现一个flying Interface. 如果您想在飞行时拍摄,那么您还需要实现gun Interface.

See the examples below:

请参阅以下示例:

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();

回答by MatRt

Briefly speaking, interfaceis to standardize a set of functions,while abstract classis to define a basic skeleton for classes to derive from.

简而言之,接口是标准化一组功能,而抽象类是定义一个基本的框架,供类派生。

回答by Mohamed Tarek

I have thought about this before, and the best I could conclude was that interfaces are a logically convenient abstraction of a pure abstract class(c++).

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

As for why you would choose interfaces over abstract classes, I quote (a c++ sourcebut the concepts are the same):

至于为什么选择接口而不是抽象类,我引用(一个 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.

请注意,将具体成员函数和数据添加到纯抽象基类中存在很大的诱惑。这必须被抵制,通常这是接口没有很好地分解的迹象。数据和具体的成员函数往往意味着一个特定的实现,因此可以从接口继承,但不应该是那个接口。相反,如果具体类之间存在一些共性,那么创建从纯抽象类继承其接口并定义具体类的公共数据和成员函数的抽象类会很好地工作。

The thing is, when using interfaces, the first thing that comes to mind is decoupling. When using an interface, the user and the implementing-class are totally decoupled. The same applies for when you're using a pure abstract classwhich is basically an interface.

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