关于多继承层次的set魔术方法解析

我们通常会将私有方法定义为$_pro,然后用一个set魔术方法进行修改,如下:

class A

{

private $_pro;

 

public function __set($pro, $val)

{

    $pro = "-".$pro;

    $this->$pro = $val;

}

 

}

 

通过类A的魔术set方法,只要私有变量定义为$_pro形式,那么会自动设置形如$obj->pro = $value的表达式。如果类B继承自类A,同时也会继承这个set魔术方法,如下:

class B extends A

{

private $_proInB;

}

那么,对于类B的实例,我们使用$objOfB->proInB = $value会不会设置相应的值呢?答案是否定的,因为这个表达式会首先寻找公有变量,然后寻找set方法,set方法定义在父类当中,父类的set方法,是无法访问子类的私有变量的。

 

这里面揭示了一个典型的场景,那就是父类的方法只能操纵父类的私有成员,而无法操纵子类的私有变量,因此,在设计父类的方法时,不要期待这个方法会对子类的私有成员产生作用。

 

在上面这个例子当中,如果期待无需重写set方法,就能对子类的变量进行读写,那么,可以采取的办法有两种:

1)将子类的属性定义为public,这样,父类的set方法在遇到这些变量时,会发挥多态的特性,读写子类的属性。

这种方法弊端很多,也极不规范,因此正常的类设计应当避免。

2)将类的属性读写单独设定getter和setter方法,然后在set和get魔术方法当中调用,如果我们重写类A如下:

class A

{

private $_pro;

 

public function getPro(){

    $pro = "-".$pro;

    return $this->$pro;

}

public function setPro($val){

    $pro = "-".$pro;

    $this->$pro=$val;

}

 

 

public function __set($pro, $val)

{

    $method = 'set'.$pro;

    if($method_exists($this, $method){

        $this->$method($val);

    }

}

 

}

 

那么,在类B当中,当设计新的私有属性时,可以设定getter和setter方法,那么就无需重定义set魔术方法了。这里的区别是,父类的set方法不能访问子类的私有成员,但是setter和getter是公共的,可以访问。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值