本文目录
前言
在
PHP
的广阔世界里,面向对象编程(OOP
)不仅是构建复杂、可维护应用的关键基石,更是提升代码质量、促进团队协作的强大工具。本指南旨在通过系统化的学习与实践,引领您深入探索PHP
面向对象编程的精髓。从面向对象的基本概念出发,我们将逐步揭开类与对象的神秘面纱,理解它们在内存中的运行机制,并掌握封装、继承等核心概念。
通过本指南,您将学会如何设计清晰、可复用的类结构,利用封装保护数据的安全,通过继承实现代码的复用与扩展。同时,我们还将探讨构造与析构方法的重要性,以及如何在继承关系中巧妙运用访问修饰符,确保代码的安全与灵活。此外,针对PHP
中特有的特性,如多重继承的替代方案及$this
关键字的妙用。
无论您是PHP
编程的初学者,还是希望提升面向对象编程技能的进阶者,本指南都将是您不可多得的宝贵资源。让我们一同踏上这段探索之旅,掌握PHP
面向对象编程的精髓,开启高效、优雅的编程新篇章!
1、面向对象介绍
1.1 介绍
面向对象是一个编程思想,编程思想有面向过程和面向对象。
面向过程:编程思路集中的是过程上。
面向对象:编程的思路集中在参与的对象。
1.2 面向对象的好处
- 多人合作方便
- 减少代码冗余,灵活性高
- 代码的可重用性发挥到极致
- 可扩展性强
1.3 类和对象
-
对象是具体存在的事务,对象是由属性(变量)和方法(函数)组成的
-
类是具有相同属性和行为的一组对象的集合
2、 在php中实现类和对象
2.1 创建类
语法:
class 类名 {
// 属性
// 方法
// 常量
}
类是由属性、方法、常量组成的,也可以说类成员有:属性、方法、常量。
类名的命名规则:
- 以字母、下划线开头,后面跟的是字母、数字、下划线。
- 不能用PHP关键字做类名
- 类名不区分大小写(变量名区分,关键字、类名不区分大小写)
- 类名用帕斯卡命名法(大驼峰 单词的首字母大写)
2.2 实例化对象
创建完类后,通过new 类名()
进行实例化
例:
<?php
// 定义类
class Student {
}
// 实例化对象
$stu1=new Student();
$stu2=new Student();
$stu3=$stu2; // 对象传递默认是传递地址
// 对象比较
var_dump($stu1,$stu2,$stu3);
var_dump($stu1==$stu2); // bool(true) 比较对象结构
var_dump($stu1===$stu2); // bool(false) 是否为同个对象
var_dump($stu2===$stu3); // bool(true) 为同个对象
?>
效果:
对象的比较:
相等:结构和保存的值一样就相等
全等:指向同一个对象才是全等
2.3 类添加属性和方法
属性本质就是变量
通过 ->
调用对象的成员
对象名->属性名 对象名 -> 方法名()
-
属性
代码:
<?php
// 定义类
class Student {
public $name; // 姓名属性
public $add='地址不详'; // 地址属性,默认值为地址不详
}
// 实例化对象
$stu=new Student();
// 给属性赋值
$stu->name='Jack';
$stu->add='厦门';
// 获取属性的值
echo '姓名:'.$stu->name,'<br/>';
echo '地址:'.$stu->add,'<br/>';
// 添加属性
$stu->age=20; // 只给对象加了这个属性,而不是类。
print_r($stu);
echo '<br/>';
// 删除属性
unset($stu->add);
print_r($stu);
?>
效果:
2. 方法
代码:
<?php
// 定义类
class Student {
// 定义方法
public function show() {
echo '这是show方法<br/>';
}
// public可以省略,如果省略,默认就是public
function test() {
echo '这是test方法';
}
}
$stu=new Student();
$stu->show();
$stu->test();
?>
效果:
小结:
1、方法前面public是可以省略,如果省略,默认就是public的。
2、属性前面的public不能省略。
3、访问修饰符
访问修饰符用来控制成员的访问权限
修饰符 | 描述 |
---|---|
public (公有的) | 在类的内部和外部都能访问 |
private(私有的) | 只能在类的内部访问 |
protected(受保护的) |
测试:
<?php
class Student {
public $name='tom';
private $add='Amoy';
}
$stu=new Student();
echo $stu->name;
echo $stu->add;
?>
效果:
属性一般都是私有的,但是可以通过公有的方法对私有的属性进行复制和取值。
作用:保证数据的合法性。
代码:
<?php
// 访问修饰符
class Student {
private $name; // 属性一般是私有的
private $add;
// 通过公有的方法对私有的属性进行赋值
public function setIn($name, $add) {
$this->name=$name; // $this表示当前对象
$this->add=$add;
}
// 取值
public function getIn() {
echo '姓名:'.$this->name,'<br/>';
echo '地址:'.$this->add,'<br/>';
}
}
$stu=new Student();
$stu->setIn('Jack', 'Amoy');
$stu->getIn()
?>
效果:
这样一来不是变的很繁琐,直接将属性设置为公有多省事,其实不然,设为私有的可以进行相对应的拦截,例如:
地址不是Amoy,就显示地址必须要是Amoy:
<?php
// 访问修饰符
class Student {
private $name; // 属性一般是私有的
private $add;
// 通过公有的方法对私有的属性进行赋值
public function setIn($name, $add) {
if ($add!='Amoy') {
echo '地址必须是Amoy!';
exit;
}
$this->name=$name; // $this表示当前对象
$this->add=$add;
}
// 取值
public function getIn() {
echo '姓名:'.$this->name,'<br/>';
echo '地址:'.$this->add,'<br/>';
}
}
$stu=new Student();
$stu->setIn('Jack', 'Amoy1');
$stu->getIn()
?>
效果:
那么就可以用来做过滤数据用。
4、类和对象在内存中的分布
- 对象的本质是一个复杂的变量
- 类的本质是一个自定义的复杂数据类型
- 栈区:运行速度快,体积小,保存基本类型
- 堆区:运行速度稍慢,体积大。保存复杂类型
- 实例化的过程就是分配内存空间的过程
- 对象保存在堆区,将堆区的地址保存到栈区。
5、封装
封装就是有选择性的提供数据
通过访问修饰符来实现封装
5.1 构造方法
构造方法也叫构造函数,当实例化对象的时候自动执行。php中构造函数中不允许使用return。使用了也没效果。
语法:
function __construct() {
}
例:
<?php
class Student {
public function __construct() {
echo '这是构造方法<br/>';
}
}
$stu1 = new Student;
?>
效果:
利用构造方法进行私有变量的赋值访问:
<?php
class Student {
private $name;
private $sex;
// 初始化成员变量
public function __construct($name,$sex) {
$this->name=$name;
$this->sex=$sex;
}
// 显示信息
public function show() {
echo "姓名:{$this->name}<br/>";
echo "性别:{$this->sex}<br/>";
}
}
// 实例化
$stu = new Student('Jack', '男');
$stu->show();
?>
效果:
5.2 析构方法
当对象销毁的时候自动调用。(析构方法不能带参数)
语法:
function __destruct() {
}
代码:
<?php
class Student {
private $name;
// 初始化成员变量
public function __construct($name) {
$this->name=$name;
echo "{$name} 生成。<br/>";
}
// 显示信息
public function __destruct() {
echo "{$this->name} 销毁。<br/>";
}
}
// 实例化
$stu = new Student('Jack');
?>
效果:
5.3 计算机的内存管理
计算机内存管理方式:
1、先进先出:
先进先出的内存管理方式一般用在业务逻辑中,比如秒杀、购票等等。
2、先进后出。
先进后出是计算机的默认内存管理方式
6、继承
6.1 继承介绍
- 继承使得代码具有层次结构
- 子类继承了父类的属性和方法,实现了代码的可重用性
- 使用extends关键字实现继承
- 父类和子类是相对的
语法:
class 子类 extends 父类 {
}
例题:
<?php
// 父类
class Person {
public function show () {
echo '我是人类<br/>';
}
}
// 子类
class Student extends Person {
}
// 测试
$stu = new Student;
$stu->show();
效果:
执行过程:
- 在Student类中查找show(),如果找到就调用,找不到就到父类中查找
- 在Person类中查询show()
6.2 子类中调用父类成员
例:
<?php
// 父类
class Person {
public function show () {
echo '我是renlei<br/>';
}
}
// 子类
class Student extends Person {
public function test () {
/* 方法一:
$person = new Person();
$person->show();
*/
// 方法二:
$this->show();
}
}
// 测试
$stu = new Student;
$stu->test();
效果:
小结:
1、方法一:通过实例化父类调用父类的成员
2、方法二:通过$this关键字去调用父类的成员
6.3 访问修饰符protected
protected: 受保护的,在整个继承链上使用,访问。
例题一:
<?php
// 父类
class Person {
protected $num=10;
}
class Student extends Person {
public function getNum() {
echo $this->num;
}
}
// 测试
$obj = new Student();
$obj->getNum();
效果:
例题二:
<?php
// 父类
class Person {
public function getNum() {
echo $this->num;
}
}
class Student extends Person {
protected $num=10;
}
// 测试
$obj = new Student();
$obj->getNum();
效果:
6.4 继承中的构造函数
规则:如果子类有构造函数就调用子类的,如果子类没有就调用父类的构造数。
通过类名调用父类的构造函数:
类名 __construct()
例题:
<?php
// 父类
class Person {
public function __construct() {
echo '这是父类';
}
}
class Student extends Person {
public function __construct() {
echo '这是子类';
}
}
// 测试
new Student();
效果:
例题:
<?php
// 父类
class Person {
public function __construct() {
echo '这是父类';
}
}
class Student extends Person {
// public function __construct() {
// echo '这是子类';
// }
}
// 测试
new Student();
效果:
通过类名调用父类的构造函数:
类名 __construct()
:
<?php
// 父类
class Person {
public function __construct() {
echo '这是父类';
}
}
class Student extends Person {
public function __construct() {
Person::__construct(); // 调用父类的构造函数
echo '这是子类';
}
}
// 测试
new Student();
效果:
但是这种耦合性高,我们需要解耦,可以使用parent关键字代表这个子类的父类:
<?php
// 父类
class Person {
public function __construct() {
echo '这是父类';
}
}
class Student extends Person {
public function __construct() {
parent::__construct(); // 调用父类的构造函数
echo '这是子类';
}
}
// 测试
new Student();
效果:
例题:给父类传递参数:
<?php
// 父类
class Person {
protected $name;
protected $sex;
public function __construct($name, $sex) {
$this->name=$name;
$this->sex=$sex;
}
}
class Student extends Person {
private $score;
public function __construct($name, $sex, $score) {
parent::__construct($name, $sex); // 调用父类的构造函数并传递参数
$this->score=$score;
}
public function getInfo() {
echo "姓名: {$this->name}<br/>";
echo "性别: {$this->sex}<br/>";
echo "成绩: {$this->score}<br/>";
}
}
// 测试
$stu = new Student('Jack', '男', 18);
$stu->getInfo();
效果:
6.5 多重继承
PHP不允许多重继承,因为多重继承容易产生二义性。
6.6 $this
$this表示当前对象的引用。
在学习的php的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。