在本文中,我们将探索PHP中的面向对象编程的基础。 我们将从类和对象的介绍开始,并在本文的后半部分讨论几个高级概念,例如继承和多态性。
什么是面向对象编程(OOP)?
面向对象的程序设计(通常称为OOP)是一种方法,可以帮助您以易于维护和长期扩展的方式开发复杂的应用程序。 在OOP的世界中,诸如Person
, Car
或Animal
现实世界实体被视为对象。 在面向对象的编程中,您通过使用对象与应用程序进行交互。 这与过程编程相反,在过程编程中,您主要与函数和全局变量进行交互。
在OOP中,有一个“ 类 ”的概念,用于将现实世界的实体建模或映射到数据( 属性 )和功能( 方法 )的模板。 “ 对象 ”是类的实例,您可以创建同一类的多个实例。 例如,只有一个Person
类,但是许多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
方法并且需要参数,则在实例化对象时需要传递这些参数。 在我们的例子中, 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类及其某些实例的图形表示。
![对象实例化](https://i-blog.csdnimg.cn/blog_migrate/21fc8f3f455aff0efa8ee923c66ea384.png)
简而言之,类是可用于创建结构化对象的蓝图。
封装形式
在上一节中,我们讨论了如何实例化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
属性声明为public。 因此,您可以在课外的任何地方进行设置,就像我们在这里所做的那样。
私人通道
当您将属性或方法声明为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'
?>
如果尝试从类外部访问私有属性,则会引发致命错误Cannot access private property Person::$name
Cannot access private property Person::$name
。 因此,您需要像使用setName
方法一样,使用setter方法来设置private属性的值。
有充分的理由说明为什么您想将财产设为私有。 例如,如果该属性发生更改,也许应该采取一些措施(例如更新数据库或重新呈现模板)。 在这种情况下,可以定义一个setter方法并在更改属性时处理任何特殊的逻辑。
受保护的访问
最后,将属性或方法声明为protected
,可以由定义该属性或方法的同一类以及继承该类的类访问该属性或方法。 我们将在下一节讨论继承,因此稍后再回到受保护的访问级别。
遗产
继承是面向对象编程范例的重要方面,它使您可以通过扩展继承其他类的属性和方法。 被继承的类称为父类 ,而继承另一个类的类称为子类 。 实例化子类的对象时,它也继承父类的属性和方法。
让我们看一下下面的屏幕快照,以了解继承的概念。
![遗产](https://i-blog.csdnimg.cn/blog_migrate/9ce6ac53fd5252a4215876a3a7b3e151.png)
在上面的示例中, 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
类可以访问声明为public或protected的Person
类的所有属性和方法。 (它无法访问被声明为私有的成员。)
在上面的示例中, $employee
对象可以访问在Person
类中定义的getName
和setName
方法,因为它们被声明为public。
接下来,我们访问的callToProtectedNameAndAge
使用方法getNameAndAge
中定义的方法Employee
类,因为它是保护被声明。 最后,由于$employee
对象被声明为私有,因此它无法访问Person
类的callToPrivateNameAndAge
方法。
另一方面,您可以使用$employee
对象设置Person
类的age
属性,就像我们在Employee
类中定义的setAge
方法中所做的setAge
,因为age
属性被声明为protected。
因此,这是继承的简要介绍。 它可以帮助您减少代码重复,从而提高代码的可重用性。
多态性
多态性是面向对象编程领域中的另一个重要概念,它涉及基于对象的数据类型以不同方式处理对象的能力。
例如,在继承的上下文中,如果子类想要更改父类方法的行为,则它可以覆盖该方法。 这称为方法覆盖。 让我们快速浏览一个真实的示例,以了解方法重写的概念。
<?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>'
?>
如您所见,我们通过在BoldMessage
类中重写formatMessage
方法来改变其行为。 重要的是,消息的格式取决于对象类型,无论是父类的实例还是子类的实例。
(某些面向对象的语言也有一种方法重载,使您可以定义多个具有相同名称但参数数量不同的类方法。PHP不直接支持此方法,但是有两种解决方法可以实现类似的目的功能。)
结论
面向对象的编程是一门广阔的话题,我们只是从表面上了解了它的复杂性。 我确实希望本教程可以帮助您入门OOP的基础知识,并能激发您继续学习更高级的OOP主题的知识。
不管您使用什么技术,面向对象的编程都是应用程序开发中的重要方面。 今天,在PHP的背景下,我们讨论了OOP的两个基本概念,我们还借此机会介绍了一些实际示例。
随时使用以下供稿发布您的查询!
翻译自: https://code.tutsplus.com/tutorials/basics-of-object-oriented-programming-in-php--cms-31910