[TOC] ## 单态(单例、单件)设计模式 单态模式的主要作用是保证在面向对象编程设计中,一个类只能有一个实例对象存在。 ``` <?php class DB { private static $obj = null; //声明一个私有的,静态的成员属性$obj private function __construct() { //私有构造方法,只能在类的内部实例化对象 echo "连接数据库成功<br>"; } public static function getInstance() { // 通过此静态方法才能获取本类的对象 if(is_null(self::$obj)) //如果本类中的$obj为空,说明还没有被实例化过 self::$obj = new self(); //实例化本类对象 return self::$obj; //返回本类的对象 } public function query($sql) { //执行SQL语句完成对数据库的操作 echo $sql; } } $db = DB::getInstance(); //只能使用静态方法getInstance()去获取DB类的对象 $db -> query("select * from user"); //访问对象中的成员 ``` ``` <?php /* * 单态(单例, 单件)设计模式 -- 最适合PHP使用这个设计模式 * 1. 如果想让一个类, 只能有一个对象, 就要先让这个类, 不能创建对象 , 将构造方法 private * 2. 可以在类的内存使用一个表态方法,来创建对象 */ class Person { static $obj = null; private function __construct() { } static function getObj() { //如果第一次调用时, 没有对象则创建, 以后调用时, 直接使用第一次创建的对象 if(is_null(self::$obj)) self::$obj = new self; return self::$obj; } function __destruct() { echo "################<br>"; } function say() { echo "aaaaaaaaaaaaaaaaa<br>"; } } $p = Person::getObj(); $p = Person::getObj(); $p = Person::getObj(); $p = Person::getObj(); $p = Person::getObj(); $p = Person::getObj(); $p = Person::getObj(); $p -> say(); ``` ## PHP抽象方法和抽象类 在OOP语言中,一个类可以有一个或多个子类,而每个类都有至少一个公有方法做为外部代码访问其的接口。而抽象方法就是为了方便继承而引入的。 当类中有一个方法,他没有方法体,也就是没有花括号,直接分号结束,象这种方法我们叫抽象方法,必须使用关键字abstract定义。 如: public abstract function fun(); 包含这种方法的类必须是抽象类也要使用关键字abstract加以声明。(即使用关键字abstract 修饰的类为抽象类) 抽象类的特点: 不能实例化,也就是不能new成对象 **若想使用抽象类,就必须定义一个类去继承这个抽象类,并定义覆盖父类的抽象方法(实现抽象方法)。** **其实抽象类对于子类(实现类),有一个约束的作用**, 含有抽象方法的类肯定是抽象类,但是不是所有的抽象类都必须包含抽象方法。 ``` <?php /* * 1. 什么是抽象方法 ? * 定义: 一个方法如果没有方法体(一个方法,不使用"{}", 直接使用分号结束的方法,才是没有方法体的方法 ),则这个方法就是抽象方法 * 一、 声明一个方法,不使用{},而直接分号结束 * 二、如果是抽象方法,必须使用 abstract(抽象关键字来修饰) * 2. 什么是抽象类 ? * 一、 如果一个类中有一个方法是抽象的方法, 则这个类就是抽象类 * 二、如果声明一个抽象类, 则这个类必须要使用 abstract关键字来修饰 * 注意: * 1. 只要使用 abstract修饰的类, 就是抽象类 * 2. 抽象类是一种特殊的类, 特殊在哪里(在抽象类中可以有抽象方法) * 3. 除了在抽象类中可以有抽象方法,以外,和正常的类完全一样 * 注意2: * 1. 抽象类不能实例化对象(不能创建出对象) * 2. 如果看见抽象类, 就必须写这个类的子类, 将抽象类中的抽象方法覆盖(加上方法体) * 3. 子类必须全部实现(覆盖重写)抽象方法, 这个子类才能创建对象, 如果只实现部分, 那么还有抽象方法,则类也就必须是抽象类 * 抽象方法作用: * 抽象方法的作用就是规定了,子类必须有这个方法的实现, 功能交给子类 * 只写出来结构, 而没有实现, 实现交给具体的子类(按自己的功能)去实现 * 抽象类的作用: * 就是要求子类的结构, 所以抽象类就是一个规范 */ abstract class Person { public $name; public $age; //特殊的方法抽象方法的存在 abstract function say(); abstract function eat(); function run() { echo "11111111111111<br>"; } function sleep() { echo "2222222222222222<br>"; } } class StudentCn extends Person { function say() { echo "我是中国人,我说中文<br>"; } function eat() { echo "我是中国人,我用筷子吃饭"; } } class StudentEn extends Person { function say() { echo "I am English ,i say english<br>"; } function eat() { echo "我是外国人, 我用刀子和叉子吃饭"; } } $s1 = new StudentEn(); $s1 -> say(); $s1 -> eat(); ``` ## PHP面向对象接口技术 PHP与大多数面向对象编程语言一样,不支持多重继承,也就是说每个类只能继承一个父类。为了解决这个这个问题,PHP引入了接口,接口的思想是指定了一个实现了该接口的类必须实现的一系列函数。 > 抽象类与接口的区别 **定义** 1. 抽象类表示该类中可能已经有一些方法的具体定义。 1. 接口就仅仅只能定义各个方法的界面,不能有具体的实现代码在成员方法中。 **用法** 1. 抽象类是子类用来继承的,当父类已有实际功能的方法时,该方法在子类中可以不必实现。 2. 实现一个接口,必须实现接口中所有定义的方法,不能遗漏任何一个。 ``` <?php /* 抽象类是一种抽象的类, 接口是一种特殊的抽象类, 接口也是一种特殊特殊的类 * 1. 抽象类和接口中都有抽象方法 * 2. 抽象类和接口都不能创建实例对象 * 3. 抽象类和接口的使用意义也就是作用相同 * * 接口和抽象类相比, 特殊在哪里? * 1. 接口中的方法,必须全要是抽象方法(不能用不抽象的方法) * 所以在接口中的抽象方法不需要使用abstract, 直接使用分号结束即可 * 2. 接口中的成员属性, 必须是常量(不能有变量) * 3. 所有的权限必须是公有的(public) * 4. 声明接口不使用class, 而是使用interface * * 接口应用的一些细节: * 1. 可以使用extends 让一个接口继承另一接口 (接口和接口---- 只有扩展新抽象方法, 没有覆盖的关系) * 2. 可以使用一个类来实现接口中的全部方法, 也可以使用一个抽象类, 来实现接口中的部分方法 * (类与接口, 抽象类与接口 -- 覆盖 -- 重写, 实现接口中的抽象方法) * 3. 就不要使用extends这个关键字, 使用implements实现 implements 相当于 extends * extends 继承(扩展), 这个在PHP中, 一个类只能有一个父类 * 4. 一个类可以在继承另一个类的同时, 使用implements实现一个接口, 可以实现个接口(一定要先继承, 再实现接口) * 5. 实现多个接口, 只需要使用逗号分开多个接口即可 */ //声明一个接口使用interface interface Demo { const NAME="妹子"; const AGE = 20; public function test(); public function test2(); function test3(); } interface Test extends Demo { function test4(); } class World { function test5() { } } interface Abc { function test6(); } class Hello extends World implements Test,Abc { function test() { } function test2() { echo "22222222222222"; } function test3() { } function test4() { } function test6() { } } $h = new Hello; $h->test2(); ``` ## PHP多态的应用 面向对象的特性多态 对象的多态性是指在父类中定义的属性或行为被子类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或行为在父类及其各个子类中具有不同的语义。 例如:"几何图形"的"绘图"方法,"椭圆"和"多边形"都是"几何图"的子类,其"绘图"方法功能不同。 ``` <?php /* 多态特性 * 1. 程序扩展准备 * 技术: * 1. 必须有继承关系, 父类最好是接口或抽象类 */ interface USB { const WIDTH = 12; const HEIGHT = 3; function load(); function run(); function stop(); } class Cumputer { function useUSB(USB $usb) { $usb -> load(); $usb -> run(); $usb -> stop(); } } class Mouse implements USB{ function load() { echo "加载鼠标成功!<br>"; } function run() { echo "运行鼠标功能!<br>"; } function stop() { echo "鼠标工作结束!<br>"; } } class KeyPress implements USB { function load() { echo "加载键盘成功!<br>"; } function run() { echo "运行键盘成功!<br>"; } function stop() { echo "停止键盘使用!<br>"; } } class Worker { function work() { $c = new Cumputer(); $m = new Mouse; $k = new KeyPress; $c->useUSB($k); $c->useUSB($m); } } $w = new Worker; $w -> work(); ```