1.1 介绍
面向对象是一个编思想. 编程思想有面向过程和面向对象.
面向过程: 编程思路集中的是过程上
面向对象: 编程思路集中在参与的对象
1.2 好处
-
多人合作方便
-
减少代码冗余, 灵活性高
-
代码的可用性发挥到极致
-
可扩展性强
OOP: 面向对象编程
OOA: 面向对象分析
OOD: 面向对象设计
1.2 类和对象
1. 对象是具体存在的事物,对象是由属性(变量)和(方法)组成的
2. 类是具体相同属性和行为的一组对象的集合
在开发的时候,先写类, 通过类创建对象, 通过对象调用方法和属性
一个类可以创建多个对象
2 在PHP中实现类和对象
2.1 创建类
class 类名{ //属性 //方法 //常量 } 类是由属性,方法,常量组成的 _________________________________________________________________________ <?php calss Student { }; ?>
命名规则
-
以字母, 下划线开头, 后面跟的是字母, 数字, 下划线
-
不能用PHP关键字做类名
-
类名不区分大小写 (变量名区分, 关键字,类名不区分带小写). 类名用帕斯卡命名法 (大驼峰, 首字母大写)
-
-
2.2 对象实例化
通过new关键字来实例化对象
<?php // 定义类 class Student{ } //实例化 $stu1=new Student(); // 小括号可以省略 $stu2=new Student;
2.3 对象的比较
对象的传递是地址传递
相等: 结构和保存的值一样就相等
全等: 指向同一个对象才是全等
<?php class Stu{ } $stu1=new Stu; $stu2=new Stu; // 对象传递的是地址 $stu3=$stu2; //true var_dump($stu1==$stu2); //false var_dump($stu1===$stu2); //true var_dump($stu2===$stu3);
3 属性 & 方法 & 修饰符
3.1 属性
属性本质就是变量
通过->
调用对象的成员 对象名 -> 属性名 对象名 -> 方法名()
<?php // 定义类 class Stu { public $name; public $add='地址不详'; } // 实例化对象 $stu=new Stu; $stu->name='Tom'; $stu->add='北京'; // 获取属性的值 echo '姓名:'.$stu->name,'<br>'; echo '地址:'.$stu->add,'<br>'; // 添加属性 $stu->age=20; echo '年龄:'.$stu->age,'<br>'; //删除属性 unset($stu->add); print_r($stu); ?>
3.2 方法 方法的本质就是函数
<?php
// 定义类
class Stu{
public function show() {
echo '这是show方法<br>';
}
function test(){
echo '这是test方法<br>';
}
}
// 调用方法
$stu=new Stu;
$stu->show();
$stu->test();
?>
-
方法前面的public是可以省略的, 如果省略, 默认是public
-
属性前面的public不能省略
-
3.3 修饰符
用来控制成员的访问权限
修饰符 | 描述 |
---|---|
public (公有的) | 在类的内部和外部都能访问 |
private (私有的) | 只能在类的内部访问 |
protected (受保护的) | 在整个继承链上访问 |
一般来说,属性都用私有的,通过公有的方法对私有的属性进行赋值和取值
作用: 保证数据的合法性
<?php class Stu{ private $name; private $sex; function setInfo($name,$sex){ if($sex!='男'&&$sex!='女'){ echo '性别必须为男或女'; exit; } $this->name=$name; $this->sex=$sex; } function getInfo(){ echo '姓名: '.$this->name,'<br>'; echo '性别: '.$this->sex,'<br>'; } } $stu=new Stu; $stu->setInfo('tom','男'); $stu->getInfo(); echo '<hr>'; $stu1=new Stu; $stu->setInfo('Sunny','难啊难'); $stu->getInfo(); ?>
4 类和对象在内存中的分布
4.1 分布
-
对象的本质是一个复杂的变量
-
类的本质是一个自定义的复杂数据类型
-
展区: 运行速度快, 体积小, 保存基本类型
-
堆区: 运行速度稍慢, 体积大, 保存复杂类型
-
实例化的过程就是分配内存空间的过程
-
对象保存在堆区, 将堆区的地址保存到栈区
-
-
4.2 计算机的内存管理
计算机内存管理方式: 先进先出, 先进后出
先进先出的内存管理方式一般用在业务逻辑中, 比如秒杀, 购票等等
先进后出是计算机的默认内存管理方式
5 构造方法 & 析构方法
5.1 介绍
构造方法也叫构造函数, 当实例化对象的时候自动执行
<?php // 前面是两个下划线 function __construct(){ } ___________________________________________________________________ class Stu{ function __construct(){ echo '这是构造方法<br>'; } } new Stu(); new Stu(); ?>
在其它语言中, 与类名同名的函数时构造函数, 在PHP中不允许这种写法
5.2 构造函数作用
初始化成员变量
构造函数可以带参数, 但不能有return
<?php class Stu{ private $name; private $sex; function __construct($name,$sex){ $this->name=$name; $this->sex=$sex; } function show(){ echo "姓名: {$this->name}<br>"; echo "性别: {$this->sex}<br>"; } } $stu=new Stu('Wang','男'); $stu->show(); ?>
5.3 析构方法
当对象销毁的时候自动调用
析构函数不可以带参数
function __destruct(){ } ______________________________________________________________ <?php class Stu{ private $name; function __construct($name){ $this->name=$name; echo "{$name}出生了<br>"; } function __destruct(){ echo "{$this->name}销毁了<br>"; } } $stu1=new Stu('Tom'); $stu2=new Stu('Wang'); echo '<hr>'; ?>
6 继承
6.1介绍
-
继承使得代码具有层次结构
-
子类继承父类的属性和方法, 实现代码的可重用性
-
使用extends关键字实现继承
-
父类和子类是相对的
-
-
class 子类 extends 父类{ } ____________________________________________________________ <?php class Person{ function show(){ echo '这是人类<br>'; } } // 子类继承父类 class Stu extends Person{ } $stu=new Stu; $stu->show(); ?>
执行过程
-
在Stu类中查找show(), 如果找到就调用, 找不到就到父类中查找
-
在Person类中查询show()
-
6.2 子类中调用父类成员
<?php class Person{ function show(){ echo '这是人类<br>'; } } // 子类 class Stu extends Person{ function test(){ // 方法一 // $person=new Person(); // $person->show(); // 方法二 $this->show(); } } $stu=new Stu; $stu->test(); ?>
-
通过实例化父类调用父类的成员
-
通过$this关键字调用父类的成员
6.3 protected
protected: 受保护的, 在整个继承链上使用
// 一 <?php class A{ protected $num=10; } class B extends A { function getNum(){ echo $this->num; } } $obj=new B(); $obj->getNum(); ?> ______________________________________________________________________ //二 <?php class A { function getNum(){ echo $this->num; } } class B extends A { protected $num=10; } $obj=new B(); $obj->getNum(); ?> ______________________________________________________________________________ //三 <?php class A { function getNum(){ echo $this->num; } } class B extends A { protected $num=10; } //整个继承链上只有A $obj=new A(); //报错: Notice:Undefined property: A::$num $obj->getNum(); ?>
6.4 继承中的构造函数
-
如果子类有构造函数就调用子类的, 如果子类没有就调用父类的构造函数
-
子类的构造函数调用后, 默认不再调用父类的构造函数
-
通过类名调用父类的构造函数
类名::__construct() _______________________________________________________________________ <?php class Person{ public function __construct(){ echo '这是父类<br>'; } } class Stu extends Person{ public function __construct(){ Person::__construct(); parent::__construct(); echo '这是子类<br>'; } } new Stu(); ?>
parent关键字表示父类的名字, 可以降低程序的耦合性
给父类传递参数
<?php class Person{ protected $name; protected $sex; public function __construct($name,$sex){ $this->name=$name; $this->sex=$sex; } } class Stu 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 Stu('Wang','男',90); $stu->getInfo(); ?>
6.5 $this详解
this表示当前对象的引用, 也就是this保存的当前对象的地址
<?php class A{ public function __construct(){ var_dump($this); } } class B extends A { } new A(); echo '<br>'; new B(); ?>
6.6 多重继承
php不允许多重继承, 因为多次继承容易产生二义性.
如何实现C继承A和B, 使用继承链