博客列表 >面向接口编程:接口与trait

面向接口编程:接口与trait

溪边小树
溪边小树原创
2020年05月09日 16:59:46839浏览

本次课程中细致讲解了关于接口与trait的基本语法与使用场景,老师希望大家能深刻理解课堂中讲解的相关内容。
接口继承是重点所在,trait的基本功能是代码复用,请分别用实例展示。

接口继承实例:

  1. <?php
  2. // 接口的使用场景2:多接口继承,一个接口同时继承多个接口
  3. // 接口可以突破php类的继承限制, 允许多继承, 形成了多层级的接口
  4. interface iStudent
  5. {
  6. // 接口常量
  7. const COLLEDGE = 'XX大学';
  8. }
  9. interface iStudent1 extends iStudent
  10. {
  11. // 接口常量
  12. const MAJOR = '网络编程';
  13. }
  14. // 接口实现多继承
  15. interface iStudent2 extends iStudent, iStudent1
  16. {
  17. // 接口方法
  18. public function message();
  19. }
  20. // 实现类
  21. class Student implements iStudent, iStudent1,iStudent2
  22. {
  23. // 必须实现接口中的抽象方法
  24. public function message()
  25. {
  26. return iStudent1::MAJOR . ' 是 ' .iStudent::COLLEDGE.'重点专业之一!' ;
  27. }
  28. }
  29. echo ( new Student)->message();
  30. echo '<hr>';
  31. // 实现类1
  32. class Student1 implements iStudent2
  33. {
  34. // 必须实现接口中的抽象方法
  35. public function message()
  36. {
  37. return iStudent1::MAJOR . ' 目前是 ' .iStudent::COLLEDGE.'重点专业之一!' ;
  38. }
  39. }
  40. echo ( new Student1)->message();
  41. // 接口场景3: 用抽象类来部分实现一个接口
  42. interface iDbBase
  43. {
  44. // 接口方法
  45. // 这里全部采用静态方法, 可省去实例化操作
  46. // 数据库常用的CURD(增删改查)操作
  47. public static function insert($db, $data);
  48. public static function select($db, $options=[]);
  49. public static function update($db,$options);
  50. public static function delete($db, $where);
  51. // 连接数据库
  52. public static function connect($dsn, $username, $password);
  53. }
  54. // 用一个抽象类只实现接口的连接方法: connect()
  55. abstract class aDb implements iDbBase
  56. {
  57. protected static $db = null;
  58. public static function connect($dsn, $username, $password)
  59. {
  60. if (is_null(self::$db)) {
  61. try {
  62. // 连接数据库, 创建pdo对象
  63. self::$db = new \PDO($dsn, $username, $password);
  64. } catch (PDOException $e) {
  65. die($e->getMessage());
  66. }
  67. }
  68. return self::$db;
  69. }
  70. }
  71. // 工作类: 通用查询
  72. class DB1 extends aDb
  73. {
  74. public static function insert($db, $data)
  75. {
  76. // ...
  77. }
  78. public static function select($db, $options=[])
  79. {
  80. $sql = 'SELECT `id`,`name`,`email` FROM `users` LIMIT 5';
  81. return$db->query($sql)->fetchAll(\PDO::FETCH_ASSOC);
  82. }
  83. public static function update($db,$options)
  84. {
  85. }
  86. public static function delete($db, $where)
  87. {
  88. // ...
  89. }
  90. }
  91. // 客户端
  92. $config = [
  93. 'type' => $type ?? 'mysql',
  94. 'host' => $hsot ?? 'localhost',
  95. 'dbname' => $dbname ?? 'phpedu',
  96. 'charset' => $charset ?? 'utf8',
  97. 'port' => $port ?? '3306',
  98. 'username' => $username ?? 'root',
  99. 'password' => $password ?? '123456',
  100. ];
  101. // 创建PDO数据源
  102. $dsn = sprintf('%s:host=%s;dbname=%s;',$config['type'],$config['host'],$config['dbname']);
  103. // 使用自定义用户密码
  104. $username = $config['username'];
  105. $password = 'root';
  106. // 连接数据库: 实际上调用的是抽象类中的connect()方法完成,返回连接对象$db
  107. $db = DB1::connect($dsn, $username, $password);
  108. // 查询操作
  109. $users = DB1::select($db);
  110. // 遍历结果集
  111. foreach ($users as list('id'=>$id, 'name'=>$name,'email'=>$email)) {
  112. printf('%s => %s : %s <br>', $id, $name, $email);
  113. }
  114. echo '<hr>';
  115. // 接口使用场景4: 接口是实现多态的重要手段
  116. // 1. 数据库操作接口
  117. interface iDb
  118. {
  119. // 构造方法: 用于连接数据库
  120. public function __construct(...$params);
  121. // 1. 新增
  122. public function insert(array $data);
  123. // 2. 查询
  124. public function select(array $options = []);
  125. // 3. 更新
  126. public function update(array $options);
  127. // 4. 删除
  128. public function delete(array $where);
  129. }
  130. /////////////////////////////////////////////////////////
  131. // 2. 使用PDO方式实现iDB接口, 仅以查询select()演示
  132. class DB_PDO implements iDb
  133. {
  134. protected $db = null;
  135. public function __construct(...$params)
  136. {
  137. list($dsn, $username, $password) = $params;
  138. $this->db = new PDO($dsn, $username, $password);
  139. }
  140. // 1. 新增
  141. public function insert(array $data)
  142. {
  143. // ...
  144. }
  145. // 2. 查询
  146. public function select(array $options = [])
  147. {
  148. echo '<h3>PDO:</h3>';
  149. $sql = 'SELECT `id`,`name`,`email` FROM `users` LIMIT 3';
  150. return $this->db->query($sql)->fetchAll(PDO::FETCH_ASSOC);
  151. }
  152. // 3. 更新
  153. public function update(array $options)
  154. {
  155. // ...
  156. }
  157. // 4. 删除
  158. public function delete(array $where)
  159. {
  160. // ...
  161. }
  162. }
  163. /////////////////////////////////////////////////////////
  164. // 3. 使用MySQLi方式实现iDB接口,仅以查询select()演示
  165. class DB_MySQLi implements iDb
  166. {
  167. protected $db = null;
  168. public function __construct(...$params)
  169. {
  170. list($host, $username, $password, $dbname, $charset) = $params;
  171. $this->db = new MySQLi($host, $username, $password, $dbname);
  172. $this->db->set_charset($charset);
  173. }
  174. // 1. 新增
  175. public function insert(array $data)
  176. {
  177. // ...
  178. }
  179. // 2. 查询
  180. public function select(array $options = [])
  181. {
  182. echo '<h3>MySQLi:</h3>';
  183. $sql = 'SELECT `id`,`name`,`email` FROM `users` LIMIT 3';
  184. return $this->db->query($sql)->fetch_all(MYSQLI_ASSOC);
  185. }
  186. // 3. 更新
  187. public function update(array $options)
  188. {
  189. // ...
  190. }
  191. // 4. 删除
  192. public function delete(array $where)
  193. {
  194. // ...
  195. }
  196. }
  197. /////////////////////////////////////////////////////////
  198. // 4. 创建数据库通用操作类,用来统一客户端调用方式(静态实现)
  199. class DB
  200. {
  201. // 新增
  202. public static function insert(iDb $db, array $data)
  203. {
  204. return $db->insert($data);
  205. }
  206. // 查询
  207. public static function select(iDb $db, array $options = [])
  208. {
  209. return $db->select($options = []);
  210. }
  211. // 更新
  212. public static function update(iDb $db, array $options)
  213. {
  214. return $db->update($options);
  215. }
  216. // 删除
  217. public static function delete(iDb $db, array $where)
  218. {
  219. return $db->delete($where);
  220. }
  221. }
  222. /////////////////////////////////////////////////////////
  223. // 客户端代码
  224. $config = [
  225. 'type' => $type ?? 'mysql',
  226. 'host' => $host ?? 'localhost',
  227. 'dbname' => $dbname ?? 'phpedu',
  228. 'charset' => $charset ?? 'utf8',
  229. 'port' => $port ?? '3306',
  230. 'username' => $username ?? 'root',
  231. 'password' => $password ?? 'root',
  232. ];
  233. extract($config);
  234. // 1. PDO实现
  235. $dsn = sprintf('%s:host=%s;dbname=%s;', $type, $host, $dbname);
  236. // 使用自定义密码
  237. $password = 'root';
  238. $db = new DB_PDO($dsn, $username, $password);
  239. $db = new DB_MySQLi($host, $username, $password, $dbname, $charset);
  240. var_dump($db);
  241. // SQL执行操作,以查询为例,无论数据库是什么类型,都无须改动查询代码
  242. // 因为是面向接口编程, DB_PDO, DB_MySQLi都实现了同一接口
  243. // 只要将对象参数的类型限定在接口上就可以实现多态
  244. // 此时, $db 即可是DB_PDO类实例, 也可以是DB_MySQLi类实例, 就看你的心情了
  245. $users = DB::select($db);
  246. // 遍历结果集
  247. foreach ($users as list('id' => $id, 'name' => $name, 'email' => $email)) {
  248. printf('%s => %s : %s <br>', $id, $name, $email);
  249. }

