PHP核心技术——继承与多态

继承:

class person{
    public $name='Tom';
    public $gender;
    static $money=10000;
    public function __construct()
    {
        echo '这里是父类',PHP_EOL;   
    }

    public function say()
    {
        echo $this->name,"\tis",$this->gender,"\r\n";
    }
}

class family extends person
{
    public $name;
    public $gender;
    public $age;
    static $money=100000;

    public function __construct()
    {
        parent::__construct(); //调用父类构造方法
        echo '这里是子类',PHP_EOL;
    }

    public function say()
    {
        parent::say();
        echo $this->name,"\tis\t",$this->gender,",and is\t",$this->age,PHP_EOL;
    }

    public function cry()
    {
        echo parent::$money,PHP_EOL;
        echo '%>_<%',PHP_EOL;
        echo self::$money,PHP_EOL; //调用自身构造方法
        echo '(*^__^)';
    }
}
$poor=new family();
$poor->name='Lee';
$poor->gender='female';
$poor->age=25;
$poor->say();
$poor->cry();
  • 在继承中,用parent指代父类,用self指代自身。使用“::”运算符(范围解析操作符)调用父类的方法。“::”操作符还用来作为类常量和静态方法的调用,不要把这两种应用混淆。
  • 如果声明类成员或方法为static,就可以不实例化类而直接访问,同时也就不能通过一个对象访问其中的静态成员(静态方法除外),也不能用“::”访问一个非静态方法。比如,把上例中的poor->cry();换成poor::cry()。
  • 继承存在什么问题:1)继承破坏封装性 2)继承是紧耦合的 3)继承扩展复杂 4)不恰当地使用继承可能违反现实世界中的逻辑。
  • 继承拥有比组合更少的代码量
class car{
    public function addoil(){
        echo "Add oil\t\n";
    }
}

class bmw extends car{

}
class benz{
    public $car;
    public function __construct(){
        $this->car=new car;
    }
    public function addoil(){
        $this->car->addoil();
    }
}
$bmw=new bmw;
$bmw->addoil();
$benz=new benz();
$benz->addoil();
  • 精心设计专门用于被继承的类,继承树的抽象层应该比较稳定,一般不要多于三层。
  • 对于不是专门用于被继承的类,禁止其被继承,也就是使用final修饰符。使用final修饰符既可防止重要方法被非法覆写,又能给编辑器寻找优化的机会。
  • 优先考虑用组合关系提高代码的可重用性。
  • 子类是一种特殊的类型,而不只是父类的一个角色。
  • 子类扩展,而不是覆盖或者使父类的功能失效。
  • 底层代码多用组合,顶层/业务层代码多用继承。底层用组合可以提高效率,避免对象臃肿。顶层代码用继承可以提高灵活性,让业务使用更方便。

多态:

  • 多态确切的含义是:同一类的对象收到相同消息时,会得到不同的结果。而这个消息是不可预测的。多态,顾名思义,就是多种状态,也就是多种结果。
  • 多态性是一种通过多种状态或阶段描述相同对象的编程方式。它的真正意义在于:实际开发中,只要关心一个接口或基类的编程,而不必关心一个对象所属于的具体类。
  • 很多地方会看到“PHP没有多态”这种说法。事实上,不是它没有,而是它本来就是多态的
class employee{
    protected function working(){
        echo '本方法需要重载才能运行';
    }
}
class teacher extends employee{
    public function working(){
        echo '教书';
    }
}
class coder extends employee{
    public function working(){
        echo '敲代码';
    }
}
function doprint($obj){
    if (get_class($obj)=='employee') {
        echo 'Error';
    }else{
        $obj->working();
    }
}
doprint(new teacher());
doprint(new coder());
doprint(new employee());
// 通过接口实现多态
interface employee{
    public function working();
}

class teacher implements employee{
    public function working(){
        echo '教书';
    }
}
class coder implements employee{
    public function working(){
        echo '敲代码';
    }
}
function doprint(employee $i)
{
    $i->working();
}
$a=new teacher;
$b=new coder;
doprint($a);
doprint($b);
  • 弱类型的PHP里多态和传统强类型语言里的多态在实现和概念上是有一些区别的,而且弱类型语言实现起多态来会更简单,更灵活。
  • 至于多态是怎么实现的,各种语言的策略是不一样的。但是,最终的实现无非就是查表和判断。
  • 类型转换不是多态。
  • PHP中父类和子类看做“继父”和“继子”关系,它们存在继承关系,但不存在血缘关系。因此子类无法向上转型为父类,从而失去多态最典型的特征。
  • 多态的本质就是if……else,只不过实现的层级不同。

参考资料

  • [PHP核心技术与最佳实践]
posted @ 2019-03-27 15:13  高级生命体  阅读(256)  评论(0编辑  收藏  举报