原文作者 刀客羽朋 ,这里重新整理,出处:http://www.cnblogs.com/tograce/category/161526.html
类的继承
类的继承是这样定义的:
<?php
class animal{
......
}
}
class dog extends animal{
......
}
?>
一个关于继承的简单实例:
1
<?php
2
//animal.php
3
class animal{
4
private $weight;
5
public function getWeight()
6
{
7
return $this->weight;
8
}
9
public function setWeight($w)
10
{
11
$this->weight=$w;
12
}
13
}
14
?>
15
<?php
16
//dog.php
17
require_once('animal.php');
18
class dog extends animal
19
{
20
/**子类新增方法*/
21
public function bark()
22
{
23
echo "Wang~~Wang~~~ ";
24
}
25
}
26
?>
27
28
<?php
29
//myDog.php
30
require_once('dog.php');
31
$myDog=new dog();
32
$myDog->setWeight(20);
33
echo "Mydog's weight is ".$myDog->getWeight().'<br />';
34
$myDog->bark();
35
?>
36
说明:
1、在php5中,构造函数可被继承;
2、在php5中,私有变量和私有方法不能被继承。
重写(override)
如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称方法的重写。
当对父类的方法进行重写时,子类中的方法必须和父类中的对应的方法具有相同的方法名称,在php5中不限制输入参数类型、参数数量和返回值类型。
子类中的覆盖方法不能使用比父类中被覆盖方法更严格的访问权限。(这是什么意思?就是说如果父类中的一个方法为public属性的,那每其子类的该方法就不能定义为private属性的)
例子:

重写简单实例
1
<?php
2
// 狗有两只眼睛,会汪汪叫,会跑.
3
class dog{
4
protected $eyeNumber=2; //属性
5
//返回封装属性的方法.
6
public function getEyeNumber(){
7
return $this->eyeNumber;
8
}
9
//狗会叫
10
public function yaff(){
11
return "Dog yaff, wang..wang..";
12
}
13
//狗会跑
14
public function run(){
15
return "Dog run..running
";
16
}
17
}
18
$dog=new dog();
19
echo "dog have ". $dog->getEyeNumber()." eyes. <br>";
20
echo $dog->yaff(). "<br >".$dog->run();
21
echo "<br /> <br /> <br /> <br />";
22
23
//这是我家的小狗叫"狗狗",它很小,不会汪汪叫,只会哼哼哼
24
class smallDog extends dog{
25
private $name="狗狗";
26
public function getName(){
27
return $this->name;
28
}
29
//重写方法yaff()
30
public function yaff(){
31
return $this->name.",heng
hegn..";
32
}
33
}
34
$myDog=new smallDog();
35
echo $myDog->getName()."have ".$myDog->getEyeNumber()." eyes. <br>";
36
echo $myDog->yaff() ."<br>".$myDog->run();
37
?>
构造函数的重写
当子类重写了构造函数,当在子类被实例化时,只调用子类的构造函数,而父类的构造函数不被调用。

Code
1
<?php
2
//构造函数继承的问题.
3
class Animal{
4
public $legNum = 0;
5
public function __construct(){
6
$this->legNum = 4;
7
echo "I am an animal<br>";
8
}
9
}
10
class Dog1 extends Animal {
11
public function __construct(){
12
$this->legNum = 4;
13
echo "I am a Dog .<br>";
14
}
15
}
16
$dog1 = new Dog1();
17
echo "legNum is ".$dog1->legNum;
18
/*
19
输出结果是:
20
I am a Dog .
21
legNum is 4
22
23
实例化子类时.子类的构造函数被调用了.而不调用父类的构造函数
24
*/
25
?>
this关键字
$this代表其所在的当前对象
$this在构造函数中指该构造函数所创建的新对象
在类中使用当前对象的属性和方法,必须使用$this->取值
来看一个局部变量和属性同名的小例:

Code
1
<!-- 验证属性和局部变量使用方法的类 -->
2
<?
3
class A{
4
private $a = 99;
5
//这里写一个打印参数的方法.
6
public function printInt($a){
7
echo "这里的 "$a 是传递的参数 $a ";
8
echo "<br>";
9
echo "这里的 "$this->a 是属性 $this->a";
10
}
11
}
12
$a = new A(); // 这里的$a 可不是类中的任何一个变量了.
13
$a->printInt(88);
14
?>
用$this调用对象中的其它方法

