面向对象(一)
常见的编程思想
面向过程思想
通过程序的执行顺序为主线开发代码
优点:简单,易学,上手快。
缺点:多人合作不方便
面向对象思想
以组成项目的对象为主线进行开发。在面向对象的思想里面,所有的事物都看成对象。
优点:多人合作方便,代码冗余很少
缺点:学起来比面向过程复杂。
面向对象简介
OOP:面向对象编程(Object Oriented Programming),OOP,面向对象编程
OOAD:OOA和OOD
OOA: 面向对象分析(Object-Oriented Analysis,OOA)
OOD: 面向对象设计(Object-Oriented Design,OOD)
对象
对象是由属性和方法组成的
属性的本质就是变量
方法的本质就是函数
类
类是所有对象共同的属性和方法的组合。
我们在开发时候是通过调用对象的方法或属性来实现某个效果,要调用方法必须先有对象,要想有对象必须先有类。
开发顺序:类——(实例化)对象——调用对象的方法和属性。
类和对象的关系
通过类可以创建多个对象,类就类似于模具,一个模具制造很多形状一致的对象。
类是有父类和子类之分的
再比如:老师是类,语文老师也是类,老师是父类,语文老师是子类。
在PHP中实现类
语法
class 类名{
//属性
//方法
//常量
}
类名的命名规则
- 以字母、下划线开头,后面跟的是字母、数字、下划线
- 一般用帕斯卡命名法
- 不能用PHP关键字做类名
- 类名不区分大小写
实例化对象
实例化:创造实例(对象)的过程
通过new关键字实例化
$对象名=new 类名()
例题
对象的传递
对象的传递的地址传递
操作属性
对象调用属性和方法使用“->”,
语法:
对象名->属性
对象名->方法名()
<?php
//类
class Student {
public $name; //语法结构:访问修饰符+变量名
}
//实例化
$stu1=new Student; //类名后不加()也可以
$stu2=new Student(); //类名后加()也可以
$stu1->name=’tom’; //操作1、给属性赋值
echo $stu1->name,'<br>’; //tom //操作2、显示属性的值
$stu1->add=’beijing’; //操作3、给stu1对象添加add属性
unset($stu2->name); //操作4、删除stu2对象的name属性
var_dump(isset($stu1->name));//bool(true) //操作5:判断属性是否存在
定义方法
语法结构
访问修饰符 function 方法名(参数){
//方法体
}
例题
对象的比较
全等:指向同一个对象是全等
相等:只要属于同一个类,结构和属性值都一致才相等
访问修饰符
用来修饰属性和方法,控制属性和方法的权限
访问修饰符 |
描述 |
Public(公有的) |
在类的内部和外部都能访问 |
private(私有的) |
只能在类的内部访问 |
protected(受保护的) |
在整个继承链上访问 |
例题一
脚下留心:一般来说,属性都是私有的,通过公有的方法对私有的属性进行赋值和取值。这样做可以在方法中对数据进行过滤,提高数据安全性。
<?php
class Student {
public $name; //私有属性
public $sex; //私有属性
//通过公有的方法进行赋值
public function setInfo($name,$sex) {
if($sex!=’男’ && $sex!=’女’){
echo ‘性别只能是男或女<br>’;
return;
}
$this->name=$name; //$this表示调用当前方法的对象
$this->sex=$sex;
}
//通过公有的方法进行取值
public function getInfo() {
echo ‘姓名:’.$this->name,'<br>’;
echo ‘性别:’.$this->sex.'<hr>’;
}
}
//调用
header(‘Content-Type:text/html;charset=utf-8’);
$stu1=new Student;
$stu1->setInfo(‘tom’,’男’);
$stu1->getInfo();
$stu2=new Student;
$stu2->setInfo(‘berry’,’女’);
$stu2->getInfo();
$this
$this在方法的内部使用,表示调用当前方法的对象。
构造函数
普通方法不调用就不执行
构造函数也叫构造方法,在实例化对象的时候自动调用执行
语法一:
Public function __construct(){
}
脚下留心:__construct()前面是两个下划线。
语法二:和类名同名的函数是构造函数
Public function 类名(){
}
例题
脚下留心:推荐使用__construct(),因为__construct()的优先级最高。
构造函数用来初始化成员变量
成员变量就是属性
析构函数
当对象销毁的时候自动调用
语法
Public function __destruct(){
}
代码
脚下留心:
- 构造函数和析构函数是PHP自己调用,不能手动调用
- 构造函数可以带有参数,析构函数不能带有参数。
多学一招:数据的存储和销毁分为两种情况:先进先出(队列)
先进后出(出入栈)
对象在内存中的分布
对象的本质就是复杂变量
类的本质就是复杂的数据类型
分析如下代码
<?php
class Student {
private $name;
private $sex;
public function show() {
echo ‘i am a student<br>’;
}
}
$stu1=new Student(); //将堆区的地址付给栈区的$stu1
$stu1->show();
$stu2=new Student();
$stu2->show();
在内存中结构
堆区特点:体积大,查询速度慢
栈区特点:体积小,查询速度快
基本数据类型的数据都存放在栈区中;复杂数据类型都存储在堆区中,但是堆区中的地址保存到栈区中。
继承
- 代码具有层次结构
- 子类继承了父类的属性和方法,实现了代码的可重用性。
语法
Class 子类 extends 父类{
}
继承的例题
<?php
//父类
class Person {
public $name=’tom’;
public function show() {
echo ‘i am a boy!’;
}
}
//子类
class Student extends Person {
}
//测试
$stu=new Student();
echo $stu->name,'<br>’;
$stu->show();
分析:$stu->name执行过程,首先在Student中寻找$name,如果找到就访问,如果找不到,就到Person类中找$name。
调用父类的属性和方法
在子类中通过$this关键字可以调用父类属性和方法
调用父类的构造方法
父类的构造方法 |
子类的构造方法 |
实例化子类 |
没有 |
有 |
调用子类构造方法 |
有 |
没有 |
调用父类构造方法 |
有 |
有 |
调用子类构造方法 |
总结一句话:如果子类有构造方法就调用子类的,如果子类没有就调用父类的。
通过parent::__construct()调用父类的构造函数
Parent表示父类的名字
给父类传递参数
<?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 show() {
echo “姓名:{$this->name}<br>”;
echo “性别:{$this->sex}<br>”;
echo “成绩:{$this->score}<br>”;
}
}
//测试
header(‘Content-Type:text/html;charset=utf-8’);
$stu=new Student(‘tom’,’男’,88);
$stu->show();
运行结果
parent表示父类的名字
提醒:使用parent关键字可以降低程序的耦合性。
protected(受保护的)
protected修饰的在整个继承链上访问
$this
$this表示当前对象的引用(地址)
封装
通过访问修饰符来封装,有选择性的提供数据。