PHP - 如果抽象类中的所有方法都是抽象的,那么接口和抽象类之间有什么区别

Nid*_*pta 3 php oop abstract-class interface

抽象类可能有也可能没有抽象方法,但接口只有未实现的方法。那么,如果我的抽象类的所有方法都标记为抽象,那么使用接口的区别和优势是什么?

Thi*_*ous 5

接口和抽象
使用的真正力量可以在具有大量类的巨大 API 中体现出来,这些类遵循精心设计的灵活结构以供将来编码。不管它是否会发生——你永远不知道代码是否会被扩展。接口仅用于语义原因。想象一下,您扩展了 API 的弃用版本,并且有工作来编辑/更改/实施/更新/改进/扩展/修改代码以使其保持最新,无论原因是什么。如果你不提前考虑,你最终会感到沮丧。

可以在没有接口的情况下制作小型 API,而这正是大多数人认为不需要接口的地方。但是一旦它们变大,它们就会失去灵活性。他们为您提供了一份课程合同,提醒您需要什么并保持概览。接口必须有公共方法,如果您有受保护或私有的方法,只需在实现了接口的类的公共方法中返回它们即可。

就像您已经解释过的那样,接口需要实现特定的方法,抽象类不需要它,因为无论如何您很可能会扩展它们。方法可以重新定义,抽象方法必须在子类中定义。接口中提到的方法只告诉您与接口有契约的类必须定义这些。它可能是多个接口,您不会像使用抽象类那样从它们继承。

以这种方式思考
其中的逻辑是预测您计划构建的未来。无论是建筑、基础设施还是工厂的大规模生产。就像您对文件夹中的书签、书籍、图像等项目进行排序的方式一样。因为您知道如果不对其进行排序,查找特定图像将花费更长的时间。抽象和接口的语义目的是相似的,尤其是在庞大的 API 中。

  • 一个界面代表了一个可能性和要求的框架。
  • 抽象保留与派生上下文相关的概念信息。

我将向您展示一个典型的 API 结构,其中包含简化的内容,其中接口和抽象类具有用于未来扩展的实际使用点。

/* Considering, this project will be widely expanded up to huge complexity. 
   This is a flexible base structure, for developers working in team. Imagine 
   there could be lots more variation of styles for certain purposes. */


// OOP STRUCT
// You might want to define multiple interfaces to separate the project
interface iString {
    // These methods MUST be defined or else the developer receives an error
    public function getContent();
    public function description($desc);
}

/* Devs might want to add an additional method later on. 
   Traits are useful for quick use. (optional) */

trait desc {

    private $desc;

    public function description($desc) {
        return $this->desc;
    }
}


/* This is the base class for the content which requires a declaration 
   of methods being described in the interface */

class contents implements iString {

    use desc; // use the method defined in a trait
    private $str;

    public function __construct($str) {
        $this->str = $str;
    }

    public function getContent() {
        return $this->str;
    }
}


/* Or devs often consider abstract classes as the real base of the whole project/app.
   Abstract classes allow the use of methods that can be modified/declared for further use in derived classes.
   Interfaces can't do that */

abstract class stylize {

    private $str;

    // This typehint below makes sure that this value is assigned on interface
    public function __construct(iString $str) { 
        $this->str = $str;
    }

    public function style() {
        return $this->str->getContent();
    }

    abstract public function getContent();
}


// EXTENDED CLASSES 
class bold extends stylize {
    // Extended classes have to define abstract methods inherited from an abstract class. Non-abstract methods are not needed.
    public function getContent() {
        return "<strong>".parent::style()."</strong>";
    }
}

class underline extends stylize {

    public function getContent() {
        return "<u>".parent::style()."</u>";
    }
}

class upperCase extends stylize {

    public function getContent() {
        return strtoupper(parent::style());
    }
}


// PROCEDUAL OUTPUT

// A tiny shortcut
$e = function($desc,$str) { echo $desc.": ".$str->getContent()."<br>"; };

// Content being used
$content = new contents('Hello World.');
$e("Normal",$content);

// Content being styled
$bold = new bold($content);
$underline = new underline($content);
$upper = new upperCase($content);

// Renders content with styles        
$e("Bold",$bold);
$e("Underline",$underline);
$e("Uppercase",$upper);
Run Code Online (Sandbox Code Playgroud)

结论 以
应用文本内容的样式为例,可能不够吸引人。但除此之外,它保持不变——如果它做了它应该做的,那么它就完成了。就像我将构建一个可扩展的电子邮件配置 API 作为 CMS 的模块一样。这种结构在适当的编码中具有语义过程。

Tipps
我建议你继续学习这种模式的小项目,即使你认为接口不值得。继续这样做,直到你把它放进去。我个人给你的建议:如果你认为你不知道从哪里开始,不知道要尝试什么项目,那么尝试真实世界的例子,只需遵循以下逻辑:

车辆(抽象类)
-> 法拉利(扩展级)
-> 卡车(扩展类)

都有轮子(财产)
两者都必须能够驾驶(方法)

他们在街道上进行 1 英里比赛(抽象方法)

一个是slowpoke(扩展属性)
一个是红色一个是蓝色(扩展属性)

后来第三个来了,它是一列火车(扩展班)

谁会赢(某种方法)

实例化所有车辆并保持对接口和 
抽象。
……像这样的……

通常,包含巨大主体的类应该在单个文件中分开 + 包含这些 + 定义一个命名空间。否则代码墙会让您或其他人感到疲倦。使用Eclipse,这是维护 OOP 的最佳应用程序。

此外,如果它适合您的项目,如果您有Linux Ubuntu,请使用phUML。如果您有很多相关的类,它会为您当前的构建生成一个图形图表。

在此处输入图片说明

phUML 是 PHP 中基于 UML 的 API。它是一个开源项目,可以为几乎所有流行的编程语言生成任何可视化方案。我经常使用它,不仅仅是用于 PHP。只需在Github 上克隆它或从dasunhegoda.com下载并按照那里的安装指南进行操作。
您也可能对此感兴趣:Typehinting on Interfaces