Code
1
<?php
2
//写一个类,让他自动完成最大值的选取
3
class Math{
4
//两个数比较大小
5
public function max($a,$b){
6
return $a>$b?$a:$b;
7
}
8
//三个数比较大小
9
public function max3($a,$b,$c){
10
$a=$this->max($a,$b);
11
return $this->max($a,$c);
12
}
13
/*-----------也可直接这样----
14
public function max3($a,$b,$c){
15
return $this->max($this->max($a,$b),$c);
16
}*/
17
}
18
$math=new Math();
19
echo "max is ".$math->max3(80,140,100);
20
?>
用$this调用构造函数
调用构造函数和析构函数是一样的
<?
class A{
private $a = 0;
public function __construct(){
$this->a = $this->a + 1 ;
}
public function doSomeThing(){
$this->__construct();
return $this->a;
}
}
$a = new A(); // 这里的$a 可不是类中的任何一个变量了.
echo "现在 "$a 的值是" . $a->doSomeThing();
?>
输出结果是:现在 "$a 的值是 2
$this到到底是什么?
$this就是指当前对象,我们甚至可以返回这个对象使用$this,

$this返回当前对象
1
<?php
2
class A{
3
function getASelf(){
4
return $this;
5
}
6
public function __toString(){
7
return "这是A的实例";
8
}
9
}
10
$a=new A();//创建A的实例
11
$b=$a->getASelf();//调用方法返回当前实例
12
echo $a;//打印对象会调用它的_toString方法
13
14
?>
用$this传递对象

Code
1
2-4-8.php <br>
2
<!--通过$this传递对象
3
在这个例子中,我们写一个根据不同的年龄发不同的工资的类
4
我们设置处理年龄和工资的业务模型为一个独立的类.
5
-->
6
<?php
7
class User{
8
private $age;
9
private $sal;
10
private $payoff;//声明全局属性
11
12
//构造函数,并创建Payoff的对象.
13
public function __construct(){
14
$this->payoff = new Payoff();
15
//★★★
16
/*【评】:通过构造函数,自动声明属性payoff是类Payoff的一实例*/
17
}
18
public function getAge(){
19
return $this->age;
20
}
21
public function setAge($age){
22
$this->age =$age;
23
}
24
//获得工资.
25
public function getSal(){
26
$this->sal = $this->payoff->figure($this);
27
//★★★★★★★
28
/*---------------------------------------------------------------
29
时间:2009-06-30
30
【评】:这是该类的精髓所在:
31
方法getSal()的作用是:①返回属性sal的值;
32
②将属性payoff中的方法figure的结果传给属性sal;
33
③同时方法figure的参数是$this,为一对象,且是类User本身
34
--------------------------------------------------------------*/
35
return $this->sal;
36
}
37
}
38
39
//这是对应工资和年龄关系的类
40
class Payoff{
41
public function figure($a){ //★★★这里的参数将是一个对象
42
$sal =0;
43
$age =$a->getAge();
44
/*★★★
45
这一句,我反复看了多遍才明白,当时我的困惑是:
46
$a为一对象,但并没有说是它是类User的一实例,又怎么可以调用方法getAge()呢?
47
看看2009-06-30我的理解正确不正确*/
48
if($age>80 || $age<16){
49
$sal =0;
50
}elseif($age>50){
51
$sal=1000;
52
}else{
53
$sal=800;
54
}
55
return $sal;
56
}
57
}
58
//实例化User
59
$user =new User();
60
61
$user->setAge(55);
62
echo $user->getAge(). "age, his sal is ".$user->getSal();
63
echo "<br />";
64
65
$user->setAge(25);
66
echo $user->getAge(). "age, his sal is ".$user->getSal();
67
echo "<br />";
68
69
$user->setAge(10);
70
echo $user->getAge(). "age, his sal is ".$user->getSal();
71
echo "<br />";
72
73
74
?>
75
输出结果:
55age, his sal is 1000
25age, his sal is 800
10age, his sal is 0
parent::关键字
通过parent::调用父类的方法

