|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
把例子全部敲进去试验,完成一遍以后就会有心得了,因为你会发现为啥我的程序和书上的一模一样就是结果不正确。新手学习的时候必须承认,不容易,因为我也是过来人,你会发现原来有那么多常用的语句,函数都要记。 PHP5 中的对象已停止了较体系、较周全的调剂,如今的模样能够看起来会有些相似于 Java。本大节侧重讲述 PHP5 中新的对象形式,并举了一些较简略单纯的例子来讲明。就让本节成为你的 PHP5 之旅的一个新出发点吧。:)
* 机关函数和析构函数
* 对象的援用
* 对象的克隆
* 对象中的公有、公共及受回护形式
* 接口 (Interfaces)
* 笼统类
* __call
* __set 和 __get
* 静态成员
机关函数和析构函数
在 PHP4 中,当函数与对象同名时,这个函数将成为该对象的机关函数,而且在 PHP4 中没有析构函数的概念。
在 PHP5 中,机关函数被一致定名为 __construct,而且引入了析构函数的概念,被一致定名为 __destruct。
例一:机关函数和析构函数
class foo {
var $x;
function __construct($x) {
$this->x = $x;
}
function display() {
print($this->x);
}
function __destruct() {
print("bye bye");
}
}
$o1 = new foo(4);
$o1->display();
?>
在下面的例子中,当你终止挪用 foo 类的时分,其析构函数将会被挪用,上例中会输入 “bye bye”。
对象的援用
尽人皆知,在PHP4 中,传递变量给一个函数或办法,实践是把这个变量做了一次复制,也就意味着你传给函数或办法的是这个变量的一个正本,除非你利用了援用符号 “&” 来声明是要做一个援用,而不是一个 Copy。在 PHP5 中,对象老是以援用的模式存在的,对象中的赋值操作一样也都是一个援用操作。
例二:对象的援用
class foo {
var $x;
function setX($x) {
$this->x = $x;
}
function getX() {
return $this->x;
}
}
$o1 = new foo;
$o1->setX(4);
$o2 = $o1;
$o1->setX(5);
if($o1->getX() == $o2->getX()) print("Oh my god!");
?>
对象的克隆
如上所述,当一个对象一直以援用的模式来被挪用时,假如我想失掉该对象的一个正本,该怎样办呢?PHP5 供应了一个新的功效,就是对象的克隆,语法为 __clone。
例三:对象的克隆
class foo {
var $x;
function setX($x) {
$this->x = $x;
}
function getX() {
return $this->x;
}
}
$o1 = new foo;
$o1->setX(4);
$o2 = $o1->__clone();
$o1->setX(5); if($o1->getX() != $o2->getX()) print("Copies are independant");
?>
对象克隆的办法在其它良多使用法式言语中都是存在的,所以你不用忧虑它的不乱性。:)
对象中的公有、公共及回护形式
PHP4 中,一个对象的一切办法和变量都是公共的,这意味着你可以在一个对象的内部操作个中的恣意一个变量和办法。PHP5 引入了三种新的用来掌握这类存取权限的形式,它们是:公共的(Public)、受回护的(Protected)及公有的(Private)。
公共形式(Public):答应在对象内部停止操作掌握。
公有形式(Private):只答应本对象内的办法对其停止操作掌握。
受回护形式(Protected):答应本对象及其父对象对其停止操作掌握。
例四: 对象中的公有、公共及受回护形式
class foo {
private $x;
public function public_foo() {
print("I'm public");
}
protected function protected_foo() {
$this->private_foo(); //Ok because we are in the same class we can call private methods
print("I'm protected");
}
private function private_foo() {
$this->x = 3;
print("I'm private");
}
}
class foo2 extends foo {
public function display() {
$this->protected_foo();
$this->public_foo();
// $this->private_foo(); // Invalid! the function is private in the base class
}
} $x = new foo();
$x->public_foo();
//$x->protected_foo(); //Invalid cannot call protected methods outside the class and derived classes
//$x->private_foo(); //Invalid private methods can only be used inside the class $x2 = new foo2();
$x2->display();
?>
提醒:对象中的变量老是以公有模式存在的,直接操作一个对象中的变量不是一个好的面向对象编程的习气,更好的举措是把你想要的变量交给一个对象的办法去向理。
接口 (Interfaces)
尽人皆知,PHP4 中的对象撑持承继,要使一个对象成为另外一个对象的派生类,你需求利用相似 “class foo extends parent” 的代码来掌握。 PHP4 和 PHP5 中,一个对象都仅能承继一次,多重承继是不被撑持的。不外,在 PHP5 中发生了一个新的名词:接口,接口是一个没有详细处置代码的特别对象,它仅仅界说了一些办法的称号及参数,尔后的对象就能够便利的利用 'implement' 关头字把需求的接口整合起来,然后再到场详细的履行代码。
例五:接口
interface displayable {
function display();
}
interface printable {
function doprint();
}
class foo implements displayable,printable {
function display() {
// code
} function doprint() {
// code
}
}
?>
这对进步代码的可读性及浅显性有很大的匡助,经由过程下面的例子可以看到,对象 foo 包括了 displayable 和 printable 两个接口,这时候咱们就能够清晰的晓得,对象 foo 必定会有一个 display() 办法和一个 print() 办法,只需求去懂得接口局部,你就能够等闲的操作该对象而不用去关怀对象的外部是若何运作的。
笼统类
笼统类不克不及被实例化。
笼统类与其它类一样,答应界说变量及办法。
笼统类一样可以界说一个笼统的办法,笼统类的办法不会被履行,不外将有能够会在其派生类中履行。
例六:笼统类
abstract class foo {
protected $x;
abstract function display();
function setX($x) {
$this->x = $x;
}
}
class foo2 extends foo {
function display() {
// Code
}
}
?>
__call
PHP5 的对象新增了一个公用办法 __call(),这个办法用来监督一个对象中的其它办法。假如你试着挪用一个对象中不存在的办法,__call 办法将会被主动挪用。
例七:__call
class foo {
function __call($name,$arguments) {
print("Did you call me? I'm $name!");
}
} $x = new foo();
$x->doStuff();
$x->fancy_stuff();
?>
这个特别的办法可以被用来完成“过载(overloading)”的举措,如许你就能够反省你的参数而且经由过程挪用一个公有的办法来传递参数。
例八:利用 __call 完成“过载”举措
class Magic {
function __call($name,$arguments) {
if($name=='foo') {
if(is_int($arguments[0])) $this->foo_for_int($arguments[0]);
if(is_string($arguments[0])) $this->foo_for_string($arguments[0]);
}
} private function foo_for_int($x) {
print("oh an int!");
} private function foo_for_string($x) {
print("oh a string!");
}
} $x = new Magic();
$x->foo(3);
$x->foo("3");
?>
__set 和 __get
这是一个很棒的办法,__set 和 __get 办法可以用来捕捉一个对象中不存在的变量和办法。
例九: __set 和 __get
class foo {
function __set($name,$val) {
print("Hello, you tried to put $val in $name");
}
function __get($name) {
print("Hey you asked for $name");
}
}
$x = new foo();
$x->bar = 3;
print($x->winky_winky);
?>
类型唆使
在 PHP5 中,你可以在对象的办法中指明其参数必需为另外一个对象的实例。
例十:类型唆使
class foo {
// code ...
}
class bar {
public function process_a_foo(foo $foo) {
// Some code
}
}
$b = new bar();
$f = new foo();
$b->process_a_foo($f);
?>
可以看出,咱们可以显性的在参数前指明一个对象的称号,PHP5 会辨认出这个参数将会如果一个对象实例。
静态成员
静态成员和静态办法在面象对象编程的术语中被称作 “对象办法(class methods)” 和 “对象变量(class variables)”。
“对象办法” 在一个对象没有实例化前答应被挪用。一样,“对象变量” 在一个对象没有实例化前可以被自力操作掌握(不需求用一个对象的办法来掌握)。
例十一:对象办法和对象变量
class calculator {
static public $pi = 3.14151692;
static public function add($x,$y) {
return $x + $y;
}
}
$s = calculator::$pi;
$result = calculator::add(3,7);
print("$result");
?>
异常处置
异常处置是公认的处置法式毛病的幻想办法,在 Java 及 C++ 中都有这个概念,咱们欣喜的看到,在 PHP5 已到场了这方面的使用。你可以测验考试利用 “try” 和 “catch” 来掌握法式的毛病。
例十二:异常处置
class foo {
function divide($x,$y) {
if($y==0) throw new Exception("cannot divide by zero");
return $x/$y;
}
}
$x = new foo();
try {
$x->divide(3,0);
} catch (Exception $e) {
echo $e->getMessage();
echo "n
n";
// Some catastrophic measure here
}
?>
上例中,咱们利用了 “try” 来履行花括号中的语句,当有毛病产生的时分,代码会把毛病交给 “catch” 子句来处置,在 “catch” 子句中,你需求指明要把毛病交给某个对象处置,如许做可使代码布局看起来更明晰,由于如今咱们可以把一切的毛病信息交给一个对象来处置。
自界说毛病处置
你可以很便利的用自界说的处置毛病的代码来掌握你的法式中的不测。你仅仅需求从异常类中派生出一个本人的毛病掌握类,在你本人的毛病掌握类中,你需求有一个机关函数和一个 getMessage 办法,以下是一个例子。
例十三:自界说毛病处置
class WeirdProblem extends Exception {
private $data;
function WeirdProblem($data) {
parent::exception();
$this->data = $data;
}
function getMessage() {
return $this->data . " caused a weird exception!";
}
}
?>
如今咱们可使用 “throw new WeirdProblem($foo)” 来抛出一个毛病句柄,假如毛病在 “try” 的代码块中产生,PHP5 会主动把毛病交给 “catch” 局部来处置。
称号空间
称号空间对类的分组或函数分组很有效。它可以把一些相干的类或函数给组合到一同,便利今后挪用。
例十四:称号空间
namespace Math {
class Complex {
//...code...
function __construct() {
print("hey");
}
}
} $m = new Math::Complex();
?>
注重你需求在何种情形下利用称号空间,在实践应用中,你能够会需求声明两个或多个称号一样的对象来做分歧的工作,那末你就能够把他们分离放到分歧的称号空间中去(但接口是要不异的)。
你的确对PHP有兴趣,那么选择教材也是很重要的。 |
|