原文作者 刀客羽朋 ,这里重新整理,出处:http://www.cnblogs.com/tograce/category/161526.html
类的继承
类的继承是这样定义的:
<?php
class animal{
......
}
}
class dog extends animal{
......
}
?>
一个关于继承的简单实例:
1<?php
2//animal.php
3class 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
17require_once('animal.php');
18class dog extends animal
19{
20 /**子类新增方法*/
21 public function bark()
22 {
23 echo "Wang~~Wang~~~ ";
24 }
25}
26?>
27
28<?php
29//myDog.php
30require_once('dog.php');
31$myDog=new dog();
32$myDog->setWeight(20);
33echo "Mydog's weight is ".$myDog->getWeight().'<br />';
34$myDog->bark();
35?>
36
说明:
1、在php5中,构造函数可被继承;
2、在php5中,私有变量和私有方法不能被继承。
重写(override)
如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称方法的重写。
当对父类的方法进行重写时,子类中的方法必须和父类中的对应的方法具有相同的方法名称,在php5中不限制输入参数类型、参数数量和返回值类型。
子类中的覆盖方法不能使用比父类中被覆盖方法更严格的访问权限。(这是什么意思?就是说如果父类中的一个方法为public属性的,那每其子类的该方法就不能定义为private属性的)
例子:
重写简单实例
1<?php
2// 狗有两只眼睛,会汪汪叫,会跑.
3class 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();
19echo "dog have ". $dog->getEyeNumber()." eyes. <br>";
20echo $dog->yaff(). "<br >".$dog->run();
21echo "<br /> <br /> <br /> <br />";
22
23//这是我家的小狗叫"狗狗",它很小,不会汪汪叫,只会哼哼哼
24class 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.",henghegn..";
32 }
33}
34$myDog=new smallDog();
35echo $myDog->getName()."have ".$myDog->getEyeNumber()." eyes. <br>";
36echo $myDog->yaff() ."<br>".$myDog->run();
37?>
构造函数的重写
当子类重写了构造函数,当在子类被实例化时,只调用子类的构造函数,而父类的构造函数不被调用。
Code
1<?php
2//构造函数继承的问题.
3class Animal{
4 public $legNum = 0;
5 public function __construct(){
6 $this->legNum = 4;
7 echo "I am an animal<br>";
8 }
9}
10class Dog1 extends Animal {
11 public function __construct(){
12 $this->legNum = 4;
13 echo "I am a Dog .<br>";
14 }
15}
16$dog1 = new Dog1();
17echo "legNum is ".$dog1->legNum;
18/*
19输出结果是:
20I am a Dog .
21legNum is 4
22
23实例化子类时.子类的构造函数被调用了.而不调用父类的构造函数
24*/
25?>
this关键字
$this代表其所在的当前对象
$this在构造函数中指该构造函数所创建的新对象
在类中使用当前对象的属性和方法,必须使用$this->取值
来看一个局部变量和属性同名的小例:
Code
1<!-- 验证属性和局部变量使用方法的类 -->
2<?
3class 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//写一个类,让他自动完成最大值的选取
3class 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();
19echo "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
2class 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();//调用方法返回当前实例
12echo $a;//打印对象会调用它的_toString方法
13
14?>
用$this传递对象
Code
12-4-8.php <br>
2<!--通过$this传递对象
3在这个例子中,我们写一个根据不同的年龄发不同的工资的类
4我们设置处理年龄和工资的业务模型为一个独立的类.
5-->
6<?php
7class 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//这是对应工资和年龄关系的类
40class 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);
62echo $user->getAge(). "age, his sal is ".$user->getSal();
63echo "<br />";
64
65$user->setAge(25);
66echo $user->getAge(). "age, his sal is ".$user->getSal();
67echo "<br />";
68
69$user->setAge(10);
70echo $user->getAge(). "age, his sal is ".$user->getSal();
71echo "<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//声明一个员工类,经理类继承自员工类
4class employer{
5 protected $sal=3000;
6 public function getSal(){
7 $this->sal=$this->sal+1200;
8 return $this->sal;
9 }
10}
11class 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();
22echo "普通员工的工资是: ".$emp->getSal()."<br />";
23echo "经理的工资是: ".$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 />";
?>