在本系列中,我将介绍 PHP 面向对象编程 (OOP) 的基础知识。内容将被组织成连续的部分,每个部分都侧重于一个特定的主题。如果您是初学者或不熟悉 OOP 概念,本系列旨在逐步指导您。 在这一部分中,我将讨论 PHP 中的抽象和接口。让我们一起开始学习PHP OOP的旅程吧!
我们知道,在面向对象编程中,抽象是一个重要的概念。那么,什么是抽象呢?抽象是指隐藏程序的实现细节,仅显示其功能。
现在,让我们尝试了解 PHP 中的抽象是如何工作的。首先,我们看一个简单的例子,其中有一个父类,一个或多个子类将从该父类继承。之后,我们将讨论这种方法的缺点。
class Vehicle { public function getBaseFare() { // implementation } public function getPerKiloFare() { // implementation } public function getTotalFare() { // implementation } } class Car extends Vehicle { // Car implementation } class Bike extends Vehicle { // Bike implementation }
在这里我们可以看到Vehicle类被Car和Bike类继承。因此,这两个类都可以访问 Vehicle 类中存在的方法。但是,有一个问题:父类中的方法带有其实现,子类继承了这些实现。这意味着所有子类将共享一个公共实现并以相同的方式运行。但情况不应该是这样,因为汽车的行为应该与自行车的行为不同。但是,由于我们从父类继承了这些方法,因此两个类的行为方式相同。
现在,如果在继承这些通用方法之后,我们希望它们对每个类有不同的行为,该怎么办?
为了解决这个问题,PHP 提供了 Abstract 类。什么是抽象类?
抽象类是一种可以同时具有抽象方法和非抽象方法的类。那么,什么是抽象方法和非抽象方法?
抽象方法是只有定义而没有实现的方法。因此,当子类继承父类时,它必须提供父类抽象方法的实现。
非抽象方法是在父类中同时具有定义和实现的方法。子类只需继承这些方法并可以使用它们。
现在,我们将尝试使用抽象类来解决上述问题。
class Vehicle { public function getBaseFare() { // implementation } public function getPerKiloFare() { // implementation } public function getTotalFare() { // implementation } } class Car extends Vehicle { // Car implementation } class Bike extends Vehicle { // Bike implementation }
在这里我们可以看到有一个名为Vehicle的类。如果我们想让一个类抽象,我们需要在类名前使用abstract关键字。因此,Vehicle类是一个抽象类。同样,如果我们想在抽象类中创建一个方法,我们需要在方法名前使用abstract关键字。需要注意的是,如果我们想让类的任何成员成为抽象类,那么该类也必须是抽象类。
现在,从Vehicle类继承的抽象方法在每个子类中都有不同的实现。因此,这些方法的行为会有所不同,并为每个子类提供不同的结果。
现在,我们可能想知道为什么我们必须在父类中抽象方法 getBaseFare 和 getPerKiloFare,而我们可以简单地直接在子类中实现它们。
如果您仔细观察,您会注意到在父类中,方法 getBaseFare 和 getPerKiloFare 在另一个方法中使用。但是,如果我们没有抽象 getBaseFare 和 getPerKiloFare 并且仅在子类中实现它们,我们将无法在父类中访问它们。因此,需要被父类和子类访问,并且其行为在每个子类中应该不同的方法被抽象出来。
需要注意的是,抽象类不能直接实例化。而是通过子类来访问,并且从抽象类继承的抽象方法必须在子类中实现。如果不这样做,子类中的任何内容都将不起作用。我希望这能让您更好地理解如何使用抽象类。
在前面的讨论中,我们讨论了抽象类。由此我们知道,当从抽象类继承抽象方法时,这些方法必须在子类中实现;否则,子类中的任何内容都将不起作用。
但是,如果在子类中不需要其中一个抽象方法,但仍然需要实现它怎么办?这不会是一个好的解决方案。那么,这种情况我们能做什么呢?
在这种情况下,我们可以使用接口。接口类似于抽象类,但抽象类并不完全抽象,因为众所周知,抽象类可以同时拥有抽象和非抽象成员。
另一方面,接口只能有抽象成员。因此,接口被认为是完全抽象的类。现在,我们将尝试使用接口来解决上述问题。
class Vehicle { public function getBaseFare() { // implementation } public function getPerKiloFare() { // implementation } public function getTotalFare() { // implementation } } class Car extends Vehicle { // Car implementation } class Bike extends Vehicle { // Bike implementation }
在界面中,我们看到 getHourlyRate 函数的声明。然后,在Car类中,我们使用(实现或继承)这个接口并提供接口内部抽象方法的实现。但是,在 Bike 类中,我们不必实现此方法,因为我们没有在 Bike 类中使用(实现或继承)该接口。但是,如果这个抽象方法位于抽象类中,我们将被迫在两个子类中实现这个方法,即使不需要它,这也会导致糟糕的设计。此外,接口还有各种其他用例。
我希望这一集能让您对所讨论的主题有基本的了解。这就是今天的全部内容。我们下节课再讲。
您可以在 GitHub 和 Linkedin 上与我联系。
以上是PHP OOP部分-抽象与接口的详细内容。更多信息请关注PHP中文网其他相关文章!