测试环境

  • 系统 : Linux
  • 服务器 : Apache/2.2.8 (Unix) PHP/4.4.7 mod_ssl/2.2.9 OpenSSL/0.9.8c mod_fastcgi/2.4.6 Phusion_Passenger/1.9.1 DAV/2 SVN/1.4.2
  • 内存使用量 : 19.93 MByte
  • MYSQL 版本 : 5.0.45-log
  • SQL 模式 : 沒有设置
  • PHP 版本 : 5.2.6
  • PHP 安全模式 : 关闭
  • PHP 允许来自 URL : 关闭
  • PHP 内存限制 : 90M
  • PHP Max Upload Size : 7M
  • PHP Max Post Size : 8M
  • PHP Max Script Execute Time : 30s
  • PHP Exif 支持 : 是 ( V1.4 )
  • PHP IPTC 支持 : 是
  • PHP XML 支持 : 是

call.php
[code=’php’]
‘;
$a = new A();
echo $a -> a1.’
‘;
echo $a -> b -> b1.’
‘;

$a -> late();
echo $a -> b -> b1.’
‘;

echo ‘B:
‘;
// new B without a parameter, warning.
//$b = new B();
$b = new B(‘p’);
echo $b->b1.’
‘;
// Access to a private property, error.
//echo $b->b2.’
‘;

echo ‘C:
‘;
$c = new C();
?>
[/code]

define.php
[code=’php’]
‘;

// When access to a property,
// must put $this-> in front of them.
$this -> a1 = ‘aa’;
$this -> a2 = 1;
$this -> b = new B(‘not test2’);
}

function late()
{
// Not working this way
//self::b=new B(‘not test3’);

// Works fine
$this -> b = new B(‘not test3’);
}
}

class B
{
var $b1 = ‘nothing’;
private $b2 = 8;

// Can’t overwrites constructor
function B_foo()
{
echo ‘Inside B constructor
‘;
$b1 = ‘test’;
}

// Constrcutor with a parameter.
function B($what)
{
echo ‘Inside B constructor
‘;
$this -> b1 = $what;
}
}

class C extends A
{
var $c1 = 123;

function C()
{
echo ‘Inside C constructor
‘;

// This is OK.
//parent::__construct();

// This is OK too, but not so OO,
// cause sons do not know their father.
parent::A();
}
}
?>
[/code]

输出
[code=’php’]
A:
Inside A constructor
Inside B constructor
aa
not test2
Inside B constructor
not test3

B:
Inside B constructor
p

C:
Inside C constructor
Inside A constructor
Inside B constructor
[/code]

总结
PHP对于面向对象编程(OOP)的支持还是很弱的。

  • 实例化一个类只能在类外面或者类的函数中(包括构造函数),而不能随声明随new。
  • 类的构造函数可以用与类名相同的函数,或者用__construct()。构造函数不能重载,且一旦定义了带有参数的构造函数,实例化该类的时候必须传递参数,否则会报warning。
  • 类的函数中访问本类的各种属性的时候,须使用$this关键字指定本身。在我的环境中(PHP 5.2.6),self::不起作用。
  • 类的成员不声明或者使用var声明,则默认是public成员。
  • 支持继承,使用extends关键字。默认不调用基类构造函数,必须使用parent::__construct();或者parent::A();(其中A是基类的名字)来显式调用基类构造函数。parent::可以使得派生类可以访问基类的成员。protected关键字有效。
  • 实例化类的时候,如果构造函数没有参数,可以简写为new A;