第五章 补充案例resource.ityxb.com/uploads/book/php/file/bcal.pdf博学谷——让IT...
Transcript of 第五章 补充案例resource.ityxb.com/uploads/book/php/file/bcal.pdf博学谷——让IT...
博学谷——让 IT 教学更简单,让 IT 学习更有效
第五章 补充案例
案例 5-1 声明类
一、案例描述
1、考核知识点
类的声明
2、练习目标
掌握声明一个类的语法格式
掌握如何在类中声明成员变量和成员方法
3、需求分析
在程序中,设计一个表示学生的类,该类具有以下属性和方法:
该类具有表示姓名的属性
该类具有表示性别的属性
该类具有表示说话行为的 sayHello()方法,并且用于输出学生的姓名。
4、设计思路
1) 使用 class 关键字定义一个表示学生类型的类,类名为 Student。
2) 在 Student 类中定义两个成员变量$name 和$gender,分别用来表示姓名和性别。
3) 在 Student类中定义一个表示说话行为的 sayHello()方法,用于输出学生的姓名。
二、案例实现
声明一个 student 类,并为增加相应的属性与方法:
class Student{
public $name;
public $gender ='male';
public function sayHello(){
return ‘大家好,我是‘ . $this->name;
}
}
三、案例总结
1、PHP 中类名对大小写不敏感,而属性名对大小写敏感,方法名对大小写不敏感。
2、public 关键字表示成员为公共的。
3、$this 变量用来在成员方法内表示当前对象。
博学谷——让 IT 教学更简单,让 IT 学习更有效
4、->语法用来访问对象的成员。
案例 5-2 实例化
一、 案例描述
1、考核知识点
类的实例化
2、练习目标
掌握类的实例化过程
掌握类实例化的语法格式
3、需求分析
在程序中,设计一个表示学生的类 Student,该类具有以下属性和方法:
该类具有表示姓名的属性
该类具有表示性别的属性
该类具有表示说话行为的 sayHello()方法,并且用于输出学生的姓名。
4、设计思路
1) 使用 class 关键字定义一个表示学生类型的类,类名为 Student。
2) 在 Student 类中定义两个成员变量$name 和$gender,分别用来表示姓名和性别。
3) 在 Student类中定义一个表示说话行为的 sayHello()方法,用于输出学生的姓名。
4) 使用 new 关键字创建一个 Student 类的实例对象,在实例化对象时为对象开辟
内存空间,并初始化其属性。
二、案例实现
声明一个 student 类与的属性与方法,实例化该类。
//声明类
class Student{
public $name;
public $gender = 'male';
public function sayHello(){
return '大家好,我是' . $this->name;
}
}
//实例化
$stu = new Student;
//并测试输出
var_dump($stu);
var_dump($stu->name);
var_dump($stu->gender);
$stu->name = '王翦';
博学谷——让 IT 教学更简单,让 IT 学习更有效
echo $stu->sayHello();
以上代码输出结果
三、案例总结
1、var_dump()可以输出变量的详细信息
2、没有默认值的属性被初始化为 NULL
3、利用->可以访问属性与调用方法。
案例 5-3 构造方法
一、案例描述
1、考核知识点
构造方法初始化对象
2、练习目标
掌握构造方法的声明与使用
3、需求分析
在 PHP 中,实例化类得到对象过程中,会自动调用构造方法,通常负责完成对象
的初始化工作。
4、设计思路
1) 同样在 Student 类中定义两个成员变量$name 和$gender。
2) 创建一个名为__construct()的方法为构造方法。
3) 使用 new 关键字创建一个 Student 类的实例对象,并且在实例化的过程中被调
用构造方法,而且允许在实例化时传递参数。
二、案例实现
声明一个 student 类与的属性与方法,实例化该类,并提供构造方法,对对象进行初始
化工作。
class Student{
public $name;
public $gender = 'male';
// public function Student($name, $gender=null) {//类同名方法
public function __construct($name, $gender=null) {
$this->name = $name;
if (!is_null($gender)) {
博学谷——让 IT 教学更简单,让 IT 学习更有效
$this->gender = $gender;
}
}
public function sayHello(){
return '大家好,我是' . $this->name;
}
}
//实例化
$stu1 = new Student('廉颇');
//并测试输出
var_dump($stu1->name);
var_dump($stu1->gender);
$stu2 = new Student('蔡文姬', 'female');
//并测试输出
var_dump($stu2->name);
var_dump($stu2->gender);
以上代码输出结果
三、案例总结
1、构造方法名__construct 为固定的构造方法名称,注意是双下划线开头。
2、new 实例化类名后可向构造方法传递参数
3、参数可以提供默认值
4、PHP 为了保证向下兼容,还支持类同名方法为构造方法。
案例 5-4 析构方法
一、案例描述
1、考核知识点
析构方法
2、练习目标
掌握构造方法的声明与使用
3、需求分析
在 PHP 中,对象被销毁的过程中,会自动调用析构方法,通常负责完成对象收尾
博学谷——让 IT 教学更简单,让 IT 学习更有效
工作。
4、设计思路
1) 同样在 Student 类中定义两个成员变量$name 和$gender。
2) 创建一个名为__destruct()的方法为析构方法,如果被声明,则在对象被销毁的
过程中被调用。不需要参数。
二、案例实现
声明一个 student 类与的属性与方法,实例化该类,对对象进行初始化工作。提供析构
方法,在对象被销毁时,自动将该对象持久化到数据库学生表。
class Student{
public $name;
public $gender = 'male';
public function __construct($name, $gender=null) {
$this->name = $name;
if (!is_null($gender)) {
$this->gender = $gender;
}
}
public function __destruct() {
//根据实际情况改写用户密码
$link = mysql_connect('localhost:3306', 'someUser', 'somePass');
//根据实际情况改写字符集
mysql_query('set names someCharset', $link);
mysql_query("insert into someDB.student (name, gender) values
('$this->name", "$this->gender");
}
}
unset($stu2);
//$stu2 = null;//也可以销毁对象,null是其他数据亦可
案例结果:
相应的 student 表内,会出现一条(蔡文姬,female)的记录。
三、案例总结
1、析构方法名__destruct 为固定的析构方法名称,注意是双下划线开头。
2、析构方法自动执行。
3、unset 一个对象变量,可以销毁该对象。
4、销毁对象的方法除 unset 外,还可以对象变量引用一个新数据,或者在脚本周期结
束时自动销毁。析构方法都会执行。
博学谷——让 IT 教学更简单,让 IT 学习更有效
案例 5–5 对象间赋值与引用
一、案例描述
1、考核知识点
对象间的赋值与引用
2、练习目标
掌握对象保存内容为对象标识。
3、需求分析
在 PHP 中,使用一个对象为另一个变量赋值,分析两个变量间的关系。
4、设计思路
对象间的赋值过程中,仅仅赋值的为对象的标识,导致多个对象变量所表示的为一
个对象。效果类似变量间的引用传递。
1) 同样在 Student 类中定义两个成员变量$name 和$gender。
2) 创建一个名为__construct()的构造方法,并在该方法中传递两个参数。
3) 实例化一个 Student 对象 stu1,然后将该对象赋值给 stu2,最后输出两个对象
的名字。
二、案例实现
声明一个 student 类,实例化该类,对对象进行赋值工作。
class Student{
public $name;
public $gender = 'male';
public function __construct($name, $gender=null) {
$this->name = $name;
if (!is_null($gender)) {
$this->gender = $gender;
}
}
}
$stu1 = new Student('蔡文姬', 'female');
$stu2 = $stu1;//赋值
echo $stu2->name;
echo '<br>';
$stu1->name = '曹操';//修改$stu1的属性
echo $stu2->name;//测试$stu2的属性
案例结果:
博学谷——让 IT 教学更简单,让 IT 学习更有效
三、案例总结
1、赋值后两个变量保存的为同一个对象。
2、效果类似引用传递。
3、实质为保存对象的标识。导致结果为同一个对象。
4、无论对象变量间为值传递,还是引用传递,结果都导致变量内为同一个对象标识,
因此建议不需要在对象赋值时使用引用传递。
5、实现原理如图所示:
案例 5-6 对象克隆
一、案例描述
1、考核知识点
对象克隆
2、练习目标
掌握克隆对象的方法
3、需求分析
在 PHP 中,对象保存的方式为标识,赋值方式不能得到新对象,需要采用克隆方
法。
4、设计思路
clone 关键字可以完成对象的克隆,克隆意味着形成属性完全一致的新对象,但是
内部的对象标识是不同的。
博学谷——让 IT 教学更简单,让 IT 学习更有效
二、案例实现
声明一个 student 类与的属性与方法,实例化该类,对对象进行初始化工作。利用实例
化好的对象,克隆出来一个新对象。
克隆测试:
class Student{
public $name;
public $gender = 'male';
public function __construct($name, $gender=null) {
$this->name = $name;
if (!is_null($gender)) {
$this->gender = $gender;
}
}
}
$stu1 = new Student('蔡文姬', 'female');
$stu2 = clone $stu1;
var_dump($stu1, $stu2);
案例结果:
克隆魔术方法测试__clone();
class Student{
public $name;
public $gender = 'male';
public $is_clone = false;
public function __construct($name, $gender=null) {
$this->name = $name;
if (!is_null($gender)) {
$this->gender = $gender;
}
}
public function __clone() {
$this->is_clone = true;
}
}
$stu1 = new Student('蔡文姬', 'female');
$stu2 = clone $stu1;
var_dump($stu1, $stu2);
博学谷——让 IT 教学更简单,让 IT 学习更有效
测试结果:
三、案例总结
1、标识不一致,但属性相同,是一个新对象。
2、克隆过程中,可以调用新对象的__clone()方法,对一些必要的属性进行修改。
3、__clone()方法中的$this 为克隆出来的新对象。
案例 5-7 静态成员
一、案例描述
1、考核知识点
静态成员的声明与使用
2、练习目标
掌握静态成员的使用
3、需求分析
在 PHP 中,当成员属性或者成员方法被所有对象所共享时,可以将成员声明称静
态的。
4、设计思路
1)static 关键字声明静态成员,访问时采用静态访问符号::来使用类来访问。
2)类外使用类名访问静态成员,而类内使用 self 关键字代替本类访问静态成员。
二、案例实现
声明一个 student 类,增加静态成员来记录学生数量与获取学生数量。每当实例化一个
学生对象,或者克隆学生对象,学生数量增加,销毁一个对象,学生数量减少。
class Student {
//属性
private $name;//非静态属性
private $gender;//对象属性
private static $counter = 0;//计算器
public function __construct($n, $g) {
$this->name = $n;
$this->gender = $g;
++ self::$counter;
}
博学谷——让 IT 教学更简单,让 IT 学习更有效
public function __clone() {
++ self::$counter;
}
public function __destruct() {
-- student::$counter;
}
public static function getCounter() {
return self::$counter;
}
}
$stu1 = new Student('蔡文姬', 'female');
$stu2 = new Student('曹操', 'male');
$stu3 = new Student('甄姬', 'female');
echo '当前学生为:', Student::getCounter() , '名学生<br>';
$stu4 = clone $stu3;
unset($stu1);
unset($stu2);
echo '当前学生为:', Student::getCounter() , '名学生<br>';
案例结果:
三、案例总结
1、static 可以声明属性或方法为静态成员
2、静态成员使用类::静态访问符号访问。
3、静态成员为所有的对象多共享,不应该使用对象->访问。
4、self 关键字表示本类的含义,不能在类外使用,在方法中使用。
案例 5-8 类常量
一、案例描述
1、考核知识点
类常量
2、练习目标
掌握类常量的使用
博学谷——让 IT 教学更简单,让 IT 学习更有效
3、需求分析
在 PHP 中,如果需要定义类所使用的常量值,可以定义类常量。
4、设计思路
const 关键字用于定义常量,语法为 const 常量名 = 常量值。声明时不需要使用访
问修饰限定符。访问时类似静态成员,使用双冒号范围解析操作符(::)访问,类
内可以使用 self 来访问。
二、案例实现
声明一个 student 类,使用类常量来设定某些枚举值的数据,例如性别。
class Student {
const GENDER_MALE = 1;
const GENDER_FEMALE = 2;
const GENDER_SECRET = 0;
//属性
private $name;//非静态属性
private $gender;//对象属性
public function __construct($n) {
$this->name = $n;
}
public function setGender($g = Student::GENDER_SECRET) {
$this->gender = $g;
}
}
$stu1 = new Student('蔡文姬');
$stu1->setGender();
var_dump($stu1);
$stu2 = new Student('曹操');
$stu2->setGender(Student::GENDER_MALE);
var_dump($stu2);
案例结果:
三、案例总结
1、const 关键字用来声明类常量,一旦声明不能修改。
2、使用类::常量名的形式访问类常量。
3、声明类常量时不需要使用访问修饰限定符。
4、类内也可以使用 self 来访问类常量。
博学谷——让 IT 教学更简单,让 IT 学习更有效
案例 5-9 继承
一、案例描述
1、考核知识点
继承
2、练习目标
掌握如何将多个对象的特征封装到父类中。
3、需求分析
在 PHP 的 OOP 中,如果需要将多个对象的特征提取,则可以定义其父类,然后子
类继承。
4、设计思路
extends 关键字可以完成继承。将公共成员定义在父类,将特有成员定义在子类,
实例化子类对象时,就可以得到所有的公共和特有成员了。
二、案例实现
声明一个 goods 商品类,存在其子类 book,和 phone 分别是不同的商品
class goods {
public $name;
public $price;
public function __construct($name, $price) {
$this->name = $name;
$this->price = $price;
}
public function getName() {
return $this->name;
}
public function getPrice() {
return $this->price;
}
}
//书商品
class book extends goods {
public $author;
public $publisher;
}
//电话商品
class phone extends goods {
public $brand;
public $color;
博学谷——让 IT 教学更简单,让 IT 学习更有效
}
$book1 = new book('PHP核心技术', 85);
$phone1 = new phone('Nokia 1110', 110);
var_dump($book1, $phone1);
案例结果:
三、案例总结
1、extends 关键字可以完成继承
2、继承只能是单继承,一个子类只能存在一个父类。
3、子类对象可以得到父类定义的成员。
4、一个父类可以存在多个子类
案例 5-10 重写
一、案例描述
1、考核知识点
重写
2、练习目标
掌握重写现象,使用 parent 调用父类方法
3、需求分析
在 PHP 的 OOP 中,如果子类定义的成员与父类定义的成员同名,则会出现重写现
象,导致子类中访问到的仅仅是子类中定义的成员。
4、设计思路
如果子类中对父类中定义的方法不能满足要求,可以将其重新定义,实现为自己需
要的功能。但是如果同时需要显式调用父类中被重写的成员,则可以使用 parent::
来访问,典型的是构造方法等。
二、案例实现
声明一个 goods 商品类,存在其子类 book,构造方法重写,但实现时 parent 强制调用
父类的构造方法,而 getName()直接重写。
class goods {
public $name;
public $price;
博学谷——让 IT 教学更简单,让 IT 学习更有效
public function __construct($name, $price) {
$this->name = $name;
$this->price = $price;
}
public function getName() {
return $this->name;
}
public function getPrice() {
return $this->price;
}
}
//书商品
class book extends goods {
public $author;
public $publisher;
public function __construct($author, $publisher, $name, $price) {
parent::__construct($name, $price);
$this->author = $author;
$this->publisher = $publisher;
}
public function getName() {
return '《' . $this->name . '》';
}
}
$book1 = new book('PHP教研组', 'ITCAST', 'PHP核心技术', 85);
echo $book1->getName();
案例结果:
三、案例总结
1、重写会导致父类成员不能访问到。
2、父类方法可以使用 parent::关键字来显式访问。
3、重写方法的参数数量要求一致。
博学谷——让 IT 教学更简单,让 IT 学习更有效
案例 5-11 抽象类抽象方法
一、案例描述
1、考核知识点
抽象类与抽象方法
2、练习目标
掌握抽象类与抽象方法的声明与使用
掌握在何时应该使用抽象类或抽象方法
3、需求分析
在 PHP 中,如果需要限制一个类不能实例化,而只能被继承使用,则将其声明为
抽象类,同时如果需要限制子类中必须要重写那个方法,可以将某个方法声明为抽
象方法。
4、设计思路
abstract 关键字可以将类或方法声明称抽象的,其中如果一个方法被声明称抽象的,
那么该方法应该只具备方法声明部分,不能该存在方法实现部分。
二、案例实现
将父类商品类声明为抽象类,而其中方法 getName 声明为抽象方法,子类必须要将其
实现,但可以分别以不同的方式来实现。
abstract class goods {
public $name;
public $price;
public function __construct($name, $price) {
$this->name = $name;
$this->price = $price;
}
abstract function getName();
public function getPrice() {
return $this->price;
}
}
//书商品
class book extends goods {
public $author;
public $publisher;
public function __construct($author, $publisher, $name, $price) {
parent::__construct($name, $price);
$this->author = $author;
$this->publisher = $publisher;
博学谷——让 IT 教学更简单,让 IT 学习更有效
}
public function getName() {
return '《' . $this->name . '》';
}
}
//电话商品
class phone extends goods {
public $brand;
public $color;
public function getName() {
return $this->name;
}
}
$good = new goods('商品', '100.1');//失败
案例结果:
不能实例化 goods 类对象,而子类 book 和 phone 必须有 getName 方法。
三、案例总结
1、abstract 可以声明类与方法
2、抽象方法不能存在方法体
3、子类继承抽象类,必须要重写父类中的抽象方法。
4、抽象类不能用于实例化对象。
5、使用抽象类可以保证子类中必须存在,但是可以实现不一致的方法。
案例 5-12 final 类和 final 方法
一、案例描述
1、考核知识点
final 类、final 方法、final 关键字
2、练习目标
掌握 final 类与 final 方法的用法。
3、需求分析
在 PHP 中,如果需要限制一个类不能被继承,而只能实例化,则将其声明为 final
类,同时如果需要限制子类中不能重写某个方法,可以将某个方法声明为 final 方
法。
4、设计思路
final 关键字可以将类或方法声明称最终的,其中如果一个方法被声明称 fianl 的,
那么该方法在子类中不能被重写。
博学谷——让 IT 教学更简单,让 IT 学习更有效
二、案例实现
可将子类声明为 final 的防止被继承,而将父类中的方法声明为 final 方法子类中不能重
写。
abstract class goods {
public $name;
public $price;
public function __construct($name, $price) {
$this->name = $name;
$this->price = $price;
}
abstract function getName();
final public function getPrice() {
return $this->price;
}
}
//书商品
final class book extends goods {
public $author;
public $publisher;
public function __construct($author, $publisher, $name, $price) {
parent::__construct($name, $price);
$this->author = $author;
$this->publisher = $publisher;
}
public function getName() {
return '《' . $this->name . '》';
}
// public function getPrice() {//出错不能被重写
// }
}
案例结果:
book 类不能被继承,而 getPrice 方法也不能被重写。
三、案例总结
1、final 关键字用来声明类与方法。
2、final 类不能被继承,final 方法不能被重写
3、如果需要保证子类中必须存在实现一致的方法,可以将方法声明为 final 的。
博学谷——让 IT 教学更简单,让 IT 学习更有效
4、如果认为类不能被扩展继承,则可以将类声明为 final 的。
案例 5-13 抽象类抽象方法
一、案例描述
1、考核知识点
抽象类与抽象方法
2、练习目标
掌握抽象类与抽象方法的声明与使用。掌握在何时应该使用抽象类或抽象方法。
3、需求分析
在 PHP 中,如果需要限制一个类不能实例化,而只能被继承使用,则将其声明为
抽象类,同时如果需要限制子类中必须要重写那个方法,可以将某个方法声明为抽
象方法。
4、设计思路
abstract 关键字可以将类或方法声明称抽象的,其中如果一个方法被声明称抽象的,
那么该方法应该只具备方法声明部分,不能该存在方法实现部分。
二、案例实现
将父类商品类声明为抽象类,而其中方法 getName 声明为抽象方法,子类必须要将其
实现,但可以分别以不同的方式来实现。
abstract class goods {
public $name;
public $price;
public function __construct($name, $price) {
$this->name = $name;
$this->price = $price;
}
abstract function getName();
public function getPrice() {
return $this->price;
}
}
//书商品
class book extends goods {
public $author;
public $publisher;
public function __construct($author, $publisher, $name, $price) {
parent::__construct($name, $price);
博学谷——让 IT 教学更简单,让 IT 学习更有效
$this->author = $author;
$this->publisher = $publisher;
}
public function getName() {
return '《' . $this->name . '》';
}
}
//电话商品
class phone extends goods {
public $brand;
public $color;
public function getName() {
return $this->name;
}
}
$good = new goods('商品', '100.1');//失败
案例结果:
不能实例化 goods 类对象,而子类 book 和 phone 必须有 getName 方法。
三、案例总结
1、abstract 可以声明类与方法
2、抽象方法不能存在方法体
3、子类继承抽象类,必须要重写父类中的抽象方法。
4、抽象类不能用于实例化对象。
5、使用抽象类可以保证子类中必须存在,但是可以实现不一致的方法。
案例 5-14 接口技术
一、案例描述
1、考核知识点
接口的定义与使用
2、练习目标
掌握接口的使用环境,interface 关键字与 implements 的使用。
3、需求分析
在 PHP 中,如果需要规定一个对象应该具备哪些公共接口方法,可以使用类来实
现某种接口。
4、设计思路
博学谷——让 IT 教学更简单,让 IT 学习更有效
interface 可以声明接口,类需要实现接口,将接口中定义的所有抽象方法全部实现,
该类才能是一个非抽象类。
二、案例实现
在所有的支付方法中都需要与第三方支付平台交互,因此来限定所有的支付方法都具有
统一的交互方法。
interface I_payment {
public function send() ;//发送支付请求的方法
public function respon() ;//处理支付响应的方法
}
//某种支付方法
class alipay implements I_payment {
public function send() {
}
public function respon() {
}
}
//其他支付方法
class otherPay implements I_payment {
public function send() {
}
public function respon() {
}
}
案例结果:
此时可以保证所有的支付方法都可以统一调用。从而实现各种支付方式的任意切换。
三、案例总结
1、interface 声明接口
2、implements 实现接口
3、接口中的抽象方法不需要使用 abstract 关键字
4、接口中的方法都需要声明为公共的 public 的。
5、实现接口的类,需要将所有的的接口方法都实现。
6、如果需要限定一些类应该具备的公共操作,可以使用接口技术完成。
博学谷——让 IT 教学更简单,让 IT 学习更有效
案例 5-15 访问修饰限定符
一、案例描述
1、考核知识点
访问修饰符
2、练习目标
掌握三种访问修饰限定符的具体使用细则。
掌握如何正确的使用访问修饰限定符。
3、需求分析
体现对象的封装性,将隐藏内部实现,此时需要使用访问修饰来限定哪些是内部实
现,哪些为公共接口。
4、设计思路
在定义类时,需要体现封装性,即隐藏内部实现,开放外部接口。将成员都声明尽
量都声明为私有的,仅仅将一些必要的公共方法。
二、案例实现
学生对象的所有的属性都是私有的,如果需要设置或者获得,需要增加 setter()与 getter()
方法来处理。
class student {
private $name;
private $age;
private $height;
public function __construct($n, $a, $h) {
$this->name = $n;
$this->age = $a;
$this->height = $h;
}
public function setName($n) {
$this->name = $n;
}
public function getName() {
return $this->name = $n;
}
}
案例结果:
博学谷——让 IT 教学更简单,让 IT 学习更有效
不能直接访问属性,需要使用 set 或者 get,在实现 set 和 get 时,增加适当的业务逻辑
验证,可以使用设定和获得变得更加严谨。
三、案例总结
1、public 公共的,在类内与继承链上,和类外都可以访问。
2、protected 包含的,在类内与继承链上可以访问。
3、private 私有的,仅仅在本类内可以访问。
4、选择的依据是尽量体现封装性。
5、注意私有成员在继承时的问题。