在本文中,我们将探讨php 中面向对象编程的基础知识。我们将从对类和对象的介绍开始,我们将在本文的后半部分讨论一些高级概念,例如继承和多态性。
什么是面向对象编程 (OOP)?
面向对象编程,通常称为 OOP,是一种帮助您以易于长期维护和可扩展的方式开发复杂应用程序的方法。在 OOP 的世界中,现实世界的实体,如Person、Car或 Animal 被视为对象。在面向对象编程中,您通过使用对象与应用程序进行交互。这与主要与函数和全局变量交互的过程编程形成对比。
在 OOP 中,有一个“类”的概念,它用于将现实世界的实体建模或映射到数据(属性)和功能(方法)的模板。“对象”是一个类的实例,您可以创建同一个类的多个实例。例如,有一个Person类,但许多人对象可以是该类的实例—— dan、zainab、hector等。
类定义属性。例如,对于 Person 类,我们可能有 name、 age和 phoneNumber。然后每个人对象将有自己的这些属性值。
您还可以在类中定义允许您操作对象属性的值并对对象执行操作的方法。例如,您可以定义一个save将对象信息保存到数据库的方法。
什么是 PHP 类?
类是代表现实世界实体的模板,它定义了实体的属性和方法。在本节中,我们将讨论典型 PHP 类的基本结构。
理解新概念的最好方法是举例。因此,让我们看一下Employee以下代码段中的类,它表示员工实体。
<?php class Employee { private $first_name; private $last_name; private $age; public function __construct($first_name, $last_name, $age) { $this->first_name = $first_name; $this->last_name = $last_name; $this->age = $age; } public function getFirstName() { return $this->first_name; } public function getLastName() { return $this->last_name; } public function getAge() { return $this->age; } } ?>
第一行中的class Employee语句定义了Employee类。然后,我们继续声明属性、构造函数和其他类方法。
PHP 中的类属性
您可以将类属性视为用于保存有关对象信息的变量。在上面的例子中,我们定义了三个属性——first_name、last_name和age。在大多数情况下,类属性是通过实例化对象访问的。
这些属性是private,这意味着它们只能从类中访问。这是属性的最安全访问级别。我们将在本文后面讨论类属性和方法的不同访问级别。
PHP 类的构造函数
构造函数是一种特殊的类方法,在实例化对象时会自动调用。我们将在接下来的几节中看到如何实例化对象,但现在您只需要知道构造函数用于在创建对象时初始化对象属性。
您可以通过定义__construct方法来定义构造函数。
PHP 类的方法
我们可以将类方法视为执行与对象相关的特定操作的函数。在大多数情况下,它们用于访问和操作对象属性并执行相关操作。
在上面的例子中,我们定义了getLastName返回与对象关联的姓氏的方法。
以上就是对PHP中类结构的简单介绍。在下一节中,我们将看到如何实例化Employee类的对象。
PHP 中的对象是什么?
在上一节中,我们讨论了 PHP 中类的基本结构。现在,当你想使用一个类时,你需要实例化它,最终结果是一个对象。所以我们可以把一个类看作一个蓝图,而一个对象是一个你可以使用的实际事物。
在我们刚刚在上一节中创建的类的上下文中Employee,让我们看看如何实例化该类的对象。
<?php $objEmployee = new Employee('Bob', 'Smith', 30); echo $objEmployee->getFirstName(); // print 'Bob' echo $objEmployee->getLastName(); // prints 'Smith' echo $objEmployee->getAge(); // prints '30' ?>
new当您想要实例化任何类的对象及其类名时,您需要使用关键字,您将获得该类的新对象实例。
如果一个类已经定义了该__construct方法并且它需要s 个参数,那么您需要在实例化一个对象时传递这些参数。在我们的例子中,Employee类构造函数需要三个参数,因此我们在创建$objEmployee对象时已经传递了这些参数。正如我们前面所讨论的,__construct当对象被实例化时,该方法会被自动调用。
接下来,我们在对象上调用类方法$objEmployee来打印在对象创建期间初始化的信息。当然,您可以创建同一个类的多个对象,如下面的代码片段所示。
<?php $objEmployeeOne = new Employee('Bob', 'Smith', 30); echo $objEmployeeOne->getFirstName(); // prints 'Bob' echo $objEmployeeOne->getLastName(); // prints 'Smith' echo $objEmployeeOne->getAge(); // prints '30' $objEmployeeTwo = new Employee('John', 'Smith', 34); echo $objEmployeeTwo->getFirstName(); // prints 'John' echo $objEmployeeTwo->getLastName(); // prints 'Smith' echo $objEmployeeTwo->getAge(); // prints '34' ?>
下图是 Employee 类及其一些实例的图形表示。
简而言之,类是可用于创建结构化对象的蓝图。
封装
在上一节中,我们讨论了如何实例化Employee类的对象。有趣的是,对象本身$objEmployee将类的属性和方法包装在一起。换句话说,它对程序的其余部分隐藏了这些细节。在 OOP 的世界中,这称为数据封装。
封装是 OOP 的一个重要方面,它允许您限制对对象的某些属性或方法的访问。这将我们带到另一个要讨论的话题: 访问级别。
访问级别
在类中定义属性或方法时,可以将其声明为具有以下三种访问级别之一——public、private或protected。
公共访问
当您将属性或方法声明为公共时,可以从类之外的任何地方访问它。可以从代码中的任何位置修改公共属性的值。
让我们看一个例子来了解公共访问级别。
<?php class Person { public $name; public function getName() { return $this->name; } } $person = new Person(); $person->name = 'Bob Smith'; echo $person->getName(); // prints 'Bob Smith' ?>
正如您在上面的示例中看到的,我们已将name属性声明为公共的。因此,您可以在课堂外的任何地方设置它,就像我们在这里所做的那样。
私人访问
当您将属性或方法声明为private时,只能从类中访问它。这意味着您需要定义 getter 和 setter 方法来获取和设置该属性的值。
同样,让我们修改前面的示例以了解私有访问级别。
<?php class Person { private $name; public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } } $person = new Person(); $person->name = 'Bob Smith'; // Throws an error $person->setName('Bob Smith'); echo $person->getName(); // prints 'Bob Smith' ?>
如果您尝试从类外部访问私有属性,则会抛出致命错误。因此,您需要使用 setter 方法设置私有属性的值,就像我们使用该 方法所做的那样。Cannot access private property Person::$namesetName
您可能想将财产设为私有有充分的理由。例如,如果该属性发生变化,也许应该采取一些行动(例如更新数据库或重新呈现模板)。在这种情况下,您可以定义一个 setter 方法并在属性更改时处理任何特殊逻辑。
受保护的访问
最后,当您将属性或方法声明为 时protected,定义它的同一类和继承相关类的类可以访问它。我们将在下一节讨论继承,所以稍后我们将回到受保护的访问级别。
遗产
继承是面向对象编程范式的一个重要方面,它允许您通过扩展其他类的属性和方法来继承它们。被继承的类称为父类,继承其他类的类称为子类。当你实例化一个子类的对象时,它也继承了父类的属性和方法。
让我们看一下下面的截图来理解继承的概念。
在上面的例子中,Person该类是父类,Employee该类扩展或继承了 Person 类,因此称为子类。
让我们尝试通过一个真实的示例来了解它是如何工作的。
<?php class Person { protected $name; protected $age; public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } private function callToPrivateNameAndAge() { return "{$this->name} is {$this->age} years old."; } protected function callToProtectedNameAndAge() { return "{$this->name} is {$this->age} years old."; } } class Employee extends Person { private $designation; private $salary; public function getAge() { return $this->age; } public function setAge($age) { $this->age = $age; } public function getDesignation() { return $this->designation; } public function setDesignation($designation) { $this->designation = $designation; } public function getSalary() { return $this->salary; } public function setSalary($salary) { $this->salary = $salary; } public function getNameAndAge() { return $this->callToProtectedNameAndAge(); } } $employee = new Employee(); $employee->setName('Bob Smith'); $employee->setAge(30); $employee->setDesignation('Software Engineer'); $employee->setSalary('30K'); echo $employee->getName(); // prints 'Bob Smith' echo $employee->getAge(); // prints '30' echo $employee->getDesignation(); // prints 'Software Engineer' echo $employee->getSalary(); // prints '30K' echo $employee->getNameAndAge(); // prints 'Bob Smith is 30 years old.' echo $employee->callToPrivateNameAndAge(); // produces 'Fatal Error' ?>
这里需要注意的重要一点是Employee该类已使用extends关键字来继承Person该类。现在,Employee该类可以访问Person该类声明为公共或受保护的所有属性和方法。(它不能访问被声明为私有的成员。)
在上面的示例中,$employee对象可以访问类中定义的方法getName和方法,因为它们被声明为公共。setNamePerson
接下来,我们使用类中定义的方法访问该callToProtectedNameAndAge方法,因为它被声明为受保护的。最后,该对象无法访问该类的方法,因为它被声明为私有。getNameAndAgeEmployee$employeecallToPrivateNameAndAgePerson
另一方面,您可以使用$employee对象来设置类的age属性Person,就像我们在类setAge中定义的方法中所做的那样Employee,因为age属性被声明为受保护的。
以上就是对继承的简要介绍。它可以帮助您减少代码重复,从而鼓励代码可重用性。
多态性
多态性是面向对象编程领域的另一个重要概念,它指的是根据对象的数据类型以不同方式处理对象的能力。
例如,在继承的上下文中,如果子类想要改变父类方法的行为,它可以重写那个方法。这称为方法覆盖。让我们快速通过一个真实的例子来理解方法覆盖的概念。
<?php class Message { public function formatMessage($message) { return printf("<i>%s</i>", $message); } } class BoldMessage extends Message { public function formatMessage($message) { return printf("<b>%s</b>", $message); } } $message = new Message(); $message->formatMessage('Hello World'); // prints '<i>Hello World</i>' $message = new BoldMessage(); $message->formatMessage('Hello World'); // prints '<b>Hello World</b>' ?>
如您所见,我们通过在类formatMessage中覆盖它来改变方法的行为。BoldMessage重要的是消息的格式会根据对象类型而不同,无论是父类的实例还是子类的实例。
(一些面向对象的语言也有一种方法重载,允许您定义多个具有相同名称但参数数量不同的类方法。这在 PHP 中不直接支持,但有一些解决方法可以实现类似的功能。)
结论
面向对象编程是一个庞大的学科,我们只触及了其复杂性的皮毛。我确实希望本教程能帮助您开始了解 OOP 的基础知识,并激励您继续学习更高级的 OOP 主题
- PHP 中的类属性
- PHP 类的构造函数
- PHP 类的方法
- 访问级别
- 公共访问
- 私人访问
- 受保护的访问