六、类的继承
1、继承,我们可以理解成共享被继承类的内容。
被继承的类我们叫做父类(或基类),继承者叫做子类(或派生类)。比如:汽车是一个比较大的类,我们也可以称之为基类。除此之外,汽车还分为卡车、轿车、东风、宝马等,因为这些子类具有很多相同的属性和方法,可以采用继承汽车类来共享这些属性与方法,实现代码的复用。
当扩展一个类的时候,子类会继承父类所有的protected与public的属性与方法,子类也可以覆盖父类相应的方法。
2、在代码中使用关键字“extends”来实现类的继承。
<?php
/*
* Created on 2014-11-3
*
* To change the template for this generated file go to
* Window - Preferences - PHPeclipse - PHP - Code Templates
*/
header("Content-Type:text/html;charset=utf-8");
class Father{
public $name = "张某";
function say(){
echo "我会说话!";
}
}
class Son extends Father{
function say(){ //方法的重写
echo Father::say().",而且说的更好。<br />"; //使用父类名::方法名或parent::方法名,访问父类中被重写的方法
}
}
$zhang = new Son();
echo "我是".$zhang -> name."<br />"; //继承父类的属性
$zhang -> say(); //重写父类的方法
?>
七、PHP中的重载
1、传统开发语言中的重写和重载:
重写(覆盖override)是指:子类重写了父类的同名方法; 重载(overload)是指:存在多个同名方法,但参数类型/个数不同,传不同的参数,调用不同的方法。
在PHP中,不允许存在多个同名方法。因此,在PHP中实现重载的方式和其他语言中不同。
2、PHP中的重载
PHP所提供的"重载"(overloading)是指动态地"创建"类属性和方法。我们是通过魔术方法(magic methods)来实现的。当调用当前环境下未定义或不可见的类属性或方法时,重载方法会被调用。
NOTE:__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo() 等方法在 PHP 中被称为"魔术方法"(Magic methods)。在命名自己的类方法时不能使用这些方法名,除非是想使用其魔术功能。
属性的重载通过__set,__get,__isset,__unset来分别实现对不存在属性的赋值、读取、判断属性是否设置、销毁属性。
方法的重载通过__call来实现,当调用不存在的方法的时候,将会转为参数调用__call方法,当调用不存在的静态方法时会使用__callStatic重载。
示例1:
<?php
/*
* Created on 2014-11-3
*
* To change the template for this generated file go to
* Window - Preferences - PHPeclipse - PHP - Code Templates
*/
header("Content-Type:text/html;charset=utf-8");
class Human {
function say() {
echo "我会说话。";
}
function __get($varName) { //使用__get、__set实现属性重载
return $varName;
}
function __set($varName, $varValue) {
$varName = $varValue;
echo "给未定义变量" . $varName . "赋值为:" . $varValue . "<br />";
}
function __call($name, $args) { //使用__call实现方法重载
if ($name == "run" && count($args) == 0) {
echo "方法重载<br />";
} else
if ($name == "run" && count($args) == 2) {
echo "方法重载,两个参数<br />";
}
}
static function __callStatic($name, $args) { //使用_callStatic实现静态方法重载。这是PHP5.3.0后新增的魔术方法,因为我现在的环境用的是PHP5.2.14,所以这个魔术方法的用法暂时无法验证。
echo "静态方法重载";
}
}
$zhang = new Human();
$zhang->height = "175"; //属性重载,给未定义变量赋值
echo $zhang->height . "<br />"; //属性重载,访问未定义的变量(注意,这里输出的是变量的名字,而不是变量的值。动态创建的东西,一般只是用来临时存储数据。我们实际应用中,一般采用示例2的用法,请看下面的示例2)
$zhang->run(); //方法重载,调用未定义的方法
$zhang->run("参数1", "参数2");
//Human::eat(); //静态方法重载,暂未验证
?>
示例2:
<?php
/*
* Created on 2014-11-3
*
* To change the template for this generated file go to
* Window - Preferences - PHPeclipse - PHP - Code Templates
*/
header("Content-Type:text/html;charset=utf-8");
class Human{
private $arr = array();
function __set($key,$value){ //使用__get、__set实现属性重载
$this -> arr[$key] = $value;
}
function __get($key){
if(isset($this -> arr[$key])){
return $this -> arr[$key];
}
return null;
}
function __isset($key){ //__isset、__unset没太搞清楚,备忘下,回头再研究
if(isset($this -> arr[$key])){
return true;
}
return false;
}
function __unset($key){
unset($this -> arr[$key]);
}
}
$zhang = new Human();
$zhang -> height = "175"; //属性重载,给未定义变量赋值
echo $zhang -> height."<br />"; //属性重载,访问未定义的变量
?>