Nid*_*pta 3 php oop abstract-class interface
抽象类可能有也可能没有抽象方法,但接口只有未实现的方法。那么,如果我的抽象类的所有方法都标记为抽象,那么使用接口的区别和优势是什么?
接口和抽象
使用的真正力量可以在具有大量类的巨大 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