php 重载构造函数,PHP中的Magic Methods系列之一——构造函数__construct

PHP中有一些方法,非常的神奇,在PHP手册中被称之为Magic Methods,其中大家比较熟知的应该是__construct和__destruct,这在普通的类的定义中会经常用到,一个是构造函数,一个是析构函数。

除此以外,还有下面一些函数

__call

__callStatic

__get

__set

__isset

__unset

__sleep

__wakeup

__toString

__invoke

__set_state

__clone

在这个系列中我会将这些Magic Methods一个一个加以说明,今天要说明的是__construct,废话不多说了,进入正题吧。

__construct:从php5开始,开发者可以为类定义构造函数了,如果类定义了这个方法,新建该类的对象时会自动调用该方法,在php中是不能通过c++的利用同样函数名,不同函数参数的方式进行构造函数的重载的,比如说下面的代码

12345678910111213141516171819202122232425

class TestClass { protected $a = ''; protected $b = ''; public function __construct($a = null) { echo "Enter constructor 1"; $this->a = $a; } public function __construct($a = null, $b = null) { echo 'Enter constructor 2'; $this->a = $a; $this->b = $b; } }

上面的代码执行会出现下面的错误。

Fatal error: Cannot redeclare TestClass::__construct() in

也就是说无法通过定义两个方法名的方式来进行构造函数的重载,那就没有办法重载构造函数了么,不是,其实php的每一个函数都拥有可变参数。

12345678910111213141516171819202122232425262728293031323334353637

class TestClass { protected $a = ''; protected $b = ''; public function __construct($a = null) { echo "Enter constructor 1\n"; $this->a = $a; $args = func_get_args(); if (count($args) > 1) { $this->b = $args[1]; } } public function __get($key) { return $this->$key; } } $tc1 = new TestClass('test1'); $tc2 = new TestClass('test1', 'test2'); echo "tc1.a=$tc1->a tc1.b=$tc1->b\n"; echo "tc2.a=$tc2->a tc2.b=$tc2->b\n";

运行脚本得到的结果如下:

1234567

Enter constructor 1 Enter constructor 1 tc1.a=test1 tc1.b= tc2.a=test1 tc2.b=test2

这样就实现了构造函数的重载。如果类的定义中没有__construct方法,php5为了向前兼容,会将与类名同名的函数作为构造函数使用,如类:

1234567891011121314151617181920212223242526272829303132333435

class TTClass { protected $a = ''; protected $b = ''; public function TTClass($a = null) { $this->a = $a; $args = func_get_args(); if (count($args) > 1) { $this->b = $args[1]; } } public function __get($key) { return $this->$key; } } $tt1 = new TTClass('tt1a'); $tt2 = new TTClass('tt2a', 'tt2b'); echo "tt1.a=$tt1->a tt1.b=$tt1->b\n"; echo "tt2.a=$tt2->a tt2.b=$tt2->b\n";

输出结果如下:

123

tt1.a=tt1a tt1.b= tt2.a=tt2a tt2.b=tt2b

利用与类同名方法的函数当做构造函数来使用时,需要注意的是重载构造函数时需要与上面__construct重载的方法一样。

如果子类定义了构造函数,那么父类的构造函数不会隐式的自动调用,如果需要在子类初始化是调用父类的构造函数需要在子类的构造函数中加入parent::__construct。如下例

12345678910111213141516171819202122232425262728293031323334353637383940414243

class ParentClass { public function __construct() { echo "Now in ParentClass's constructor.\n"; echo "Parent's Constructor\n"; } } class ChildClassA extends ParentClass { public function __construct() { echo "Now in ChildClassA constructor.\n"; echo "ChildA's Constructor\n"; } } class ChildClassB extends ParentClass { public function __construct() { echo "Now in ChildClassB's constructor.\n"; parent::__construct(); echo "ChildB's Constructor\n"; } } $parent = new ParentClass(); $childA = new ChildClassA(); $childB = new ChildClassB();

脚本执行的结果如下:

123456789101112131415

Now in ParentClass's constructor. Parent's Constructor Now in ChildClassA constructor. ChildA's Constructor Now in ChildClassB's constructor. Now in ParentClass's constructor. Parent's Constructor ChildB's Constructor

上面的结果,ChildClassA的初始化过程中没有任何parent的信息,也就是说没有自动调用父类的构造函数,而在ChildClassB的构造函数中显式调用了父类的构造函数,因此也有了父类构造函数的信息打印出来。从上面的结果可以证明父类的构造函数不会隐式自动被调用,需要编码实现。

至此,__construct相关的内容大致就说完了,也许日后会遇到或者想到什么再对此进行补充吧,今天就到这里了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值