脚本宝典收集整理的这篇文章主要介绍了PHP 中的面向对象编程:通向大型 PHP 工程的办法,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
这篇
文章介绍在&nbs
p;PHP 的面向对象编程(OOP)。我将演示如何用面向对象的概念编出较少的
代码但更好的程序。祝大家好运。
面向对象编程的概念对每
一个作者来说都有不同的看法,我提醒一下
一个面向对象语言应有的东西:
- 数据抽象和信息隐藏
- 继承
-
多态性 在
PHP中使用类进行封装的办法:
<?
PHP class Something {
// In OOP classes are usually n
amed starting w
ITh a cap letter.
VAR $x;
function setX($v) {
// 
;methods start in lowercase then use lowercase to se
PRate
// wo
rds in the method name example getValueOfArea()
$this->x=$v;
}
function getX() {
return $this->x;
}
}
?>
当然你可以用你自己的办法,但有
一个标准总是好的。
PHP 中类的数据成员使用 "var" 定义,数据成员是没有类型直到被赋值。
一个数据成员可能是
一个 integer、数组、联合数组 (associative array) 或甚至对象(object).
方法在类里定义成
函数,在
方法里
存取数据成员,你必须使用 $this->name 这样的办法,否则对
方法来说是
一个函数的局部变量。
使用 new 来创建
一个对象
$obj = new Something;
然后使用成员
函数 $obj->setX(5);
$see = $obj->getX();
setX 成员
函数将 5 赋给对象(而不是类)obj 中成员变量, 然后 getX 返回值 5.
你也可以用对象引用来存取成员变量,例如:$obj->x=6; 然而,这不一种好的面向对象编程的
方法。我坚持你应使用成员
函数来设置成员变量的值和通过成员
函数来读取成员变量。如果你认为成员变量是不可存取的除了使用成员
函数的办法,你将成为
一个好的面向对象程序员。但不幸的是
PHP 本身没有办法声明
一个变量是私有的,所以允许糟糕的
代码存在。
在
PHP 中继承使用 extend 来声明。
<?
PHP class Another extends Something {
var $y;
function setY($v) {
// Methods start in lowercase then use lowercase to se
PErate
// words in the method name example getValueOfArea()
$this->y=$v;
}
function getY() {
return $this->y;
}
}
?>
这样类 "Another" 的对象拥有
父类的所用成员变量及
方法函数,再
加上自己
的成员变量及成员
函数。如:
$obj2=new Another;
$obj2->setX(6);
$obj2->setY(7);
多重继承不被
支持,所以你不能让
一个类继承多个类。
在继承类中你可以重新定义来重定义
方法,如果我们在 "Another" 重新定义 getX,那么我们不再能存取 "Something" 中的成员
函数 getX. 同样,如果我们在继承类中声明
一个和
父类同名的成员变量,那么继承类的变量将隐藏
父类的同名变量。
你可以定义
一个类的构造
函数, 构造
函数是和类同名的成员
函数,在你创建类的对象时被
调用。
<?
PHP class Something {
var $x;
function Something($y) {
$this->x=$y;
}
function setX($v) {
$this->x=$v;
}
function getX() {
return $this->x;
}
}
?>
所以可以用如下
方法创建对象:
$obj=new Something(6);
构造
函数自动赋值 5 给成员变量 x,构造
函数和成员
函数都是普通的
PHP函数,所以你可以使用缺省参数。
function Something($x="3",$y="5")
然后:
$obj=new Something(); // x=3 and y=5
$obj=new Something(8); // x=8 and y=5
$obj=new Something(8,9); // x=8 and y=9
缺省参数的定义
方法和 C++ 一样,因此你不能传
一个值给 Y 但让 X 取缺省值,
实参的传递是从左到右,当没有更多的实参时
函数将使用缺省参数。
只有当继承类的构造
函数被
调用后,继承类的对象才被创建,
父类的构造
函数没有被
调用,这是
PHP不同其他面向对象语言的特点,因为构造
函数调用链是面向对象编程的特点。如果你想
调用基类的构造
函数,你不得不在继承类的构造
函数中显式
调用它。这样它能工作是因为在继承类中
父类的
方法全部可用。
<?
PHP function Another() {
$this->y=5;
$this->Something(); //e
xplicit call to base class constructor.
}
?>
在面向对象编程中一种好的机制是使用抽象类,抽象类是一种不能实例化而是用来给继承
类定义界面的类。设计师经常使用抽象类来强制程序员只能从特定的基类来继承,所以就能确定新类有所需的
功能,但在
PHP中没有标准的办法
做到这
一点,
不过:
如果你在定义基类是需要这个特点,可以通过在构造
函数中
调用 "
die",这样你就可以确保它不能实例化,现在定义抽象类的
函数并在每个
函数中
调用 "die",如果在继承类中程序员
不想重定义而直接
调用基类的
函数,将会产生
一个错误。此外,你需要确信因为
PHP没有类型,有些对象是从基类继承而来的继承类创建的,因此
增加一个方法在基类来辨别类(返回 "一些标识")并验证这一点,当你收到
一个对象作为参数派上用场。 但对于
一个恶棍程序没用办法,因为他可以在继承类中重定义此
函数,通常这种办法只对懒惰的程序员奏效。当然,最好的办法是
防止程序接触到基类的
代码只提供界面。
重载在
PHP中不被
支持。在面向对象编程中你可以通过定义不同参数种类和多少来重载
一个同名成员
函数。
PHP是一种松散的类型语言,所以参数类型重载是没有用的,同样参数个数不同的办法重载也不能工作。
有时候,在面向对象编程中重载构造
函数很有用,所以你能以不同的方式创建不同的对象(通过传递不同的参数个数)。
一个小巧门可以做到这一点:
<?
PHP class Myclass {
function Myclass() {
$name="Myclass".
func_num_args();
$this->$name();
//Note t
hat $this->$name() is usually wrong but here
//$name is a string with the name of the method to call.
}
function Myclass1($x) {
code;
}
function Myclass2($x,$y) {
code;
}
}
?>
通过这种办法可以部分达到重载的目的。
$obj1=new Myclass(1); //Will call Myclass1
$obj2=new Myclass(1,2); //Will call Myclass2
感觉还不错!
多态性
多态性被定义为当在运行时刻
一个对象作为参数传递时,对象能决定
调用那个
方法的能力。例如,用
一个类定义了
方法 "draw",继承类重定义 "draw" 的行为来画
圆或正方形,这样你就有
一个参数为 x 的
函数,在
函数里可以
调用 $x->draw(). 如果
支持多态性,那么 "draw"
方法的
调用就取决于对象 x 的类型。多态性在
PHP中很自然被
支持(想一想这种情况在C++编译器中如果编译,那
一个方法被
调用?然而你不
知道对象的类型
是什么,当然现在不是这种情况)。幸好
PHP支持多态性。
<?
PHP function niceDrawing($x) {
//Supose this is a method of the class Board.
$x->draw();
}
$obj=new Circle(3,187);
$obj2=new Rectangle(4,5);
$board->niceDrawing($obj); //will call the draw method of Circle.
$board->niceDrawing($obj2); //will call the draw method of Rectangle.
?>
PHP 的面向对象编程
纯对象论者认为
PHP不是真正的面向对象语言,这是对的。
PHP是一种混合语言,你可以用面向对象或传统结构编程的
方法来使用它。对于大型工程,然而你可能或需要使用纯面向对象
方法来定义类,并在你的工程中只使用对象和类。越来越大的工程通过使用面向对象的
方法会获得益处,面向对象工程非常容易维持,容易理解并且重用。这是软件工程的基本。使用这些概念在网站设计中是未来成功的关键。
PHP中的高级面向对象技
术 在回顾面向对象的基本概念之后,我将介绍一些更高级的技术。
串行化 PHP并
不支持持久性对象,在面向对象语言中持久性对象是一些经过应用程序多次
调用仍然保持其状态和
功能的对象,这意味着有一种能保存对象到
文件或
数据库中然后重新装载对象。这种机制称之为串行化。
PHP 有
一个串行化
函数,可以在对象中
调用,串行化
函数返回
一个字符串代表这个对象。然后串行化
函数保存的是成员数据而不是成员
函数。
在
PHP4中,如果你串行化
一个对象到字符串 $s, 然后
删除此对象,再反串行化对象到 $obj,你仍然可以
调用对象的
方法函数。但我不推荐这种
方法,这因为 (a) 这种
功能在将来不一定
支持(b)这导致一种幻象,如果你保存串行化对象到磁盘并
退出程序。将来重新运行此脚本时你不能反串行化此对象并希望对象的
方法函数仍有效,因为串行化出来的字符串并没有表示任何成员
函数。最后,串行化保存对象的成员变量在
PHP中非常有用,仅仅如此. (你可以串行化联合数组和数组到磁盘里)。
例子:
<?
PHP $obj=new Classfoo();
$str=serialize($obj);
// Save $str to
disk //
...some months later
//Load str
From disk
$obj2=unserialize($str)
?>
上例中,你可以恢复成员变量而没有成员
函数(根据文档)。这导致 $obj2->x 是
唯一的
方法来存取成员变量(因为没有成员
函数)。
这里还有一些
方法解决这个问题,但我留下给你因为它会搞脏这个干净的文档。
我希望
PHP将来能全面
支持串行化。
使用类来操纵保存的数据
PHP 和面向对象编程中
一个比较好的地方是你很容易定义类来操纵某些东西,并且当需要时
调用合适的类。假设有
一个HT
ML文件,你需要通过选择产品的 ID 号来选择
一个产品,你的数据保存在
数据库中,而你想
显示产品的信息,如价格
等等。你有不同种类的产品,同样的动作对不同的产品有不同的含义。例如,
显示一个声音意味着播放它,而对其他产品来说可能是
显示一个存储在
数据库的
图片。你可以用面向对象编程和
PHP来达到,
代码少但更好。
定义
一个类,定义类
应该有的
方法,然后通过继承来定义每一种产品的类(SoundItem类, Viewabl
eitem类,等等),重定义每个产品类的
方法,使它们如你所需。根据你保存在
数据库中的表的产品类型字段来给每一种产品类型定义
一个类,
一个典型的产品表应有字段(id, 类型, 价格, 描述,等等)。在脚本中你从
数据库的表中
获取类型信息,然后实例化相应类的对象:
<?
PHP $obj=new $type();
$obj->action();
?>
这是
PHP比较的特性,你可以
调用 $obj 的
显示方法或其他
方法而
不用去管对象的类型。通过这种技术,当你
增加一种新类型的对象时,你不需要去
修改脚本。这个
方法有点威力,就是定义所有对象应有的
方法而不管它的类型,然后在不同的类中以不同的方式来实现,这样就可以在脚本中对不同的类型对象使用他们,再没有 if, 没有两个程序员在同
一个文件里,
永远快乐。你相信编程是这样快乐不?维护代价小并且可重用?
如果你带领一组程序员,最好的
方法是划分
任务,每人可以对某种类和对象负责。
国际化可以用同样的技术
解决,使合适的类对应使用者选择的不同的语言等等。
复制和克隆
当你创建
一个对象 $obj, 你可以使用 $obj2 = $obj 来拷贝
一个对象,新的对象是 $obj 的
一个拷贝(不是引用),所以在赋值完新对象有 $obj 同新的状态。有时候你不想这样,只想创建和 obj 同样的新对象,
调用新对象的构造
函数如同你曾使用过 new 命令。这可以通过
PHP的串行化和使用基类并且其他类必须从基类继承来达到。
进行危险的地带
当你串行化
一个对象,你得到
一个有特定格式的字符串,如果你有好奇心,可能你会探寻其中的秘密,字符串中有
一个东西就是类的名字,你可以解开它:
<?
PHP $herring = serialize($obj);
$vec =
explode(":",$herring);
$nam = str_replace("\"", "", $vec[2]);
?>
假设你创建
一个类 "Universe" 并且使所有类都从 "Universe" 继承而来,你可以在 "Universe" 定义
一个克隆的
方法:
<?
PHP class Universe {
function __clone() {
$herring=serialize($this);
$vec=explode(":",$herring);
$nam=str_replace("\"",$vec[2]);
$ret= new $nam;
return $ret;
}
}
//Then:
$obj=new Something();
//Something extends Universe !!
$other=$obj->__clone();
?>
你所得的是类 Something 的新对象如同使用 new 一样,并且构造
函数被
调用等等。我不知道这对你是不是有用,这是
一个很好的实践,Universe 类知道它的继承类的名字。对你来说,唯一的限制是你的想象力!!!
注意:我使用的是
PHP4,
文章里有些东西可能不适合
PHP3。
-结束-
脚本宝典总结
以上是脚本宝典为你收集整理的PHP 中的面向对象编程:通向大型 PHP 工程的办法全部内容,希望文章能够帮你解决PHP 中的面向对象编程:通向大型 PHP 工程的办法所遇到的问题。
如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。