php面向对象之继承

继承: 是指以一个类为父类,另一个类可以做为其子类,
子类在继承了父类的属性/方法的基础上,进一步增添或修改.

引出继承概念

// 定义3个类, 人类, 学生类,律师类
class Human {
    private $height = 160;

    public function cry() {
        echo '5555<br />';
    }
}


class Stu {
    private $height = 170;
    public $snun = '00134';

    public function cry() {
        echo '59啊59....<br />';
    }
    public function study() {
        echo 'good good study, day day up<br />';
    }
}
class Lawer {
    private $height = '180';
    public $area = '经济案件';

    public function cry() {
        echo '5555<br />';
    }

    public function bianhu() {
        echo '我的当事人是无罪的<br />';
    }
}
$zhoukou = new Human();
$zhoukou->cry();


$xiaoming = new Stu();
$xiaoming->cry();
$xiaoming->study();

$lizhuang = new Lawer();
$lizhuang->cry();
$lizhuang->bianhu();
/**
1: 学生和律师 归根结底还是人!
自然,人的属性和方法,自然就有


2:学生和律师,虽然是人,但比最原始的人,
又多了一些属性和方法.


而我们目前写的3个类,
完成了第2点: 即有原始人的属性,又有学生/律师的独特属性

但是,没有很好的利用上第1点:
即:既然是人,那默认就应该有人的属性,何必再重新声明一遍???

这里的代码,就已经冗余! 

如何达到 学生/律师 默认就有人的属性,达到代码的重用和简洁?
答: 继承

语法:
子类 extends 父类 {
}

注意点: 子类 只能继承自 一个父类

简单的继承示例

class Human {
    private $height = 160;

    public function cry() {
        echo '5555<br />';
    }
}



// 再声明一个学生类,学生本质上还是人
// 只不过是人类中,稍微特殊一点的一个群体.
// 即:人类的基础上,衍生出学生类.
// 可以让学生类 继承自 人类
class Stu extends Human{
}

$zhoukou = new Human();
$zhoukou->cry();

/**/
$lily = new Stu();
$lily->cry();
$lily->laugh();


/*
思考:
在学生类中
cry 与 laugh方法 都没定义
为什么cry方法调用成功
laugh方法调用失败!

答:因为Stu类 继承自 Human类

现实中,继承的例子更多.
你同事高帅富,某天开了个宝马.
他没有宝马,但是他爹有宝马.

继承的范围

继承了哪些东西?
子类可以做什么扩充? 构造函数如何继承的? 私有属性/方法如何继承?

class Human {
    private $wife = '小甜甜';

    public function cry() {
        echo '5555<br />';
    }
}


class Stu extends Human{
    public function subtell() {
        echo $this->wife;
    }
}

$lisi =  new Stu();

$lisi->cry(); // 5555
$lisi->subtell(); // 出错:未定义的属性,wife属性Undefined property: Stu::$wife in 。。。

/**
问:父类不是有wife属性吗? 为什么没继承过来?
答: 私有的属性,可以理解不能继承.
    (其实能继承过来,只不过无法访问)

public protected private中,
public protected 都可以继承,并拥有访问和修改的权限
这就好比说,家产已经继承了,愿意卖就卖,愿意改就改.

而私有的,就像先祖的牌位,继承下来
但是无权动,只能供着.

这里写图片描述

举例:

class Human {
    private $wife = '小甜甜';
    public $age = 22;
    public function cry() {
        echo '5555<br />';
    }

    public function pshow() {
        echo $this->wife,'<br />';
    }
}


class Stu extends Human{
    private $wife = '凤姐';

    public $height = 180;
    public function sshow() {
        parent::pshow();
        echo $this->wife,'<br />';
    }
}

$lisi =  new Stu();
$lisi->sshow();
/**最后一句中:思考?
如果把Stu类中的 wife=凤姐去掉,什么效果?  // echo $this->wife 出错;未定义属性Undefined property: Stu::$wife

如果把Human类中的 wife=小甜甜去掉,什么效果? //  parent::pshow() 出错;无权访问Cannot access private property Stu::$wife 

子类继承父类的属性/方法,可以修改或增加

这里所说的继承过来的大环境,是指 protected /public

class sixty {
    protected $wine = '1斤';
    public function play() {
        echo '谈理想<br />';
    }
}

class nine extends sixty{
    public function play() {
        echo '玩网游,宅!<br />';
    }

    public function momo() {
        echo '妹子,认识一下<br />';
    }

    public function showW() {
        echo $this->wine,'<br />';
    }
}
$s9 = new nine();
$s9->showW(); echo '<br />';  // 父类有的,继承过来
$s9->play(); //  父类有的,继承过来,可以修改/覆盖(overide).
$s9->momo(); // 父类没有,可以添加

继承的权限变化

继承自父类的属性/方法
权限只能越来越宽松或不变,不能越来越严格.

class Human {
    public function cry() {
        echo '555<br />';
    }
}
class Stu extends Human{
    protected function cry() {
        echo '5959<br />';
    }
}
/**
Fatal error: Access level to Stu::cry() must be public (as in class Human) in 。。。

子类的cry比父类的cry方法,权限要严格.
这不行,继承时,权限只能越来越宽松或不变,不能越来越严格.

构造方法的继承

构造方法也是可以继承的,而且继承的原则和普通方法一样.

如果子类也声明构造函数,则父类的构造函数,被覆盖了!如果父类构造函数被覆盖了,自然,只执行子类中新的构造函数.

class Human {
    public function __construct(){
        echo '呱呱坠地!<br />';
    }
}
class Stu extends Human {
}
$ming = new Stu(); // 呱呱坠地,这说明构造函数也是可以继承的

class King extends Human {
    public function __construct() {
        echo '红光满屋,终日不散<br />';
    }
}
$king=new King(); //'红光满屋,终日不散 ,父类的构造函数已经被覆盖

引发一个问题:
如果是一个数据库操作类,或者model类我们肯定是要继承过去再使用,不能直接操作model类.
而model类的构造函数,又做了许多初始化工作.
我重写的model类的构造函数之后,导致初始化工作完不成了,怎么办?
答: 如果子类继承时,子类有构造函数,保险一点,调用 parent::__construct

class Mysql {
    protected $conn = NULL;
    public function __construct() {
        $this->conn = mysql_connect('localhost','root','111111');
    }

    public function query($sql) {
        return mysql_query($sql,$this->conn);
    }
}
class MyDb extends Mysql{
    public function __construct() {
        // 如果子类继承时,有构造函数,保险一点
        parent::__construct();

        // 然后再写自己的业务逻辑
    }

    public function autoInsert() {
        return $this->query('use test');
    }
}

和java的不同
这一点和java的面向对象,也有不同.
在java中,实例化子类时, 父类的构造函数运行,且先运行然后运行子类的构造函数
java中构造函数不是 __construct(),而是和类名相同的方法理解为构造函数

public class ExtTest
{
    public static void main (String[] args)
    {
        Stu ming = new Stu();
    }

}


class Human
{
    Human ()
    {
        System.out.println("Human");
    }
}


class Stu extends Human
{
    Stu()
    {
        System.out.println("Stu");
    }
}
/**
Human
Stu
说明,父类,子类构造函数,先后调用
而在PHP中,只调用子类自己的,或子类继承的构造函数
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值