PHP OOP 部分组合与继承和依赖注入
在本系列中,我将介绍 PHP 面向对象编程 (OOP) 的基础知识。内容将被组织成连续的部分,每个部分都侧重于一个特定的主题。如果您是初学者或不熟悉 OOP 概念,本系列旨在逐步指导您。 在这一部分中,我将讨论 PHP 中的组合与继承和依赖注入。让我们一起开始学习PHP OOP的旅程吧!
组合与继承
我们已经了解了面向对象编程中父类和子类之间的关系,我们看到子类可以继承父类并访问父类的所有内容。这就是所谓的继承。
另一方面,组合是指将父类分配为子类中的属性值,而不是继承它。通过这个,我们可以访问父类的所有内容。这称为组合。
下面是说明组合和继承的示例。
代码示例
class Link { public string $name; public string $type; public function create($name, $type) { $this->name = $name; $this->type = $type; } public function show() { echo "name: $this->name, type: $this->type"; } } // Inheritance example class ShoLink extends Link { // other functionalities } // Composition example class User { public Link $link; public function __construct() { $this->link = new Link(); } // other functionalities } $user = new User(); $user->link->create("Jamir", "Short");
在第一个示例中,我们可以看到 ShoLink 类继承了 Link 类。另一方面,在第二个示例中,User 类没有继承 Link 类。相反,它将 Link 类的一个实例分配给它的属性之一。因此,我们可以访问两个子类中 Link 类的所有内容。
现在可能会出现一个问题:如果我们已经可以通过继承来访问所有内容,为什么还要使用组合呢?毕竟,对于组合,我们需要声明一个附加属性并通过构造设置其值。这看起来像是额外的工作——那么使用组合有什么好处呢?
嗯,我们知道继承使得父类中的所有内容都可以在子类中访问。因此,即使我们不想使用父类的某些方法,或者子类中不需要父类的某些属性或方法,如果它们是公共或受保护成员,它们仍然可以在子类中访问.
为了解决这个问题,使用了组合。通过组合,我们可以只让子类可以访问父类所需的部分。让我们用另一个例子进一步阐明这一点。
如果我们仔细观察 Link 类,我们可以看到它有一个 show 方法。使用这个方法,我们可以直接显示ShoLink类中创建的链接。
但是,如果我们希望 User 类阻止任何人直接查看为用户创建的链接怎么办?相反,我们可能希望在用户的个人资料旁边显示用户的链接。
这就是为什么在 User 类中,我们不是继承 Link 类,而是通过组合来访问它。这样一来,没有人可以通过 User 类直接查看用户的链接,但可以直接查看 ShoLink 类的链接。
优先考虑组合而不是继承
现在我们对组合以及何时使用组合而不是继承来解决某些问题有了一些了解。在OOP中,有一个原则叫做“Favor Composition over Inheritance”,意思是组合优先于继承。换句话说,对于不需要从父类访问所有内容的子类,我们应该始终优先选择组合而不是继承。
现在问题来了:我们如何决定何时使用组合以及何时使用继承?
在这种情况下,我们需要根据两种类型的关系做出决定:
- 是一个->关系。如果关系是“is a”,我们应该使用继承。
- 有一个->关系。如果关系是“有一个”,我们应该使用组合。
代码示例
class Link { public string $name; public string $type; public function create($name, $type) { $this->name = $name; $this->type = $type; } public function show() { echo "name: $this->name, type: $this->type"; } } // Inheritance example class ShoLink extends Link { // other functionalities } // Composition example class User { public Link $link; public function __construct() { $this->link = new Link(); } // other functionalities } $user = new User(); $user->link->create("Jamir", "Short");
如果您查看上面 ShoLink 类的示例,您会发现 ShoLink 类继承自 Link 类。因此,如果我要定义它们之间的关系,则该关系将是 ShoLink 是链接,因为 ShoLink 本质上是链接的一种类型。
代码示例
// Inheritance example class ShoLink extends Link { // other functionalities }
现在,如果我们看一下上面 User 类的示例,我们可以看到 User 类与 Link 类使用组合。因此,如果我要定义它们之间的关系,则该关系将是“用户拥有链接”,因为用户不是链接,但用户可以拥有链接或可能拥有链接。
我希望您现在对组合和继承有了更清晰的了解,包括何时使用每一项以及在不同情况下优先考虑哪一项。
依赖注入
在了解依赖注入之前,我们首先需要了解什么是依赖。依赖是指子类通过继承或组合使用另一个类的成员。在这种情况下,父类将成为子类的依赖项。
在上面的例子中,我们看到当我们使用组合而不是继承时,我们需要在子类中声明一个属性,并通过构造函数将父类的实例分配给该属性。因此,如果我们要使用User类,就必须在其构造函数中实例化Link类,因为User类依赖于Link类。换句话说,Link 类是 User 类的依赖项。这里的问题是 Link 类的实例化过程与 User 类紧密耦合。
问题在于 Link 类的实例化是有限的并且特定于 User 类。如果我们想将任何其他类而不是 Link 类从外部传递到 User 类中,我们就不能这样做,因为我们在构造函数中显式创建 Link 类的实例并将其分配给 Link 属性。这称为紧耦合依赖关系,意味着我们无法从外部更改此依赖关系。
但是,如果我们不在构造函数中自己实例化 Link 类,而是将其留给用户,这意味着当用户使用我们的 User 类时,他们会将 Link 类依赖项传递给 User 类,我们的问题将是解决了。
让我们看一下下面的代码示例。
代码示例
class Link { public string $name; public string $type; public function create($name, $type) { $this->name = $name; $this->type = $type; } public function show() { echo "name: $this->name, type: $this->type"; } } // Inheritance example class ShoLink extends Link { // other functionalities } // Composition example class User { public Link $link; public function __construct() { $this->link = new Link(); } // other functionalities } $user = new User(); $user->link->create("Jamir", "Short");
在此示例中,我们可以看到,我们不是在 User 类的构造函数中实例化 Link 类,而是从外部将 Link 类的依赖项传递到 User 类中。这种通过用户将依赖项传递到 User 类的过程称为依赖项注入。换句话说,我们从外部注入或推送 Link 类的依赖项。这称为松耦合依赖关系,这意味着我们可以轻松地从外部更改此依赖关系。
现在,如果 Link 类也有自己的依赖项,我们也可以通过 User 类从外部将这些依赖项注入到它中。然后,我们可以简单地将 Link 类的实例注入到 User 类中。因此,我们不需要担心 Link 类在 User 类中的依赖关系,因为用户将从外部处理它。
让我们看一下下面的代码示例。
代码示例
// Inheritance example class ShoLink extends Link { // other functionalities }
这样我们就可以从外部注入任意数量的依赖,而且会灵活很多。这就是今天的全部内容;我们下节课再讲。
您可以在 GitHub 和 Linkedin 上与我联系。
以上是PHP OOP 部分组合与继承和依赖注入的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JWT是一种基于JSON的开放标准,用于在各方之间安全地传输信息,主要用于身份验证和信息交换。1.JWT由Header、Payload和Signature三部分组成。2.JWT的工作原理包括生成JWT、验证JWT和解析Payload三个步骤。3.在PHP中使用JWT进行身份验证时,可以生成和验证JWT,并在高级用法中包含用户角色和权限信息。4.常见错误包括签名验证失败、令牌过期和Payload过大,调试技巧包括使用调试工具和日志记录。5.性能优化和最佳实践包括使用合适的签名算法、合理设置有效期、

