《php面向对象》 第20课:继承-构造方法

构造方法是用来初始化成员变量的,当我们实例化对象时,会自动执行构造方法。那么当使用继承时,在构造方法方面我们应该注意什么呢?

注意:在PHP的继承中,构造方法有很多的坑,需要我们去发现。

我们改造上节课中的代码,还是汽车,卡车,公交车,我们把构造方法添加上。

 

<?php

/**
 * 汽车类
 */
class Car
{
    public $wheel; //汽车轮子
    function __construct($wheel)
    {
        $this->wheel = $wheel;
    }

    public function run()
    {
        echo '能跑';
    }

    public function stop()
    {
        echo '能刹车';
    }
}

/**
 * 卡车类,继承了汽车类
 */
class Truck extends Car
{
    public $load; //载货量
}

/**
 * 公交车类,继承汽车类
 */
class Bus extends Car
{
    public $peples; //载客量

    public function say(){
        echo '报站';
    }
}


$t = new Truck();
$t->wheel = 12; //卡车12个轮子
$t->load = '20T'; //载重20吨
$t->run(); //卡车在行驶中

$b = new Bus();
$b->wheel = 6;  //公交车6个轮子
$b->peples = '50人'; //载客50人
$b->say(); //在报站

运行上面的代码,会报告很多错误。

主要错误是说:实例化truck对象和bus对象时,执行了构造方法,但缺少了一个参数。

我们分析一下:

在父类car中,我们定义了构造方法。

在子类truck和bus中,我们没有定义构造方法。

当实例化子类的对象时,系统会自动执行父类的构造方法。

因为父类的构造方法有一个参数,而我们实例化子类对象时,没有传递参数,就发生了错误。

下面我们重新改写一下代码。

<?php

/**
 * 汽车类
 */
class Car
{
    public $wheel; //汽车轮子
    function __construct($wheel)
    {
        $this->wheel = $wheel;
    }

    public function run()
    {
        echo '能跑';
    }

    public function stop()
    {
        echo '能刹车';
    }
}

/**
 * 卡车类,继承了汽车类
 */
class Truck extends Car
{
    public $load; //载货量
}

/**
 * 公交车类,继承汽车类
 */
class Bus extends Car
{
    public $peples; //载客量

    public function say(){
        echo '报站';
    }
}


$t = new Truck(12);//传递参数
printf("卡车有%d个轮子",$t->wheel);
echo '<br>';
$b = new Bus(6);//传递参数
printf("公交车有%d个轮子",$t->wheel);

运行结果如下:

如果子类有自己的构造方法,结果又会如何呢?

<?php

/**
 * 汽车类
 */
class Car
{
    public $wheel; //汽车轮子
    function __construct($wheel)
    {
        $this->wheel = $wheel;
    }

    public function run()
    {
        echo '能跑';
    }

    public function stop()
    {
        echo '能刹车';
    }
}

/**
 * 卡车类,继承了汽车类
 */
class Truck extends Car
{
    public $load; //载货量
    function __construct()
    {
    }
}

/**
 * 公交车类,继承汽车类
 */
class Bus extends Car
{
    public $peples; //载客量
    function __construct()
    {
    }

    public function say(){
        echo '报站';
    }
}


$t = new Truck(12);//传递参数
printf("卡车有%d个轮子",$t->wheel);
echo '<br>';
$b = new Bus(6);//传递参数
printf("公交车有%d个轮子",$t->wheel);

运行结果如下:

分析一下原因:

当子类有自己的构造方法时,实例化子类的对象,就会执行子类的构造方法,不会执行父类的构造方法。这是PHP与其它编程语言不同之处。

子类的构造方法没有参数,而我们实例化子类对象时传递了一个参数,为什么没有报错呢?

在PHP中,调用函数或执行方法时,可以多传递参数,不可以少传递参数。多出来的参数在传递时是无效的,不会报错。

总结:

子类继承父类时,子类没有构造方法,实例化子类对象时,会执行父类的构造方法。子类如果有自己的构造方法,实例化子类对象时,只会自动执行子类自己的构造方法。

 

那么如何实现:实例化子类对象时,既要执行子类的构造方法,又要执行父类的构造方法呢?

参见 下面的代码,我们继续改造代码。

<?php

/**
 * 汽车类
 */
class Car
{
    public $wheel; //汽车轮子
    function __construct($wheel)
    {
        $this->wheel = $wheel;
    }

    public function run()
    {
        echo '能跑';
    }

    public function stop()
    {
        echo '能刹车';
    }
}

/**
 * 卡车类,继承了汽车类
 */
class Truck extends Car
{
    public $load; //载货量
    function __construct($wheel)
    {
        //调用父类的构造方法
        parent::__construct($wheel);
    }

}

/**
 * 公交车类,继承汽车类
 */
class Bus extends Car
{
    public $peples; //载客量
    function __construct($wheel)
    {
        //调用父类的构造方法
        parent::__construct($wheel);
    }

    public function say(){
        echo '报站';
    }
}


$t = new Truck(12);//传递参数
printf("卡车有%d个轮子",$t->wheel);
echo '<br>';
$b = new Bus(6);//传递参数
printf("公交车有%d个轮子",$t->wheel);

在子类的构造方法中,使用 parent::__construct($wheel); 主动调用父类的构造方法。

当然,子类的构造方法也可以有多个参数:

<?php

/**
 * 汽车类
 */
class Car
{
    public $wheel; //汽车轮子
    function __construct($wheel)
    {
        $this->wheel = $wheel;
    }

    public function run()
    {
        echo '能跑';
    }

    public function stop()
    {
        echo '能刹车';
    }
}

/**
 * 卡车类,继承了汽车类
 */
class Truck extends Car
{
    public $load; //载货量
    function __construct($wheel,$load)
    {
        //调用父类的构造方法
        parent::__construct($wheel);
        $this->load = $load;
    }

}

/**
 * 公交车类,继承汽车类
 */
class Bus extends Car
{
    public $persons; //载客量
    function __construct($wheel,$peples)
    {
        //调用父类的构造方法
        parent::__construct($wheel);
        $this->persons = $peples;
    }

    public function say(){
        echo '报站';
    }
}


$t = new Truck(12,20);//传递两个参数
printf("卡车有%d个轮子,载重%d吨",$t->wheel,$t->load);
echo '<br>';
$b = new Bus(6,50);//传递两个参数
printf("公交车有%d个轮子,载客%d人",$t->wheel,$b->persons);

因为子类的构造方法有两个参数,所以当我们实例化子类对象时,必须传递两个参数。

好了,PHP中有关继承时的构造方法,我们已经把“坑”填平了,做为初学者,一定牢记。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李 书 明

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值