Chinaunix首页 | 论坛 | 博客
  • 博客访问: 898776
  • 博文数量: 1812
  • 博客积分: 90800
  • 博客等级: 元帅
  • 技术积分: 22390
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-03 18:35
文章分类

全部博文(1812)

文章存档

2008年(1812)

我的朋友

分类:

2008-05-03 20:07:23

技术文章 翻译:Victoria / 孤独过客

如需转载,请指明出处




(二) PHP5的新特性

接下来请按照顺序看一下被强化的PHP5的性能。首先是最为重要的面向对象性能,类的实体特性在大幅度的被修改着。这里说的仅是关于类的新特性。

? 对象的参照过渡是默认的(default)
? 引入访问属性的限制
? 引入访问方法的限制
? 抽象类和抽象方法
? 接口
? final声明
? 名空间
? 类内常量
? 类变量
? 统一构建器
? 析构函数(Distructor)
? 其他附属特性

以上内容是根据2003年4月22日CVS上登录版本资料所写的,在正式的发布之前,也有变动的可能性。

■对象的默认参照过渡

在PHP4中,在以变量$var1为类的实体对象的时候,如果$var2 = $var1;那么,在$var2中,$var1的复制被代入。明显的,$var2为了指向与$var1相同的对象,就要写成$var2 =& $var1,必须要加上&作为参照。
而在PHP5,对象的代入将成为自动的参照过渡。也就是说,$var2=$var1,两者指向相同的对象。如果想要同php4一样,带入copy,那么就会运用到导入__clone()的方法。
$var2 = $var1->__clone();此处,clone前面是两个连续的“_”
(这仅仅是类的实体的特性)

■引入访问属性的限制

在PHP4的类中,连同属性和方法在内,可以自由的访问类的内外任何地方,而没有限制。因此,用户就无法防范属性的无意中的更改。

而在PHP5中,同C 和Java一样,导入了private, protected, public三个等级的访问限制,使得类的设计者能够对属性和方法的使用方法进行限定。以下是各种访问限制的意思。

? Public: 可以自由的在类的内外任何地方进行参照、变更
? Private: 只能在这个类的方法中进行参照、变更
? Protected:能够在这个类以及继承了这个类的另一个类的方法中进行参照、变更。另外,在继承的类中,能够写入访问指定。

在PHP4中的“var”,同以往一样与public有着相同的意思。下面就来举一个例子,让我们来看看访问限制是怎样起作用的。

class Hoge1 {
 private $var1 = 'A';
 protected $var2 = 'B';
 protected $var3 = 'C';

 function setLower() {
  $this->var1 = 'a';
  $this->var2 = 'b';
  $this->var3 = 'c';
 }
 function var1() {
  return $this->var1;
 }
 function var2() {
  return $this->var2;
 }
 function var3() {
  return $this->var3;
 }
}

在这个类中,带有$var1, $var2, $var3三个属性。$var1被声明为private, $var2和$var3是protected.在此处

$hoge=new Hoge1;
echo’var1:’.$hoge->var1.”
\n”

如果尝试参照不允许从外部进行访问的private属性,那么就会出现如下错误:

Fatal error: Cannot access private property hoge1::$var1 in /path/to/script.php on line XX

对于protected的$var2也是相同的。

但是,因为$hoge的方法是没有private和protected的,所以下面的代码能够正常运作,返回内部私有和保护变量的值。

echo 'var1: ' . $hoge->var1() . "
\n"; // var1: A
echo 'var2: ' . $hoge->var2() . "
\n"; // var2: B
echo 'var3: ' . $hoge->var3() . "
\n"; // var3: C

$hoge->setLower();

echo 'var1: ' . $hoge->var1() . "
\n"; // var1: a
echo 'var2: ' . $hoge->var2() . "
\n"; // var2: b
echo 'var3: ' . $hoge->var3() . "
\n"; // var3: c

其次,为了能够看到protected的属性的状态,我们试着创造了继承了Hoge1的类Hoge2

class Hoge2 extends Hoge1 {
 public $var3 = '3';

 function d_var1() {
  return $this->var1;
 }
 function d_var2() {
  return $this->var2;
 }
 function d_var3() {
  return $this->var3;
 }
}

在类Hoge2中,只有$var3被声明为public。在属性是protected的情况下,从子类进行访问有何种限制,是由子类的属性声明决定的。在Hoge2中,因为$var3被声明是public,因此无论是从何处都可以访问Hoge2的$var3(实体是Hoge1的$var3)。因为$var1在Hoge1中是private,因此,在Hoge2子类中Hoge1的$var1不会被继承,而在Hoge2中有可能会做出名为$var1的属性,因此,必须要明确区分Hoge1::$var1和Hoge2::$var1。

$hoge = new Hoge2;

echo 'var1: ' . $hoge->var1 . "
\n";   // var1:
// echo 'var2: ' . $hoge->var2 . "
\n";  // Error
echo 'var3: ' . $hoge->var3 . "
\n";   // var3: 3