trait实例:

  1. <?php
  2. // trait 功能与语法
  3. // trait: php5.4+, 代码复用
  4. // trait:与抽象类,接口一样不能实例化, 只能嵌入到宿主类中使用
  5. // triat是一个特殊类: 1. 常规, 2. 静态, 3. 抽象, 不能用类常量
  6. trait tDemo
  7. {
  8. // 常规
  9. protected $name = '张嘎子';
  10. public function getName()
  11. {
  12. return $this->name;
  13. }
  14. // 静态
  15. public static $sex = '男';
  16. public static function getSex()
  17. {
  18. return self::$sex;
  19. }
  20. // 抽象
  21. // 抽象静态属性
  22. public static $age;
  23. // 抽象静态方法
  24. abstract public static function getAge();
  25. }
  26. // 客户端
  27. class User
  28. {
  29. // 类中使用trait , 用use 关键
  30. use tDemo;
  31. // 将use tDemo 理解为加载
  32. // require tDemo;
  33. // 常规
  34. // protected $name = '张嘎子';
  35. // public function getName()
  36. // {
  37. // return $this->name;
  38. // }
  39. // // 静态
  40. // public static $sex = '男';
  41. // public static function getSex()
  42. // {
  43. // return self::$sex;
  44. // }
  45. // // 抽象
  46. // // 抽象静态属性
  47. // public static $age;
  48. public static function getAge()
  49. {
  50. return self::$age;
  51. }
  52. }
  53. $user = new User;
  54. User::$age = 16;
  55. echo $user->getName() . ' : ' . User::getSex() . ' ===> ' . User::getAge();
  56. echo '<hr>';
  57. // trait 功能1: 代码复用
  58. trait tDemo1
  59. {
  60. // 格式化打印
  61. public function write()
  62. {
  63. $props =get_class_vars(__CLASS__);
  64. printf('<pre>%s</pre>', print_r($props, true));
  65. }
  66. }
  67. // User1
  68. class User1
  69. {
  70. use tDemo1;
  71. protected $course = '网络编程';
  72. protected $score = 80;
  73. protected $mainpoint = ['类', '接口', 'trait'];
  74. }
  75. (new User1)->write();
  76. // User2
  77. class User2
  78. {
  79. use tDemo1;
  80. protected $course = '网站设计原理';
  81. protected $score = 90;
  82. protected $mainpoint = ['前端', '框架', '数据库'];
  83. }
  84. (new User2)->write();
  85. echo '<hr>';
  86. // trait2: 在继承上下文环境中, 具有优先级, 通过优先的设置, 降低单继承的影响
  87. trait tDemo2
  88. {
  89. public static $name = 'Trait中的属性';
  90. public static function hello()
  91. {
  92. return 'Trait中的方法: ' . __METHOD__;
  93. }
  94. }
  95. // 基类/父类
  96. class Dad
  97. {
  98. // public static $name = '基类中的属性';
  99. public static function hello()
  100. {
  101. return '基类中的方法: ' . __METHOD__;
  102. }
  103. }
  104. // 扩展类/子类
  105. class Son extends Dad
  106. {
  107. use tDemo2;
  108. // trait中的同名方法将父类中同名方法覆盖了, 重写了
  109. // public static $name = '扩展类中的属性';
  110. public static function hello()
  111. {
  112. return '扩展类中的方法: ' . __METHOD__;
  113. }
  114. // 当前类的同名方法又会覆盖掉trait中同名方法
  115. }
  116. // 客户端
  117. echo Son::hello();
  118. // 方法使用的优先级:子类 > trait > 父类

课程学习小结

本次课程老师从浅显易懂的实例出发,细致讲解了接口继承及trait使用的相关内容,通过回看视频及讲义代码,加深了理解,尤其是接口继承及多态的使用场景、trait在宿主类中的使用方法及与父类、子类间调用相应方法的优先级比较等,相关代码基本模仿老师的实例格式进行修改实现,虽然花费了不少时间,但对促使自己多动手实践的习惯养成又进了一步,调试成功后还是感觉挺好的。!

声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议