代码之家  ›  专栏  ›  技术社区  ›  FlyingCat

php中抽象和接口的区别是什么?[副本]

  •  6
  • FlyingCat  · 技术社区  · 14 年前


    PHP: What is the difference between an interface and abstract class?

    6 回复  |  直到 4 年前
        1
  •  12
  •   Piskvor left the building Rohit Kumar    14 年前

    这些差异既有理论上的,也有实践上的:

    • 能力 您的类具有和播发(因此实现相同接口的各种类可以以相同的方式使用)
    • 抽象类可以是 实现,包含可能出现在所有实现中的部分。它不必实现完整的接口

    示例-接口:

    // define what any class implementing this must be capable of
    interface IRetrieveData {
        // retrieve the resource
        function fetch($url);
    
        // get the result of the retrieval (true on success, false otherwise)
        function getOperationResult();
    
        // what is this class called?
        function getMyClassName();
    }
    

    现在我们有了一系列的需求,这些需求将针对实现此功能的每个类进行检查。让我们创建一个抽象类及其子类:

    // define default behavior for the children of this class
    abstract class AbstractRetriever implements IRetrieveData {
        protected $result = false;
    
        // define here, so we don't need to define this in every implementation
        function getResult() {
           return $result;
        }
    
        // note we're not implementing the other two methods,
        // as this will be very different for each class.
    }
    
    class CurlRetriever extends AbstractRetriever {
         function fetch($url) {
             // (setup, config etc...)
             $out = curl_execute();
             $this->result = !(curl_error());
             return $out;
         }
         function getMyClassName() {
             return 'CurlRetriever is my name!';
         }
    }
    
    class PhpRetriever extends AbstractRetriever {
         function fetch($url) {
            $out = file_get_contents($url);
            $this->result = ($out !== FALSE);
            return $out;
         }
         function getMyClassName() {
             return 'PhpRetriever';
         }
    }
    

    一个完全不同的抽象类(与接口无关),其子类实现了我们的接口:

    abstract class AbstractDog {
         function bark() {
             return 'Woof!'; 
         }
    }
    
    class GoldenRetriever extends AbstractDog implements IRetrieveData {
         // this class has a completely different implementation
         // than AbstractRetriever
         // so it doesn't make sense to extend AbstractRetriever
         // however, we need to implement all the methods of the interface
         private $hasFetched = false;
    
         function getResult() {
             return $this->hasFetched;
         }
    
         function fetch($url) {
             // (some retrieval code etc...)
             $this->hasFetched = true;
             return $response;
         }
         function getMyClassName() {
             return parent::bark();
         }
    }
    

    function getStuff(IRetrieveData $retriever, $url) {
        $stuff = $retriever->fetch($url);
    }
    

    我们不必担心哪种检索器(cURL、PHP或Golden)会被传入,以及它们将如何实现目标,因为所有的检索器都应该具有相似的行为。你也可以用一个抽象类来实现这一点,但是你要根据类的祖先而不是它的能力来限制自己。

        2
  •  6
  •   laurent    12 年前

    多重继承与单一继承:

    实施:

    • 接口只定义公共成员函数。实现相同接口的类实际上并不共享代码。

    这是我脑子里想的。

        3
  •  2
  •   user151841 zhanxw    14 年前

    . 还没做完,你还得做完。因此,当您创建一个扩展抽象类的类时,您只是完成了从抽象类开始的工作。这也是为什么你不能实例化一个抽象类的原因;如果你把它抽象了,说明它是不完整的。它仍然需要一些额外的功能。

    一个接口只保证某些方法(每个方法都有一定数量的参数)必须存在于实现它的类中。因此,以后,使用实现特定接口的类的程序员可以放心,他们可以调用该类上的某些方法。

        5
  •  1
  •   js1568    14 年前

    下面是对两者区别的一个很好的描述:

    http://www.supertom.com/code/php_abstracts_and_interfaces.html

    这一切归结为这样一个事实:extends是一个“is-a”关系,而implements是一个“has-a”关系。

        6
  •  1
  •   Community CDub    7 年前
    "An Abstract Class can contain default Implementation, where as an 
    Interface should not contain any implementation at all. "
    

    至于在实际应用中使用什么。。。归根结底,这取决于上下文。

    question on here the other day about implementing a game using PHP . 在这里,他们有一个抽象类定义了一个怪物,任何怪物都可以基于这个抽象类。这允许继承默认的怪物属性。

    而对于一个接口,您定义的是一种“接口”方法的一般要求(请原谅在解释中使用这个术语)。我最近做的一个项目就是一个例子。我在php中实现了一个soapclient,以便与来自第三方的soapserver进行交互。这个接口定义了服务器支持哪些soap方法,因此实现我的接口的任何类都必须定义这些方法。