echo 'var1: ' . $hoge->d_var1() . "
\n"; // var1:
echo 'var2: ' . $hoge->d_var2() . "
\n"; // var2: B
echo 'var3: ' . $hoge->d_var3() . "
\n"; // var3: 3

$hoge->var1是与Hoge1::var1没有关系的变量,因此不会有任何显示,因为var2有protected访问限制,所以如果不通过method就直接参照$var2,就会出现致命错误。

■引入访问方法的限制

与上述相同,此处也分为private, protected, public三种。

? Public: 能够从任何地方调用
? Private: 只能够从这个类的method内调用
? Protected: 只能够从这个类以及subclass的method中调用

此处的意思同Java和C 相同,请不要搞混。

■抽象(abstract)的类和抽象的方法

支持与Java相同的抽象类和抽象方法。抽象方法只提供了方法名的调用方式,而没有提供实体。另外,持有抽象方法的类,必须抽象宣言类本身。如果想要直接作成抽象类的对象,那么就会出现如下的致命错误。

Fatal error: Cannot instantiate abstract class ClassName

产生错误的实际的例子如下所示:


abstract class MyAbstract {
 abstract public function test();
 public function test2() {
  echo "MyAbstract::test2() called.
\n";
 }
}

class MyImplement extends MyAbstract {
 public function test() {
  echo "MyImplement::test() called.
\n";
 }
}

$obj = new MyImplement;
$obj->test();

?>

■接口(interface)

支持与Java相同的接口(interface)。接口是适合所描述的外部调用形式而设计组合起来的。
接口的实体不能够记录。相反的,实现接口的类必须持有与这个接口的方法相对应的实体。另外,类能够实现多个接口,因此,有可能实现多重继承。

interface Throwable {
 public function getMessage();
}

interface Serializable {
 public function toString();
}

class MyException implements Throwable, Serializable {
 public function getMessage() {
  return 'this is MyException message';
 }

 public function toString() {
  return 'MyException: this is MyException message';
 }
}

$e = new MyException;
echo $e->getMessage();
echo $e->toString();
?>

■final声明

同Java一样,PHP5支持final声明。如果对于一个方法追加final声明,这个方法将肯定在子类不能重载(Override)。如果方法被final声明了,但是还在子类中重载,就会出现如下错误:

Fatal error: Cannot override final method fuga::foo()

产生错误的例子:
class Fuga {
 final function foo() {
  echo "this is final function\n";
 }
}

class Hoge extends Fuga {
 function foo() {
  echo "this is not final function\n";
 }
}
?>

翻译:Victoria / 孤独过客

如需转载,请指明出处




(二) PHP5的新特性

接下来请按照顺序看一下被强化的PHP5的性能。首先是最为重要的面向对象性能,类的实体特性在大幅度的被修改着。这里说的仅是关于类的新特性。

? 对象的参照过渡是默认的(default)
? 引入访问属性的限制
? 引入访问方法的限制
? 抽象类和抽象方法
? 接口
? final声明
? 名空间
? 类内常量
? 类变量
? 统一构建器
? 析构函数(Distructor)
? 其他附属特性

以上内容是根据2003年4月22日CVS上登录版本资料所写的,在正式的发布之前,也有变动的可能性。

■对象的默认参照过渡

在PHP4中,在以变量$var1为类的实体对象的时候,如果$var2 = $var1;那么,在$var2中,$var1的复制被代入。明显的,$var2为了指向与$var1相同的对象,就要写成$var2 =& $var1,必须要加上&作为参照。
而在PHP5,对象的代入将成为自动的参照过渡。也就是说,$var2=$var1,两者指向相同的对象。如果想要同php4一样,带入copy,那么就会运用到导入__clone()的方法。
$var2 = $var1->__clone();此处,clone前面是两个连续的“_”
(这仅仅是类的实体的特性)

■引入访问属性的限制

在PHP4的类中,连同属性和方法在内,可以自由的访问类的内外任何地方,而没有限制。因此,用户就无法防范属性的无意中的更改。

而在PHP5中,同C 和Java一样,导入了private, protected, public三个等级的访问限制,使得类的设计者能够对属性和方法的使用方法进行限定。以下是各种访问限制的意思。

? Public: 可以自由的在类的内外任何地方进行参照、变更
? Private: 只能在这个类的方法中进行参照、变更
? Protected:能够在这个类以及继承了这个类的另一个类的方法中进行参照、变更。另外,在继承的类中,能够写入访问指定。

在PHP4中的“var”,同以往一样与public有着相同的意思。下面就来举一个例子,让我们来看看访问限制是怎样起作用的。

class Hoge1 {
 private $var1 = 'A';
 protected $var2 = 'B';
 protected $var3 = 'C';

 function setLower() {
  $this->var1 = 'a';
  $this->var2 = 'b';
  $this->var3 = 'c';
 }
 function var1() {
  return $this->var1;
 }
 function var2() {
  return $this->var2;
 }
 function var3() {
  return $this->var3;
 }
}

在这个类中,带有$var1, $var2, $var3三个属性。$var1被声明为private, $var2和$var3是protected.在此处

