第 5 章 静态属性/静态方法
1.1 先看一个问题
l 我们先使用传统的方法解决-思路:
我们可以先定义一个全局变量$total_num; 当有一个小孩子加入游戏时,我们就把这个变量+1;
l 使用全局变量来搞定
说明:上面的代码解决问题,但是不是纯的OOP, 因为出现了全局变量,因此需要使用新的方案-->静态变量。
l 使用静态变量解决问题-代码
示意图:
5.2 静态属性基本介绍
概念:静态属性是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量。这个从前面的图也可看出来.
5.3 如定义一个静态变量
访问修饰符 static $变量名;
说明一下,类的静态变量的定义,要放到类中。
5.4 如何访问静态变量
l 代码说明:
5.5 静态属性的注意事项
l $this和self的区别
l 其它注意事项
代码说明:
其它注意点:
l 静态属性的练习题
代码 :
5.6 静态方法
l 基本的介绍
基本语法是:
访问修饰符 static function 函数名{ 函数体;}
l 快速入门案例
l 关于静态方法的使用细节
(1) 什么时候,我们会使用到静态方法呢?
答: 在后面我们学习单例模式时,就是静态方法的经典使用案例.因为静态方法有一个特点,不需要创建对象实例就可以调用.
(2) 在类外部调用静态方法: 类名::静态方法名 或者 对象名->静态方法名 或者 对象名::静态方法(语法支持,但是不推荐)
(3) 在类内部调用静态方法: self::静态方法名 或者 类名::静态方法名 , 通过 $this也可以
(4) 注意:静态方法中不能访问非静态属性(普通属性, 没有static)。****普通的成员方法,可以访问静态属性****。
代码:
5.7 静态属性的小结
5.8 静态方法的小结
5.9 单例模式
l 看需求分析
l 代码实现11
第一种写法:
第二种写法:
l 练习题
评讲:
第 6 章 面向对象编程的三大特征
1.1 抽象这个概念
抽象:是一种研究分析问题方法,就是把一类事物的共有的属性和行为(方法)提取出来,形成一个类。这种思想就是抽象的思想。
举例说明:
代码:
6.2 封装
l 基本概念
l 如何实现封装
l 举例说明这三个访问修饰符:
l 看一个关于封装的案例
6.3 访问protected , private属性的三种方式
l 第一种方式
代码说明:
说明: 使用__get 和 __set 方法来操作 属性
(1) 优点:简单,较为统一.
(2) 缺点:不够灵活.
l 第二种操作protected 和 private 的属性的方式
代码说明:
l 第三种方式-直接写一个public函数,来操作protected 和 private 属性
关于选择哪种方式的说明
(1) 主要是根据需求来决定的.
(2) setXxx 和 getXxx 方式针对单个的属性分别操作的.
(3) 第三种方式可以通过一个public的函数来操作多个属性,这样比较通用.
(4) 使用的概率大还是第二种和第三种. 第一种使用比较少.
l 访问修饰符的使用的注意
代码说明:
l 封装的练习题
6.4 对象运算符的连用现象
案例:
需求是,通过学生找到该学生对于的班级信息.
对应的练习题:
6.5 继承
6.5.1 为什么需要继承
先看一个问题:
l 分析上面的问题和解决思路
l 使用继承后的代码如下
fen = $fen;
}
public function showInfo(){
echo '
学生的名字是 ' . $this->name . ' 学生的年龄是 ' . $this->age . ' 学生成绩是 ' . $this->fen;
}
}
//子类,扩展类
class Pupil extends Student{
public function testing(){
echo '
小学生在考试...';
}
}
//使用一下
$pupil1 = new Pupil();
$pupil1->name = '小马';
$pupil1->age = 10;
$pupil1->testing();
$pupil1->setFen(80);
$pupil1->showInfo();
//定义类, 大学生
//子类,扩展类
class Graduate extends Student{
public function testing(){
echo '
大学生在考试...';
}
}
//使用一下
$graduate1 = new Graduate();
$graduate1->name = '老马';
$graduate1->age = 30;
$graduate1->testing();
$graduate1->setFen(90);
$graduate1->showInfo();
6.5.2 继承的介绍
6.5.3 继承的细节说明
l 父类的public修饰符的属性和方法,protected修饰符的属性和方法被子类继承了并可以访问
代码说明:
l 继承的本质
继承发生了什么?
说明:
继承不能简单的理解成子类定义时,会把父类的属性声明,方法定义拷贝一份,而是建立了继承查找的的关系.
举例说明:
示意图:
l 子类最多只能继承一个父类(指直接继承)
即: php的OOP编程是单继承机制.
l 子类可以继承其父类(或者基类)的 public ,protected修饰的变量(属性) 和 函数(方法)
l 在创建某个子类对象时,默认情况下会自动调用其父类的构造函数(指在 子类没有自定义构造函数情况时), 如果子类自己有构造函数,则调用自己构造函数.
案例说明:
l 如果在子类中需要访问其父类的方法(构造方法/成员方法 而且方法的访问修饰符是public/protected),可以使用父类::方法名(或者 parent::方法名 ) 来完成
l 如果子类(扩展类)中的方法和父类(基类)方法相同,我们称为方法重写
l 类定义的进一步完善
l 作业练习题
name;
}
}
class Pupil extends Student{
private $grade;
protected $tel_phone;
public $school_name;
//构造函数
public function __construct($grade, $tel_phone, $school_name, $name, $age, $my_class, $major){
$this->grade = $grade;
$this->tel_phone= $tel_phone;
$this->school_name = $school_name;
//怎样给自己继承的父类的属性赋值?
//1. 直接在子类中对继承的属性赋值
$this->name = $name;
$this->age = $age;
$this->my_class = $my_class;
$this->major = $major;
}
}
$pupil = new Pupil(70, 123456789, '北京小学', '小白', 10, '小学1年级', '美术专业');
echo '';
var_dump($pupil);
$pupil->showName();
第二种思路:
name;
}
//构造函数
public function __construct($name, $age, $my_class, $major){
$this->name = $name;
$this->age = $age;
$this->my_class = $my_class;
$this->major = $major;
}
}
class Pupil extends Student{
private $grade;
protected $tel_phone;
public $school_name;
//构造函数
public function __construct($grade, $tel_phone, $school_name, $name, $age, $my_class, $major){
$this->grade = $grade;
$this->tel_phone= $tel_phone;
$this->school_name = $school_name;
//怎样给自己继承的父类的属性赋值?
parent::__construct($name, $age, $my_class, $major);
}
}
//$student = new Student('犀牛精', 400, '大神一期', '腾云');
$pupil = new Pupil(56, 3456789000, '火云洞', '犀牛精', 400, '大神一期', '腾云');
echo '';
var_dump($pupil);
6.5.4 方法重载
l 传统****的意义上的方法重载指一个标识符被用作多个方法名,且能够通过方法的参数个数或参数类型将这些同名的函数区分开来,调用不发生混淆。调用的时候,虽然方法名字相同,但根据参数不同可以自动调用对应的函数。
代码说明一下:
l php中如何实现重载
代码实现:
l __callStatic 的使用
(1) 基本使用案例
(2) 使用__callStatic 实现静态方法的重载
l 练习题:
6.5.5 属性的重载
概述: 可以通过__set 和 __get来实现属性重载
代码说明:
如果你不希望程序员使用到属性重载的现象.
6.5.6 方法的重写
l 问题的引出
既然子类可以继承父类的属性和方法,这样可以提高代码的复用性,这个很好,问题来了,假设现在我要求大家写三个类 猫猫,狗狗,猪猪.我们知道这三个东东都是动物,动物必然存在相同的特点。根据类的抽象特征,我们可以把它们的相同点提取出来,形成一个父类 Animal,然后继承
l 一个子类中有一个方法,和父类的某个方法是完全一样的,那么我们就称为,子类的方法重写了父类的方法。
l 方法重写的基本用法
l 方法重写概念再说明
l 方法重写的细节
(1) parent::静态属性 [这种方式不能访问普通属性,但是能访问父类的静态属性,而且这个静态属性的访问控制符必须是public 或者 protected]
(2) 如果子类要重写父类的某个方法,则要求子类的方法名和参数个数要和父类的那个方法完全一样
代码:3
上面的写法,因为子类的cry 和 父类的 cry 的参数个数不一样,因此报错.
l 对方法重写的细节总结
对应的代码:
6.5.7 属性重写
基本概念:** 注意点**:
1. public 和 protected可以被重写。
2. private 的属性不能被重写
代码说明:
l 重写的练习题
6.6 多态
l 基本介绍:
代码说明:
l 练习题,请大家看PPT
6.7 类型约束补讲(重点!)
接口也可以用于类型约束
l 类型约束不能用于标量类型如 [int]或 [string]。[Traits] 也不允许