在 PHP 中,"抽象类" 和 "接口" 有什么区别?

26 浏览
0 Comments

在 PHP 中,"抽象类" 和 "接口" 有什么区别?

这个问题已有答案:

可能重复:

PHP:接口和抽象类之间有什么区别?

据我所知,一个类实现或扩展抽象或接口类必须使用默认方法。我知道我们可以使用实现关键字来使用多个接口,但我们只能扩展1个抽象类。 在实际项目中使用哪一个,有什么区别?

admin 更改状态以发布 2023年5月24日
0
0 Comments

多重继承和单一继承:

  • 你只能从一个抽象类继承。
  • 你可以实现多个接口。

实现:

  • 抽象类可以实际上拥有代码实现。这让你可以在子类之间共享实现。
  • 接口只定义公共成员函数。实现相同接口的类实际上没有共享代码。

以上是我头脑中所知道的。

0
0 Comments

接口和抽象类的差异既有理论的,也有实际的:

  • 接口是对类所具有和广告的某些能力的描述(因此,实现相同接口的各种类可以用相同的方式)。
  • 抽象类可以是默认实现,包含可能出现在所有实现中的部分,它不需要实现完整的接口。

例如-一个接口:

// 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)将被传递,并且它们将如何完成目标,因为所有检索器都应该能够表现出类似的行为方式。您也可以使用抽象类来实现此操作,但是这会基于类祖先而限制自己,而不是其能力。

0