$hoge=new Hoge1;
echo’var1:’.$hoge->var1.”
\n”

如果尝试参照不允许从外部进行访问的private属性,那么就会出现如下错误:

Fatal error: Cannot access private property hoge1::$var1 in /path/to/script.php on line XX

对于protected的$var2也是相同的。

但是,因为$hoge的方法是没有private和protected的,所以下面的代码能够正常运作,返回内部私有和保护变量的值。

echo 'var1: ' . $hoge->var1() . "
\n"; // var1: A
echo 'var2: ' . $hoge->var2() . "
\n"; // var2: B
echo 'var3: ' . $hoge->var3() . "
\n"; // var3: C

$hoge->setLower();

echo 'var1: ' . $hoge->var1() . "
\n"; // var1: a
echo 'var2: ' . $hoge->var2() . "
\n"; // var2: b
echo 'var3: ' . $hoge->var3() . "
\n"; // var3: c

其次,为了能够看到protected的属性的状态,我们试着创造了继承了Hoge1的类Hoge2

class Hoge2 extends Hoge1 {
 public $var3 = '3';

 function d_var1() {
  return $this->var1;
 }
 function d_var2() {
  return $this->var2;
 }
 function d_var3() {
  return $this->var3;
 }
}

在类Hoge2中,只有$var3被声明为public。在属性是protected的情况下,从子类进行访问有何种限制,是由子类的属性声明决定的。在Hoge2中,因为$var3被声明是public,因此无论是从何处都可以访问Hoge2的$var3(实体是Hoge1的$var3)。因为$var1在Hoge1中是private,因此,在Hoge2子类中Hoge1的$var1不会被继承,而在Hoge2中有可能会做出名为$var1的属性,因此,必须要明确区分Hoge1::$var1和Hoge2::$var1。

$hoge = new Hoge2;

echo 'var1: ' . $hoge->var1 . "
\n";   // var1:
// echo 'var2: ' . $hoge->var2 . "
\n";  // Error
echo 'var3: ' . $hoge->var3 . "
\n";   // var3: 3

echo 'var1: ' . $hoge->d_var1() . "
\n"; // var1:
echo 'var2: ' . $hoge->d_var2() . "
\n"; // var2: B
echo 'var3: ' . $hoge->d_var3() . "
\n"; // var3: 3

$hoge->var1是与Hoge1::var1没有关系的变量,因此不会有任何显示,因为var2有protected访问限制,所以如果不通过method就直接参照$var2,就会出现致命错误。

■引入访问方法的限制

与上述相同,此处也分为private, protected, public三种。

? Public: 能够从任何地方调用
? Private: 只能够从这个类的method内调用
? Protected: 只能够从这个类以及subclass的method中调用

此处的意思同Java和C 相同,请不要搞混。

■抽象(abstract)的类和抽象的方法

支持与Java相同的抽象类和抽象方法。抽象方法只提供了方法名的调用方式,而没有提供实体。另外,持有抽象方法的类,必须抽象宣言类本身。如果想要直接作成抽象类的对象,那么就会出现如下的致命错误。

Fatal error: Cannot instantiate abstract class ClassName

产生错误的实际的例子如下所示:


abstract class MyAbstract {
 abstract public function test();
 public function test2() {
  echo "MyAbstract::test2() called.
\n";
 }
}

class MyImplement extends MyAbstract {
 public function test() {
  echo "MyImplement::test() called.
\n";
 }
}

$obj = new MyImplement;
$obj->test();

?>

■接口(interface)

支持与Java相同的接口(interface)。接口是适合所描述的外部调用形式而设计组合起来的。
接口的实体不能够记录。相反的,实现接口的类必须持有与这个接口的方法相对应的实体。另外,类能够实现多个接口,因此,有可能实现多重继承。

interface Throwable {
 public function getMessage();
}

interface Serializable {
 public function toString();
}

class MyException implements Throwable, Serializable {
 public function getMessage() {
  return 'this is MyException message';
 }

 public function toString() {
  return 'MyException: this is MyException message';
 }
}

$e = new MyException;
echo $e->getMessage();
echo $e->toString();
?>

■final声明

同Java一样,PHP5支持final声明。如果对于一个方法追加final声明,这个方法将肯定在子类不能重载(Override)。如果方法被final声明了,但是还在子类中重载,就会出现如下错误:

Fatal error: Cannot override final method fuga::foo()

产生错误的例子:
class Fuga {
 final function foo() {
  echo "this is final function\n";
 }
}

class Hoge extends Fuga {
 function foo() {
  echo "this is not final function\n";
 }
}
?>

技术文章 为面向对象而生的PHP5 之二为面向对象而生的PHP5 之二为面向对象而生的PHP5 之二为面向对象而生的PHP5 之二为面向对象而生的PHP5 之二为面向对象而生的PHP5 之二为面向对象而生的PHP5 之二为面向对象而生的PHP5 之二为面向对象而生的PHP5 之二为面向对象而生的PHP5 之二为面向对象而生的PHP5 之二为面向对象而生的PHP5 之二
阅读(199) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~