Code
1
<?php
2
//用parent::调用父类的方法
3
//声明一个员工类,经理类继承自员工类
4
class employer{
5
protected $sal=3000;
6
public function getSal(){
7
$this->sal=$this->sal+1200;
8
return $this->sal;
9
}
10
}
11
class manager extends employer{
12
//如果想让经理在员工的基础上多发1500元,
13
//先要调用父类的方法
14
public function getSal(){
15
parent::getSal(); //这里调用了父类的方法
16
$this->sal=$this->sal+1500;
17
return $this->sal;
18
}
19
}
20
$emp=new employer();
21
$manag=new manager();
22
echo "普通员工的工资是: ".$emp->getSal()."<br />";
23
echo "经理的工资是: ".$manag->getSal(). "<br />";
24
?>
25
将输出:
普通员工的工资是: 4200
经理的工资是: 5700
重载Overload
当类中的方法名相同时,称为方法的重载(Overload);
PHP5中不支持重载(Overload)
实例
在前面,我们建立一个user类,并可使用类获取用户信息,现在,我们将进一步加强其功能,用户可修改自己的密码。
先需要将前面的类稍修改,在UserInfo类中将获取密码的方法隐藏。
然后再写一个 UserChange 类,它继承自 UserInfo 类,但在这个类中增加修改密码的方法,并将获取密码的方法重写为public权限。
在这里,我们还将连接单独写成一个类 MysqlConn

Code
<?php
class MysqlConn{
protected $conn;
protected $my_db;
protected $result;

public function __construct(){
require_once("db_config.php");
$this->conn=mysql_connect($db_server,$db_user,$db_pwd);//建立连接,
mysql_query("set names 'utf8'");
$this->my_db=mysql_select_db($db_name,$this->conn);
}
public function query($sql){
$this->result=mysql_query($sql,$this->conn);
return $this->result;
}
public function next(){
return $row=mysql_fetch_array($this->result);
}

public function close(){
mysql_free_result($this->result);
}
//使用转义字符,保证系统安全.
public function escapeString($str){
return mysql_escape_string($str);
}
/*--------------------------------------------
mysql_escape_string与addslashes的区别在于
mysql_escape_string总是将“'”转换成“\'”
而addslashes
在magic_quotes_sybase=on时将“'”转换成“''”
在magic_quotes_sybase=off时将“'”转换成“\'”
------------------------------------------------*/
}

?>
加强了的 UserInfo 类

Code
<?php
//class_user.php
require_once("class_mysqlConn.php");
class UserInfo{
protected $userName;
protected $birthplace;
protected $password;
protected $userEmail;
protected $theUserInfo;
protected $mysqlConn;
/*★与前面的class_user_before.php相比,将属性类型更改为protected,并加入了新的属性mysqlConn*/
public function __construct($name){
$this->mysqlConn=new MysqlConn();
$sql="select * from user where username='$name'";//查询的sql
$rs=$this->mysqlConn->query($sql);
$this->theUserInfo=$this->mysqlConn->next();
$this->getInfo();
}
//获取信息传递给属性的方法
protected function getInfo(){
$this->userName=$this->theUserInfo["username"];
$this->birthplace=$this->theUserInfo["birthplace"];
$this->password=$this->theUserInfo["passwd"];
$this->userEmail=$this->theUserInfo["email"];
}
//返回每个属性的public方法.
public function getUserName(){
return $this->userName;
}
public function getBirthplace(){
return $this->birthplace;
}
protected function getPassword(){
return $this->password;
}
public function getEmail(){
return $this->userEmail;
}
}
子类UserChange 类

Code
<?
// class_userChange.php
require_once("class_user.php");
class UserChange extends userInfo{
public function setUserPSW($pws){
$pws=$this->mysqlConn->escapeString($pws);//过滤
$username=$this->mysqlConn->escapeString($this->userName);//过滤
/*userName属性是protected性质的,但为什么能直接获取属性值呢?
----------------------------------------------------------------*/
$sql="Update user set passwd ='$pws'where username ='username'";
$rs=$this->mysqlConn->query($sql);//执行
if ($rs){
$this->password=$pws;
}
return $rs; //退回它的意义是什么?
}
public function getPassword(){//重写getUserPSW方法
return $this->password;
}
}
?>
还记得上回用 UserInfo类获取值的实例吗,这里照样可以放心使用:
<?php
//view_user_mysql_process.php
require_once("class_user.php");
$user=new UserInfo("shuwill");
$userName=$user->getUserName();
$birthplace=$user->getBirthplace();
$email=$user->getEmail();
echo "Your name is ".$userName."<br />";
echo "Your birthplace is ".$birthplace."<br />";
echo "Your email is ".$email."<br />";
?>