继承

继承是从一个基类得到一个或多个派生类的机制。创建继承树的第一步是找到现有基类元素中不适合放在一起,或者不需要进行特殊处理的类方法。要创建一个子类,必须在类声明中使用extends关键字。子类默认继承父类所有的public和protected方法,但是不能继承private方法或属性。子类可以扩展和修改父类的功能。

<?php

// 继承
// 前面的商品类,面临新的需求,例如:需要显示图书的总页数,作者;而对于手机,则需要显示手机的品牌,操作系统等信息。
// 我们可以在ShopProduct类中增加数据,也可以将ShopProduct类拆分成两个单独的类
// 强行将不同的类字段合并到一个类中,会导致对象臃肿,产生冗余的属性和方法
// 而分拆类会产生重复代码

class ShopProduct {
    public $title        = '商品名称';
    public $producerName = '制造商名称';
    public $place        = '产地';
    public $price        = 0;

    function __construct( $title, $producerName, $place, $price ) {
        $this->title        = $title;
        $this->producerName = $producerName;
        $this ->place       = $place;
        $this->price        = $price;
    }
    function getProducer() {
        return "$this->place" . "$this->producerName";
    }
    function getSummaryLine() {
        $base = "$this->title" . "\t" . "$this->place" . "\t" . "$this->producerName";
        return $base;
    }
}

//继承父类使用extends关键词

class BookProduct extends ShopProduct {
    public $numPages;
    public $author;

    //构造函数
    function __construct( $title, $producerName, $place, $price, $numPages, $author ) {
        parent::__construct ( $title, $producerName, $place, $price ); //直接调用父类的方法,减少重复代码
        $this->numPages = $numPages;
        $this->author   = $author;
    }
    //子类自有方法
    function getNumPages() {
        return $this->numPages;
    }
    function getAuthor() {
        return $this->author;
    }
    function getSummaryLine() {
        $base = parent::getSummaryLine();
        $base .= "\t" . "$this->numPages" . "\t" ."$this->author";
        return $base;
    }
}

class PhoneProduct extends ShopProduct {
    public $brand;
    public $os;

    //构造函数
    function __construct( $title, $producerName, $place, $price, $brand, $os ) {
        //直接调用父类的方法,减少重复代码
        parent::__construct ( $title, $producerName, $place, $price );
        $this->brand = $brand;
        $this->os    = $os;
    }
    //子类自有方法
    function getBrand() {
        return $this->brand;
    }
    function getOs() {
        return $this->os;
    }
    function getSummaryLine() {
        $base = parent::getSummaryLine();
        $base .= "\t" . "$this->brand" . "\t" ."$this->os";
        return $base;
    }
}

$book1  = new BookProduct( "信息简史", "人民邮电出版社", "北京", 69, 458, "詹姆斯·格雷克" );
$phone1 = new PhoneProduct( "荣耀3C", "华为公司", "深圳", 999, "huawei", "android 4.2" );

echo $book1->getSummaryLine();
echo "<br />";
echo $phone1->getSummaryLine();
echo "<br />";
echo $phone1->getOs();
?>

在子类中定义构造方法时,如果父类构造方法是有参数的,那么需要传递参数给父类的构造方法,否则你得到的可能是一个构造不完整的对象。如上例中的:

function __construct( $title, $producerName, $place, $price, $brand, $os ) {
        //直接调用父类的方法,减少重复代码
        parent::__construct ( $title, $producerName, $place, $price );
        $this->brand = $brand;
        $this->os    = $os;
    }

范围解析操作符(::)或者更简单地说是一对冒号,可以用于访问静态成员,类常量,还可以用于覆盖类中的属性和方法。如上例中的:

parent::__construct()

results matching ""

    No results matching ""