PHP8.1中的枚举功能通过定义命名常量增强了代码的清晰度和类型安全性。1)枚举可以是整数、字符串或对象,提高了代码可读性和类型安全性。2)枚举基于类,支持面向对象特性,如遍历和反射。3)枚举可用于比较和赋值,确保类型安全。4)枚举支持添加方法,实现复杂逻辑。5)严格类型检查和错误处理可避免常见错误。6)枚举减少魔法值,提升可维护性,但需注意性能优化。

会话劫持可以通过以下步骤实现:1.获取会话ID,2.使用会话ID,3.保持会话活跃。在PHP中防范会话劫持的方法包括:1.使用session_regenerate_id()函数重新生成会话ID,2.通过数据库存储会话数据,3.确保所有会话数据通过HTTPS传输。

SOLID原则在PHP开发中的应用包括:1.单一职责原则(SRP):每个类只负责一个功能。2.开闭原则(OCP):通过扩展而非修改实现变化。3.里氏替换原则(LSP):子类可替换基类而不影响程序正确性。4.接口隔离原则(ISP):使用细粒度接口避免依赖不使用的方法。5.依赖倒置原则(DIP):高低层次模块都依赖于抽象,通过依赖注入实现。

静态绑定(static::)在PHP中实现晚期静态绑定(LSB),允许在静态上下文中引用调用类而非定义类。1)解析过程在运行时进行,2)在继承关系中向上查找调用类,3)可能带来性能开销。

RESTAPI设计原则包括资源定义、URI设计、HTTP方法使用、状态码使用、版本控制和HATEOAS。1.资源应使用名词表示并保持层次结构。2.HTTP方法应符合其语义,如GET用于获取资源。3.状态码应正确使用,如404表示资源不存在。4.版本控制可通过URI或头部实现。5.HATEOAS通过响应中的链接引导客户端操作。

在PHP中,异常处理通过try,catch,finally,和throw关键字实现。1)try块包围可能抛出异常的代码;2)catch块处理异常;3)finally块确保代码始终执行;4)throw用于手动抛出异常。这些机制帮助提升代码的健壮性和可维护性。

匿名类在PHP中的主要作用是创建一次性使用的对象。1.匿名类允许在代码中直接定义没有名字的类,适用于临时需求。2.它们可以继承类或实现接口,增加灵活性。3.使用时需注意性能和代码可读性,避免重复定义相同的匿名类。
