PHP 面向对象编程
上次修改时间:2025 年 5 月 18 日
在本文中,我们讨论了 PHP 中的面向对象编程。
有三种广泛使用的编程范式:过程式、函数式和面向对象。 PHP 支持过程式和面向对象编程。
面向对象编程 (OOP) 是一种使用对象及其交互来设计应用程序和计算机程序的编程范例。
OOP 中的基本编程概念是
- 抽象
- 多态
- 封装
- 继承
抽象 是通过对适用于问题的类进行建模来简化复杂的现实。 多态性 是以不同方式对不同数据输入使用运算符或函数的过程。 封装 隐藏了类的实现细节,不让其他对象知道。 继承 是一种使用已经定义的类来形成新类的方法。
PHP 对象
对象是 PHP OOP 程序的基本构建块。 对象是数据和方法的组合。 在一个 OOP 程序中,我们创建对象。 这些对象通过方法相互通信。 每个对象都可以接收消息、发送消息和处理数据。
创建对象有两个步骤。 首先,我们创建一个类。 一个 类 是一个对象的模板。 它是一个蓝图,描述了该类的对象都共享的状态和行为。 一个类可以用来创建许多对象。 在运行时从一个类创建的对象被称为该特定类的 实例。
<?php
class Simple {}
$object = new Simple();
print_r($object);
echo gettype($object), "\n";
在我们的第一个例子中,我们创建一个简单的对象。
class Simple {}
这是一个简单的类定义。模板的主体是空的。它没有任何数据或方法。
$object = new Simple();
我们创建一个 Simple 类的新实例。 为此,我们有 new 关键字。 $object 变量是创建的对象的句柄。
print_r($object); echo gettype($object), "\n";
我们使用 print_r 函数来获取关于对象的信息,使用 gettype 函数来获取变量的类型。
$ php simple_class.php Simple Object ( ) object
我们没有获得太多信息,因为类定义是空的。 变量的类型是 object。
PHP 对象属性
对象属性是捆绑在一个类实例中的数据。 对象属性被称为 实例变量 或 成员字段。 实例变量是在类中定义的变量,类的每个对象都有一个单独的副本。
<?php
class Person {
public $name = "";
}
$p1 = new Person();
$p1->name = "Jane";
$p2 = new Person();
$p2->name = "Beky";
echo $p1->name . "\n";
echo $p2->name . "\n";
在上面的 PHP 脚本中,我们有一个 Person 类,其中有一个成员字段。
$p1 = new Person(); $p1->name = "Jane";
我们创建了 Person 类的一个实例,并将 $name 变量设置为“Jane”。 我们使用 -> 运算符来访问对象的属性。
$p2 = new Person(); $p2->name = "Beky";
我们创建了 Person 类的另一个实例。 这里我们将变量设置为“Beky”。
echo $p1->name . "\n"; echo $p2->name . "\n";
我们将变量的内容打印到控制台。
$ php member_fields.php Jane Beky
我们看到脚本的输出。 Person 类的每个实例都有 $name 成员字段的单独副本。
PHP 方法
方法是在类的正文中定义的函数。 它们用于对我们对象的属性执行操作。 方法在 OOP 范式的 封装 概念中至关重要。 例如,我们可能在 AccessDatabase 类中有一个 connect 方法。 我们不需要被告知方法 connect 是如何准确地连接到数据库的。 我们只知道它用于连接到数据库。 这对于划分编程中的责任至关重要,尤其是在大型应用程序中。
<?php
class Circle {
public $radius;
function setRadius($radius) {
$this->radius = $radius;
}
function area() {
return $this->radius * $this->radius * M_PI;
}
}
$c = new Circle();
$c->setRadius(5);
echo $c->area(), "\n";
在代码示例中,我们有一个 Circle 类。 我们定义了两种方法。
public $radius;
我们有一个成员字段。 它是圆的半径。 public 关键字是一个访问说明符。 它告诉该变量可以从外部世界完全访问。
function setRadius($radius) {
$this->radius = $radius;
}
这是 setRadius 方法。 它是一个普通的 PHP 函数。 我们将类中定义的函数称为 方法。 $this 变量是一个特殊变量,我们使用它从方法访问成员字段。
function area() {
return $this->radius * $this->radius * M_PI;
}
area 方法返回圆的面积。 M_PI 是一个内置常量。
$ php circle.php 78.539816339745
PHP 访问修饰符
访问修饰符 设置方法和成员字段的可见性。 PHP 有三个访问修饰符:public、protected 和 private。 public 成员可以从任何地方访问。 protected 成员只能在类本身以及继承的类和父类中访问。 private 成员只能由定义成员的类访问。
访问修饰符保护数据免受意外修改。 它们使程序更加健壮。
<?php
class Person {
public $name = "";
private $age;
}
$p = new Person();
$p->name = "Jane";
#$p->age = 17;
echo $p->name . "\n";
在上面的 PHP 脚本中,我们有两个成员字段;一个声明为 public,另一个声明为 private。
$p->name = "Jane"; #$p->age = 17;
我们从外部世界访问 $name 成员。 通过外部世界,我们指的是“不在类中”。 这是可以的,因为 $name 变量被声明为 public。 访问 $age 成员是不可能的。 private 修饰符禁止这样做。 如果我们取消注释代码行,我们会得到“Fatal error: Cannot access private property Person::$age”错误。
<?php
class Base {
public $name = "Base";
protected $id = 6124;
private $is_defined = "yes";
}
class Derived extends Base {
public function info() {
echo "This is Derived class\n";
echo "Members inherited: \n";
echo $this->name . "\n";
echo $this->id . "\n";
echo $this->is_defined . "\n";
}
}
$derived = new Derived();
$derived->info();
在此 PHP 脚本中,我们有一个 Derived 类,它扩展了 Base 类。 Base 类有三个成员字段,所有成员字段都有不同的访问修饰符。 $is_defined 成员未被继承。 private 修饰符阻止了这一点。
public function info() {
info 方法有一个 public 访问修饰符。 这意味着它可以在类环境之外调用。
$ php access2.php This is Derived class Members inherited: Base 6124
public 和 protected 成员被继承,private 成员不被继承。
<?php
class SysInfo {
private function get_date() {
return date("Y/m/d");
}
private function get_version() {
return phpversion();
}
public function getInfo() {
$date = $this->get_date();
$version = $this->get_version();
echo "The date is: $date\n";
echo "The PHP version is: $version\n";
}
}
$sys = new SysInfo();
$sys->getInfo();
#$sys->get_date();
在这个脚本中,我们有一个 SysInfo 类。 它将一些系统信息输出到控制台。 我们有两个私有函数和一个公共函数。 私有方法仅用于 SysInfo 类的内部工作。 它们不应该在类外调用。
$sys = new SysInfo(); $sys->getInfo(); #$sys->get_date();
我们创建一个 SysInfo 类的实例,并调用公开可用的 getInfo 方法。 getInfo 方法在内部使用私有方法来完成它的工作。 取消注释最后一行代码会导致错误。
PHP 方法重载
方法重载允许创建多个具有相同名称的方法,但这些方法在输入类型上彼此不同。
方法重载有什么用? Qt4 库给出了一个很好的使用示例。 QPainter 类有三种方法来绘制矩形。 它们的名称是 drawRect,它们的参数不同。 一个接受对浮点矩形对象的引用,另一个接受对整数矩形对象的引用,最后一个接受四个参数:x、y、宽度、高度。 如果 C++ 语言(Qt 的开发语言)没有方法重载,那么库的创建者将不得不将方法命名为 drawRectRectF、drawRectRect、drawRectXYWH。 使用方法重载的解决方案更优雅。
<?php
class Sum {
public function getSum() {
return 0;
}
public function getSum($x) {
return $x;
}
public function getSum($x, $y) {
return $x + $y;
}
}
$s = new Sum();
echo $s->getSum() . "\n" ;
echo $s->getSum(5) . "\n" ;
echo $s->getSum(3, 4) . "\n" ;
这是一种方法重载,我们从 C#、Java 或 C++ 等语言中得知。 但这在 PHP 中不起作用。 运行此示例,我们得到以下错误:“Fatal error: Cannot redeclare Sum::getSum()”。 默认情况下,PHP 函数可以接受任意数量的变量。
为了在 PHP 中模拟方法重载,我们使用 func_get_args 函数。
<?php
class Sum {
public function getSum() {
$sum = 0;
$args = func_get_args();
if (empty($args)) return 0;
foreach ($args as $arg) {
$sum += $arg;
}
return $sum;
}
}
$s = new Sum();
echo $s->getSum() . "\n" ;
echo $s->getSum(5) . "\n" ;
echo $s->getSum(3, 4) . "\n" ;
echo $s->getSum(3, 4, 7) . "\n" ;
这次,脚本将运行。
$args = func_get_args();
func_get_args 函数返回一个包含函数参数列表的数组。
foreach ($args as $arg) {
$sum += $arg;
}
我们遍历数组的所有成员,并计算总和。
echo $s->getSum() . "\n" ; echo $s->getSum(5) . "\n" ; echo $s->getSum(3, 4) . "\n" ; echo $s->getSum(3, 4, 7) . "\n" ;
我们使用不同数量的输入调用相同的方法名称。
$ php overloading2.php 0 5 7 14
PHP 构造函数
构造函数是一种特殊的方法。 当对象被创建时,它会自动被调用。 构造函数的目的是启动对象的状态。 PHP 中构造函数的名称是 __construct(带两个下划线)。
<?php
class Song {
function __construct() {
echo "Song object is created \n";
}
}
$song = new Song();
我们有一个 Song 类。 这个类有一个构造函数,它将消息打印到控制台。
$song = new Song();
这是创建对象并调用构造函数的时候。 我们在控制台中收到一条消息。
$ php constructor.php Song object is created
构造函数通常接受参数。
<?php
class Song {
function __construct($song) {
echo "Song $song is created \n";
}
}
$song = new Song("Bad romance");
我们稍微修改了之前的示例。 我们将一个值传递给构造函数。
function __construct($song) {
echo "Song $song is created \n";
}
传递的参数存储在本地 $song 变量中。
$ php constructor2.php Song Bad romance is created
现在我们有一条消息,其中包含打印到控制台的歌曲标题。
在下一个例子中,我们初始化该类的数据成员。初始化变量是构造函数的典型工作。
<?php
class Friend {
private $born;
private $name;
function __construct($name, $born) {
$this->name = $name;
$this->born = $born;
}
function getInfo() {
echo "My friend $this->name was born in $this->born\n";
}
}
$friend = new Friend("Monika", 1990);
$friend->getInfo();
我们有一个 Friend 类,其中包含数据成员和方法。
private $born; private $name;
我们在类定义中有两个变量。 private 关键字是一个访问修饰符。 它是一种封装形式。 private 关键字是限制最严格的修饰符。 它只允许相关对象访问该变量。 没有后代,也没有其他对象。 稍后将详细介绍此主题。
function __construct($name, $born) {
$this->name = $name;
$this->born = $born;
}
在构造函数中,我们初始化了两个数据成员。 $this 变量是一个用于引用对象变量的句柄。
$friend = new Friend("Monika", 1990);
$friend->getInfo();
我们使用两个参数创建了一个 Friend 对象。 然后我们调用该对象的 getInfo 方法。 要调用对象方法,我们使用 -> 运算符。
$ php friend.php My friend Monika was born in 1990
PHP 构造函数属性提升
构造函数属性提升是 PHP 8.0 中引入的一个特性,它允许您直接在构造函数参数列表中声明和初始化类属性。 这减少了样板代码,并使类定义更简洁。
<?php
class User {
public function __construct(
public string $name,
private int $age,
protected string $email
) {}
}
$user = new User("Alice", 30, "alice@example.com");
echo $user->name . "\n";
// echo $user->age; // Error: private property
// echo $user->email; // Error: protected property
在此示例中,User 类使用构造函数属性提升。 name 属性是 public 的,age 是 private 的,email 是 protected 的。 这些属性会自动从构造函数参数中声明和初始化。
此功能对于数据传输对象和具有许多属性的类特别有用,使您的代码更短且更易于阅读。
PHP 类常量
PHP 能够创建类常量。 这些常量不属于具体对象。 它们属于类。 按照惯例,常量用大写字母书写。
<?php
class Math {
const PI = 3.14159265359;
public function getPI() {
echo self::PI;
}
}
$math = new Math();
echo Math::PI, "\n";
echo $math->getPI(), "\n";
我们有一个 Math 类,其中包含一个 PI 常量。
const PI = 3.14159265359;
const 关键字用于定义常量。
public function getPI() {
echo self::PI;
}
从方法内部访问类常量,使用 self 关键字,后跟两个冒号。
echo Math::PI, "\n"; echo $math->getPI(), "\n";
我们将 PI 常量打印到控制台。 在第一种情况下,我们通过引用类名(后跟两个冒号和常量名)来获取常量值。 请注意,不需要任何对象即可获取类常量。 在第二种情况下,我们使用对象方法。
PHP instanceof 关键字
instanceof 关键字用于确定 PHP 变量是否是某个类的实例化对象。
<?php
class Cat {}
class Dog {}
class Bird {}
$objects = [ new Cat(), new Dog(), new Cat(), new Bird(), new Bird(),
new Dog(), new Dog(), new Cat(), new Bird() ];
shuffle($objects);
foreach ($objects as $object) {
if ($object instanceof Cat) {
echo "It is a Cat\n";
} elseif ($object instanceof Dog) {
echo "It is a Dog\n";
} else if ($object instanceof Bird) {
echo "It is a Bird\n";
}
}
在上面的脚本中,我们有三个类:Cat、Dog 和 Bird。 我们遍历数组,并为每个数组值打印类。
$objects = [ new Cat(), new Dog(), new Cat(), new Bird(), new Bird(),
new Dog(), new Dog(), new Cat(), new Bird() ];
我们创建了一个这些对象的数组。
shuffle($objects);
我们打乱了数组。 此时,我们不知道数组值的类类型。
if ($object instanceof Cat) {
echo "It is a Cat\n";
}
这里我们使用 instanceof 关键字来找出类的类型。
$ php instanceof.php It is a Bird It is a Cat It is a Cat It is a Dog It is a Dog It is a Cat It is a Dog It is a Bird It is a Bird
PHP __toString 方法
当我们对对象实例使用 print 或 echo 关键字时,将调用 __toString 特殊方法。 我们将在以下示例中演示这一点。
<?php
class Cat {
public $name;
public $age;
function __construct($name, $age) {
$this->age = $age;
$this->name = $name;
}
function __toString() {
return "Cat: $this->name, Age: $this->age \n";
}
}
$missy = new Cat("Missy", 6);
$lucky = new Cat("Lucky", 4);
print $missy;
echo $lucky;
我们有一个 Cat 类,其中定义了一个 __toString 特殊方法。
function __toString() {
return "Cat: $this->name, Age: $this->age \n";
}
该方法打印有关对象的基本信息。
$missy = new Cat("Missy", 6);
$lucky = new Cat("Lucky", 4);
我们创建了 Cat 类的两个对象。
print $missy; echo $lucky;
我们对它们使用 print 或 echo 关键字。
$ php tostring.php Cat: Missy, Age: 6 Cat: Lucky, Age: 4
PHP 继承
继承是一种使用已经定义的类来形成新类的方法。 新形成的类被称为 派生 类,我们从中派生的类被称为 基 类。 继承的重要好处是代码重用和程序复杂性的降低。 派生类(后代)覆盖或扩展基类(祖先)的功能。
<?php
class Base {
function __construct() {
echo "Construction of Base class \n";
}
}
class Derived extends Base {
function __construct() {
parent::__construct();
echo "Construction of Derived class \n";
}
}
$obj1 = new Base();
$obj2 = new Derived();
在此 PHP 脚本中,我们有两个类:一个 Base 类和一个 Derived 类。 Derived 类继承自 Base 类。
class Derived extends Base {
在 PHP 中,我们使用 extends 关键字来创建继承关系。
function __construct() {
parent::__construct();
echo "Construction of Derived class \n";
}
在 Derived 类的构造函数中,我们调用父构造函数。 我们使用 parent 关键字,后跟两个冒号和 __construct 方法。 必须显式调用父类的构造函数。
$obj1 = new Base(); $obj2 = new Derived();
我们实例化了 Base 类和 Derived 类。
$ php derived.php Construction of Base class Construction of Base class Construction of Derived class
接下来是一个更复杂的示例。
<?php
abstract class Being {
protected $isAlive = true;
public function isAlive() {
if ($this->isAlive) {
echo "Being is alive\n";
} else {
echo "Being is not alive\n";
}
}
public function kill() {
$this->isAlive = false;
}
}
abstract class Animal extends Being {
protected $age;
public function __construct($age) {
$this->age = $age;
}
protected function setAge($age) {
$this->age = $age;
}
public function getAge() {
return $this->age;
}
}
class Cat extends Animal {
private $name;
public function __construct($name, $age) {
$this->name = $name;
parent::__construct($age);
}
public function getName() {
return $this->name;
}
}
$cat = new Cat("Cici", 4);
$cat->isAlive();
echo $cat->getName() . " is " . $cat->getAge() . " years old\n";
$cat->kill();
$cat->isAlive();
我们在这里使用了几个新概念。 在代码示例中,我们有三个类:Being、Animal 和 Cat。 Animal 类继承自 Being 类。 Cat 类继承自 Animal 类。 类继承未声明为私有的方法和数据成员。
abstract class Being {
Being 类被声明为 abstract。 abstract 关键字禁止实例化类。 创建 Being 类的实例没有多大意义。
protected $isAlive = true;
$isAlive 数据成员被声明为 protected。 只有定义它们的类及其后代才能访问此类成员。
abstract class Animal extends Being {
Animal 类也被声明为抽象。 它继承自类 Being。 为此,我们使用 extends 关键字。 Animal 是一个后代。 它继承了基类 Being 的方法和变量。
class Cat extends Animal {
Cat 类继承自 Animal 类。 它继承自 Animal 类,也间接继承自 Being 类。 它未声明为抽象,这意味着我们可以实例化它。
parent::__construct($age);
在 Cat 类的构造函数中,我们使用 parent 关键字(后跟两个冒号和 __construct 方法)调用父构造函数。 必须显式调用父类的构造函数。
$cat = new Cat("Cici", 4);
$cat->isAlive();
echo $cat->getName() . " is " . $cat->getAge() . " years old\n";
$cat->kill();
$cat->isAlive();
我们创建了一只新猫:Cici,4 岁。 然后我们在 cici 对象上调用函数。 请注意使用未在 Cat 类中创建,而是从父类继承的方法。
$ php inheritance.php Being is alive Cici is 4 years old Being is not alive
PHP 抽象类和方法
抽象类不能被实例化。 如果一个类包含至少一个抽象方法,它也必须被声明为抽象。 抽象方法不能被实现,它们只是声明了方法的签名。 当我们从一个抽象类继承时,派生类必须实现所有抽象方法。 此外,这些方法必须使用相同或更宽松的可见性来声明。
与接口不同,抽象类可以拥有带有完整实现的方法,也可以定义成员字段。因此,抽象类可以提供部分实现。程序员经常将一些公共功能放入抽象类中。然后将这些抽象类进行子类化以提供更具体的实现。例如,Qt 图形库有一个 QAbstractButton,它是按钮小部件的抽象基类,提供按钮的公共功能。按钮 Q3Button、QCheckBox、QPushButton、QRadioButton 和 QToolButton 继承自这个抽象基类。
正式来说,抽象类用于强制执行协议。协议是一组所有实现对象必须支持的操作。
<?php
abstract class Drawing {
protected $x = 0;
protected $y = 0;
public abstract function area();
public function getCoordinates() {
echo "\$x is $this->x\n";
echo "\$y is $this->y\n";
}
}
class Circle extends Drawing {
private $radius;
public function __construct($x, $y, $r) {
$this->radius = $r;
$this->x = $x;
$this->y = $y;
}
public function area() {
return $this->radius * $this->radius * pi();
}
public function __toString() {
return "Circle, at x: $this->x, y: $this->y, radius: $this->radius";
}
}
$o = new Circle(12, 45, 22);
echo "$o \n";
echo "Area of the circle: " . $o->area() . "\n";
echo $o->getCoordinates();
在我们的 PHP 脚本中,我们有一个抽象基类 Drawing。该类定义了两个成员字段,定义了一个方法并声明了一个方法。其中一个方法是抽象的,另一个方法是完全实现的。 Drawing 类是抽象的,因为我们无法绘制它。我们可以绘制一个圆,一个点或一个正方形。 Drawing 类具有我们可以绘制的对象的某些公共功能。
class Circle extends Drawing {
Circle 是 Drawing 类的子类。它必须实现抽象的 area 方法。
$ php abstract.php Circle, at x: 12, y: 45, radius: 22 Area of the circle: 1520.53084434 $x is 12 $y is 45
PHP 接口
遥控器是观众和电视之间的接口。它是此电子设备的接口。外交协议指导外交领域的所有活动。道路规则是驾驶者、骑自行车者和行人必须遵守的规则。编程中的接口与之前的例子类似。
接口是
- API
- 约定
对象通过它们暴露的方法与外界交互。实际的实现对程序员来说并不重要,或者它也可能是一个秘密。一家公司可能出售一个库,并且它不想公开实际的实现。程序员可能会在 GUI 工具包的窗口上调用一个 maximize 方法,但对该方法的实现方式一无所知。从这个角度来看,接口是对象与外界交互的方法,而无需过多地暴露其内部工作原理。
从第二个角度来看,接口是合同。如果达成一致,就必须遵守。它们用于设计应用程序的架构,并帮助组织代码。
接口是完全抽象的类型。它们使用 interface 关键字声明。接口只能有方法签名和常量。在接口中声明的所有方法签名都必须是公共的。它们不能有完全实现的方法,也不能有成员字段。一个 PHP 类可以实现任意数量的接口。一个接口也可以扩展任意数量的接口。实现接口的类必须实现接口的所有方法签名。
接口用于模拟多重继承。一个 PHP 类只能扩展一个类。一个 PHP 类可以实现多个接口。使用接口的多重继承不是关于继承方法和变量。它是关于继承思想或合同,这些思想或合同由接口描述。
接口和抽象类之间有一个重要的区别。抽象类为在继承层次结构中相关的类提供部分实现。另一方面,接口可以由彼此不相关的类实现。例如,我们有两个按钮:一个经典按钮和一个圆形按钮。两者都继承自一个抽象按钮类,该类为所有按钮提供一些公共功能。实现类是相关的,因为所有都是按钮。另一个例子可能有类 Database 和 SignIn。它们彼此无关。我们可以应用一个 ILoggable 接口,这将迫使它们创建一个用于进行日志记录的方法。
<?php
interface IInfo {
public function do_inform();
}
class Some implements IInfo {
public function do_inform() {
echo "This is a Some class\n";
}
}
$sm = new Some();
$sm->do_inform();
这是一个简单的 PHP 脚本,演示了一个接口。
interface IInfo {
public function do_inform();
}
这是一个接口 IInfo。它具有 do_inform 方法签名。
class Some implements IInfo {
我们使用 implements 从接口实现。
public function do_inform() {
echo "This is a Some class\n";
}
该类为 do_inform 方法提供了实现。
下一个示例展示了类如何实现多个接口。
<?php
interface Device {
public function switch_on();
public function switch_off();
}
interface Volume {
public function volume_up();
public function volume_down();
}
interface Pluggable {
public function plug_in();
public function plug_off();
}
class CellPhone implements Device, Volume, Pluggable {
public function switch_on() { echo "Switching on\n"; }
public function switch_off() { echo "Switching off\n"; }
public function volume_up() { echo "Volume up\n"; }
public function volume_down() { echo "Volume down\n"; }
public function plug_in() { echo "Plugging in\n"; }
public function plug_off() { echo "Plugging off\n"; }
}
$o = new CellPhone();
$o->switch_on();
$o->volume_up();
$o->plug_in();
我们有一个 CellPhone 类,它继承自三个接口。
class CellPhone implements Device, Volume, Pluggable {
该类实现了所有三个接口,这些接口用逗号分隔。CellPhone 类必须实现所有三个接口的所有方法签名。
$ php interface.php Switching on Volume up Plugging in
下一个示例展示了接口如何从多个其他接口扩展。
<?php
interface IInfo {
public function do_inform();
}
interface IVersion {
public function get_version();
}
interface ILog extends IInfo, IVersion {
public function do_log();
}
class DBConnect implements ILog {
public function do_inform() {
echo "This is a DBConnect class\n";
}
public function get_version() {
echo "Version 1.02\n";
}
public function do_log() {
echo "Logging\n";
}
public function connect() {
echo "Connecting to the database\n";
}
}
$db = new DBConnect();
$db->do_inform();
$db->get_version();
$db->do_log();
$db->connect();
在这个 PHP 脚本中,我们定义了三个接口。扩展接口允许我们组织它们。
interface ILog extends IInfo, IVersion {
public function do_log();
}
ILog 接口扩展了另外两个接口。
public function do_inform() {
echo "This is a DBConnect class\n";
}
DBConnect 类实现了 do_inform 方法。此方法由 ILog 接口继承,该类实现了该接口。
PHP 多态
多态性是使用运算符或函数以不同方式处理不同数据输入的过程。在实际中,多态性意味着如果类 B 继承自类 A,它不必继承关于类 A 的所有内容;它可以以不同的方式做一些类 A 做的事情。
一般来说,多态性是呈现不同形式的能力。从技术上讲,它是一种为派生类重新定义方法的能力。多态性涉及将特定实现应用于接口或更通用的基类。
<?php
abstract class Shape {
private $x = 0;
private $y = 0;
public abstract function area();
}
class Rectangle extends Shape {
function __construct($x, $y) {
$this->x = $x;
$this->y = $y;
}
function area() {
return $this->x * $this->y;
}
}
class Square extends Shape {
function __construct($x) {
$this->x = $x;
}
function area() {
return $this->x * $this->x;
}
}
$shapes = [ new Square(5), new Rectangle(12, 4), new Square(8) ];
foreach ($shapes as $shape) {
echo $shape->area() . "\n";
}
在上面的 PHP 脚本中,我们有一个抽象的 Shape 类。这个类变形为两个后代类:Rectangle 和 Square。两者都提供了它们自己对 area 方法的实现。多态性为 OOP 系统带来了灵活性和可扩展性。
在本文中,我们介绍了 PHP 中的 OOP。
作者
来源
列出所有 PHP 教程。