1. 类中的方法不是全局方法,可以和外部的普通方法重名,例如:
<?php function time();
则会报错:不能重新声明方法
Fatal error: Cannot redeclare time()
而在类中定义则可以:
<?php class clock{ public function time(){ echo date('Y-m-d H:i:s'); } } $c = new clock(); $c -> time();
页面输出:
2015-02-28 16:47:36
===============
2.析构函数
<?php class Human{ public function __construct(){ echo 'hello<br />'; } public function __destruct(){ echo 'bye'; } } $a = new Human(); //此时会输出'hello'和'bye' //因为php是脚本语言,在代码执行到最后一行时,所有申请的内存都要被释放。 //自然,对象也要被销毁
$a 并不是对象,只是一个变量名指向对象。当一个对象如果还有其他变量来引用,unset($a)并不会销毁对象。当引用为0时,对象才会被销毁。
==========
3.父类的 private 属性可以被子类继承,但是子类无权操作
<?php class Human{ private $name = 'monkey'; } class Stu extends Human{ private $name = 'student'; } $john = new Stu(); var_dump($john);
页面输出:
object(Stu)[1] private 'name' => string 'student' (length=7) private 'name' (Human) => string 'monkey' (length=6)
=======
4.名词:里氏代换 - 面向对象设计的基本原则之一,任何基类可以出现的地方,子类一定可以出现。
多态 - 只抽象地声明父类,具体工作由子类对象完成。简单例子
<?php class Light{ public function turnOn(Glass $g){ //类名 作 参数类型检测(php5.3) $g->setUp(); } } class Glass{ public $color; public function setUp(){ echo '装上',$this->color,'色的玻璃<br />'; } } class RedGlass extends Glass{ public $color = '红'; } class BlueGlass extends Glass{ public $color = '篮'; } $light = new Light(); $redglass = new RedGlass(); $blueglass = new BlueGlass(); $light->turnOn($redglass); $light->turnOn($blueglass);
页面输出:
装上红色的玻璃
装上篮色的玻璃
=======
5. 魔术方法 ( __get(),__set(),__isset(),__unset() ) 在框架中的应用
<?php class UserModel{ //存放传递的值 protected $data = array(); //获取 public function __get($p){ if(isset($this->data[$p])){ return $this->data[$p]; } } //设置 public function __set($p,$v){ $this->data[$p] = $v; return $this->data; } //销毁 public function __unset($p){ if(isset($this->data[$p])){ unset($this->data[$p]); } } //isset判断 public function __isset($p){ return isset($this->data[$p]); } public function add(){ //取出$data里存放的数值,键作为数据表的字段名,值作为数据表的字段值 $k = implode(',',array_keys($this->data)); $v = implode('\',\'',array_values($this->data)); //拼接字符串 $sql = 'insert into Review ('; $sql .= $k; $sql .= ') values (\''; $sql .= $v; $sql .= '\')'; return $sql; } } $new = new UserModel(); $new->username = 'uname'; $new->password = 'upwd'; var_dump($new); var_dump($new->email); //显示 null echo $new->add(),'<br />'; unset($new->password); var_dump($new);
页面输出:
object(UserModel)[1] protected 'data' => array 'username' => string 'uname' (length=5) 'password' => string 'upwd' (length=4) null insert into Review (username,password) values ('uname','upwd') object(UserModel)[1] protected 'data' => array 'username' => string 'uname' (length=5)
=================
7.抽象类
① 抽象类的抽象方法不能有方法体,否则报错:Fatal error: Abstract function Classname::functionname() cannot contain body in ...
② 抽象类不能被实例化,否则报错:Fatal error: Cannot instantiate abstract class Classname in...
③ 继承抽象类的子类必须实现抽象类中的所有抽象方法,后则报错:Fatal error: Class SonClassname contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (AbstractClassname ::Abstractfunctionname) in ...
④ 含有抽象方法的类一定是抽象类;
⑤ 抽象类中不一定有抽象方法,也可以含有非抽象方法。
<?php //抽象类 无法实例化 abstract class FlyIdea{ //抽象方法,不能有方法体 public abstract function engine(); public abstract function blance(); } //抽象类 abstract class Rocket extends FlyIdea{ public function engine(){ echo 'half completed'; } } //如果继承的类不是抽象类,则它的父类中的抽象方法必须全部实现 class ModenFly extends Rocket{ public function engine(){ echo 'engine completed'; } public function blance(){ echo 'blance completed'; } } $apache = new ModenFly();
==================
8.延迟绑定:
是指类的计算 self 的定义不是以定义时为准,而是以运算时的计算结果为准。
<?php //动物类 class Animal{ const age = 1; public static $leg = 4; public static function eat(){ echo 'fresh food <br />'; } public static function t1(){ self::eat(); echo self::age,'<br />'; echo self::$leg,'<br />'; } //延迟绑定 public static function t2(){ static::eat(); echo static::age,'<br />'; echo static::$leg,'<br />'; } } //人类 class Human extends Animal{ const age = 30; public static $leg = 2; public static function eat(){ echo 'cooked food <br />'; } } //学生类 class Stu extends Human{ const age = 20; public static $leg = 3; public static function eat(){ echo 'rubbish food <br />'; } } Stu::t1(); Stu::t2(); //后期绑定(运行期绑定)
页面输出:
fresh food
1
4
rubbish food
20
3
==================
9.接口
如果说类是一种事物的抽象,那么接口则是事物的功能的抽象。
接口比抽象类更为抽象,接口中不能含有非抽象方法,不能含有成员属性。接口中可以定义常量。
一个类可以同时实现多个接口,同时必须实现接口中所有的抽象方法。
不能实例化接口。
类实现接口使用 implements。接口继承接口使用 extends 。
<?php //接口1 interface animal{ //接口中的抽象方法 public function eat(); } //接口2 继承 接口1 interface lion extends animal{ public function run(); } //接口3 继承 接口1 interface wisdom extends animal{ public function think(); public function emotion(); } //一个类同时继承2个接口 class Human implements lion,wisdom{ //必须实现2个接口中所有的抽象方法(包括继承接口的父接口) public function eat(){ echo '吃'; } public function run(){ echo '跑'; } public function think(){ echo '想'; } public function emotion(){ echo '情绪'; } }
======================
10.类的自动加载
<?php function __autoload($c){ require './'.$c.'Model.php'; } $Mary = new Human; $Mary->say();
=======================
11.异常
在类中如果产生了错误,实例化该类依然会生成对象。使用了异常处理之后就可以针对对象进行错误检测。
<?php //生产环境关闭错误信息 error_reporting(0); class Db{ private $conn; public function __construct(){ $this->conn = mysql_connect('localhost','root','111'); //异常处理 if(!$this->conn){ //实例化exception类,并传递错误信息和错误码参数 $e = new Exception('数据库连接失败!!',9); //抛出异常 throw $e; } } } //测试并试图捕捉异常 try{ $mysql = new Db(); }catch(Exception $e){ echo '捕捉到错误信息:'; echo $e->getMessage(),'<br />'; echo '捕捉到的错误码:'; echo $e->getCode(),'<br />'; echo '错误文件:',$e->getFile(),'<br />'; echo '错误行:',$e->getLine(),'<br />'; } var_dump($mysql);
如果数据库的信息填写错误,比如密码错误,页面输出:
捕捉到错误信息:数据库连接失败!! 捕捉到的错误码:9 错误文件:D:\practise\php\OOP\exception.php 错误行:11 null