php面向对象之继承

    xiaoxiao2025-06-13  13

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

    引出继承概念

    // 定义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中,只调用子类自己的,或子类继承的构造函数
    转载请注明原文地址: https://ju.6miu.com/read-1299897.html
    最新回复(0)