PHP面向对象继承用法详解(优化与减少代码重复)

5年以前  |  阅读数:1148 次  |  编程语言:PHP 

本文实例讲述了PHP面向对象继承用法。分享给大家供大家参考,具体如下:

继承

先看两个类


    <?php
    class CdProduct {
      public $playLength; // 播放时间
      public $title;
      public $producerMainName;
      public $producerFirstName;
      public $price;
      function __construct(  $title, $firstName,
                  $mainName, $price,
                  $playLength ) {
        $this->title       = $title;
        $this->producerFirstName = $firstName;
        $this->producerMainName = $mainName;
        $this->price       = $price;
        $this->playLength    = $playLength;
      }
      function getPlayLength() {
        return $this->playLength;
      }
      function getSummaryLine() {
        $base = "{$this->title} ( {$this->producerMainName}, ";
        $base .= "{$this->producerFirstName} )";
        $base .= ": playing time - {$this->playLength}";
        return $base;
      }
      function getProducer() {
        return "{$this->producerFirstName}".
            " {$this->producerMainName}";
      }
    }
    class BookProduct {
      public $numPages; // 看的页数
      public $title;
      public $producerMainName;
      public $producerFirstName;
      public $price;
      function __construct(  $title, $firstName,
                  $mainName, $price,
                  $numPages ) {
        $this->title       = $title;
        $this->producerFirstName = $firstName;
        $this->producerMainName = $mainName;
        $this->price       = $price;
        $this->numPages     = $numPages;
      }
      function getNumberOfPages() {
        return $this->numPages;
      }
      function getSummaryLine() {
        $base = "{$this->title} ( {$this->producerMainName}, ";
        $base .= "{$this->producerFirstName} )";
        $base .= ": page count - {$this->numPages}";
        return $base;
      }
      function getProducer() {
        return "{$this->producerFirstName}".
            " {$this->producerMainName}";
      }
    }
    $product1 = new CdProduct("cd1", "bob", "bobbleson", 4, 50 );
    print $product1->getSummaryLine();
    print "\n";
    $product2 = new BookProduct("book1", "harry", "harrelson", 4, 30 );
    print $product2->getSummaryLine();
    print "\n";
    ?>

输出:

cd1 ( bobbleson, bob ): playing time - 50
book1 ( harrelson, harry ): page count - 30

点评:这两个类,代码重复性太高,有相同性,也有差异性。不如用继承来简化处理。

采用继承来处理


    <?php
    class ShopProduct {
      public $numPages;
      public $playLength;
      public $title;
      public $producerMainName;
      public $producerFirstName;
      public $price;
      function __construct(  $title, $firstName,
                  $mainName, $price,
                  $numPages=0, $playLength=0 ) {
        $this->title       = $title;
        $this->producerFirstName = $firstName;
        $this->producerMainName = $mainName;
        $this->price       = $price;
        $this->numPages     = $numPages;
        $this->playLength    = $playLength;
      }
      function getProducer() {
        return "{$this->producerFirstName}".
            " {$this->producerMainName}";
      }
      function getSummaryLine() {
        $base = "$this->title ( {$this->producerMainName}, ";
        $base .= "{$this->producerFirstName} )";
        return $base;
      }
    }
    class CdProduct extends ShopProduct {
      function getPlayLength() { // 增加属于自己的方法
        return $this->playLength;
      }
      function getSummaryLine() { // 改造了父类的方法
        $base = "{$this->title} ( {$this->producerMainName}, ";
        $base .= "{$this->producerFirstName} )";
        $base .= ": playing time - {$this->playLength}";
        return $base;
      }
    }
    class BookProduct extends ShopProduct {
      function getNumberOfPages() {
        return $this->numPages;
      }
      function getSummaryLine() {
        $base = "{$this->title} ( {$this->producerMainName}, ";
        $base .= "{$this->producerFirstName} )";
        $base .= ": page count - {$this->numPages}";
        return $base;
      }
    }
    $product1 = new CdProduct("cd1", "bob", "bobbleson", 4, null, 50 );
    print $product1->getSummaryLine();
    print "\n";
    $product2 = new BookProduct("book1", "harry", "harrelson", 4, 30 );
    print $product2->getSummaryLine();
    print "\n";
    ?>

输出:

cd1 ( bobbleson, bob ): playing time - 50
book1 ( harrelson, harry ): page count - 30

点评:继承处理很好的解决了差异性,相通性问题。

进一步优化处理


    <?php
    class ShopProduct {
      // 抽离出共有属性
      public $title;
      public $producerMainName;
      public $producerFirstName;
      public $price;
      function __construct(  $title, $firstName,
                  $mainName, $price ) {
        $this->title       = $title;
        $this->producerFirstName = $firstName;
        $this->producerMainName = $mainName;
        $this->price       = $price;
      }
      function getProducer() {
        return "{$this->producerFirstName}".
            " {$this->producerMainName}";
      }
      function getSummaryLine() {
        $base = "{$this->title} ( {$this->producerMainName}, ";
        $base .= "{$this->producerFirstName} )";
        return $base;
      }
    }
    class CdProduct extends ShopProduct {
      // 抽离出属于自己特有的属性
      public $playLength;
      function __construct(  $title, $firstName,
                  $mainName, $price, $playLength ) {
        parent::__construct(  $title, $firstName,
                    $mainName, $price ); // 继承父类的构造函数
        $this->playLength = $playLength; // 处理自己专有的属性
      }
      function getPlayLength() {
        return $this->playLength;
      }
      function getSummaryLine() {
        $base = "{$this->title} ( {$this->producerMainName}, ";
        $base .= "{$this->producerFirstName} )";
        $base .= ": playing time - {$this->playLength}";
        return $base;
      }
    }
    class BookProduct extends ShopProduct {
      public $numPages;
      function __construct(  $title, $firstName,
                  $mainName, $price, $numPages ) {
        parent::__construct(  $title, $firstName,
                    $mainName, $price );
        $this->numPages = $numPages;
      }
      function getNumberOfPages() {
        return $this->numPages;
      }
      function getSummaryLine() {
        $base = "$this->title ( $this->producerMainName, ";
        $base .= "$this->producerFirstName )";
        $base .= ": page count - $this->numPages";
        return $base;
      }
    }
    $product1 = new CdProduct("cd1", "bob", "bobbleson", 4, 50 );
    print $product1->getSummaryLine();
    print "\n";
    $product2 = new BookProduct("book1", "harry", "harrelson", 4, 30 );
    print $product2->getSummaryLine();
    print "\n";
    ?>

输出:

cd1 ( bobbleson, bob ): playing time - 50
book1 ( harrelson, harry ): page count - 30

点评:这里把共有属性在父类中,其他个性属性放在自己的类中处理。并设置自己的构造方法,继承父类的构造方法。

进一步继承父类的方法


    <?php
    class ShopProduct {
      public $title;
      public $producerMainName;
      public $producerFirstName;
      public $price;
      function __construct(  $title, $firstName,
                  $mainName, $price ) {
        $this->title       = $title;
        $this->producerFirstName = $firstName;
        $this->producerMainName = $mainName;
        $this->price       = $price;
      }
      function getProducer() {
        return "{$this->producerFirstName}".
            " {$this->producerMainName}";
      }
      function getSummaryLine() {
        $base = "{$this->title} ( {$this->producerMainName}, ";
        $base .= "{$this->producerFirstName} )";
        return $base;
      }
    }
    class CdProduct extends ShopProduct {
      public $playLength;
      function __construct(  $title, $firstName,
                  $mainName, $price, $playLength ) {
        parent::__construct(  $title, $firstName,
                    $mainName, $price );
        $this->playLength = $playLength;
      }
      function getPlayLength() {
        return $this->playLength;
      }
      function getSummaryLine() {
        $base = parent::getSummaryLine();
        $base .= ": playing time - {$this->playLength}";
        return $base;
      }
    }
    class BookProduct extends ShopProduct {
      public $numPages;
      function __construct(  $title, $firstName,
                  $mainName, $price, $numPages ) {
        parent::__construct(  $title, $firstName,
                    $mainName, $price );
        $this->numPages = $numPages;
      }
      function getNumberOfPages() {
        return $this->numPages;
      }
      function getSummaryLine() {
        $base = parent::getSummaryLine();
        $base .= ": page count - {$this->numPages}";
        return $base;
      }
    }
    $product1 = new CdProduct("cd1", "bob", "bobbleson", 4, 50 );
    print $product1->getSummaryLine();
    print "\n";
    $product2 = new BookProduct("book1", "harry", "harrelson", 4, 30 );
    print $product2->getSummaryLine();
    print "\n";
    ?>

输出:

cd1 ( bobbleson, bob ): playing time - 50
book1 ( harrelson, harry ): page count - 30

点评:同样的结果,可以优化优化再优化。这里继承父类的方法。parent::getSummaryLine()。不过这个用的比较少。

继续添加一些有意思的内容


    <?php
    class ShopProduct {
      private $title;
      private $discount = 0;
      private $producerMainName;
      private $producerFirstName;
      protected $price;
      function __construct(  $title, $firstName,
                  $mainName, $price ) {
        $this->title       = $title;
        $this->producerFirstName = $firstName;
        $this->producerMainName = $mainName;
        $this->price       = $price;
      }
      function setDiscount( $num ) {
        $this->discount=$num;
      }
      function getPrice() {
        return ($this->price - $this->discount);
      }
      function getProducer() {
        return "{$this->producerFirstName}".
            " {$this->producerMainName}";
      }
      function getSummaryLine() {
        $base = "{$this->title} ( {$this->producerMainName}, ";
        $base .= "{$this->producerFirstName} )";
        return $base;
      }
    }
    class CdProduct extends ShopProduct {
      public $playLength;
      function __construct(  $title, $firstName,
                  $mainName, $price, $playLength ) {
        parent::__construct(  $title, $firstName,
                    $mainName, $price );
        $this->playLength = $playLength;
      }
      function getPlayLength() {
        return $this->playLength;
      }
      function getSummaryLine() {
        $base = parent::getSummaryLine();
        $base .= ": playing time - {$this->playLength}";
        return $base;
      }
    }
    class BookProduct extends ShopProduct {
      public $numPages;
      function __construct(  $title, $firstName,
                  $mainName, $price, $numPages ) {
        parent::__construct(  $title, $firstName,
                    $mainName, $price );
        $this->numPages = $numPages;
      }
      function getPrice() {
        return $this->price;
      }
      function getNumberOfPages() {
        return $this->numPages;
      }
      function getSummaryLine() {
        $base = parent::getSummaryLine();
        $base .= ": page count - {$this->numPages}";
        return $base;
      }
    }
    $product1 = new CdProduct("cd1", "bob", "bobbleson", 4, 50 );
    $product1->setDiscount( 3 );
    print $product1->getSummaryLine();
    print "\n";
    print "price: {$product1->getPrice()}\n";
    $product2 = new BookProduct("book1", "harry", "harrelson", 4, 30 );
    $product2->setDiscount( 3 ); // 折扣对book无效
    print $product2->getSummaryLine();
    print "\n";
    print "price: {$product2->getPrice()}\n";
    ?>

输出:

cd1 ( bobbleson, bob ): playing time - 50
price: 1
book1 ( harrelson, harry ): page count - 30
price: 4

点评:父类添加了折扣,book继承之后,修改了getPrice方法,所以折扣对book无效。

私有化属性,通过方法来设置与获取


    <?php
    class ShopProduct {
      // 私有化属性,通过方法来设置与获取
      private $title;
      private $producerMainName;
      private $producerFirstName;
      protected $price;
      private $discount = 0;
      public function __construct(  $title, $firstName,
                  $mainName, $price ) {
        $this->title       = $title;
        $this->producerFirstName = $firstName;
        $this->producerMainName = $mainName;
        $this->price       = $price;
      }
      public function getProducerFirstName() {
        return $this->producerFirstName;
      }
      public function getProducerMainName() {
        return $this->producerMainName;
      }
      public function setDiscount( $num ) {
        $this->discount=$num;
      }
      public function getDiscount() {
        return $this->discount;
      }
      public function getTitle() {
        return $this->title;
      }
      public function getPrice() {
        return ($this->price - $this->discount);
      }
      public function getProducer() {
        return "{$this->producerFirstName}".
            " {$this->producerMainName}";
      }
      public function getSummaryLine() {
        $base = "{$this->title} ( {$this->producerMainName}, ";
        $base .= "{$this->producerFirstName} )";
        return $base;
      }
    }
    class CdProduct extends ShopProduct {
      private $playLength = 0;
      public function __construct(  $title, $firstName,
                  $mainName, $price, $playLength ) {
        parent::__construct(  $title, $firstName,
                    $mainName, $price );
        $this->playLength = $playLength;
      }
      public function getPlayLength() {
        return $this->playLength;
      }
      public function getSummaryLine() {
        $base = parent::getSummaryLine();
        $base .= ": playing time - {$this->playLength}";
        return $base;
      }
    }
    class BookProduct extends ShopProduct {
      private $numPages = 0;
      public function __construct(  $title, $firstName,
                  $mainName, $price, $numPages ) {
        parent::__construct(  $title, $firstName,
                    $mainName, $price );
        $this->numPages = $numPages;
      }
      public function getNumberOfPages() {
        return $this->numPages;
      }
      public function getSummaryLine() {
        $base = parent::getSummaryLine();
        $base .= ": page count - {$this->numPages}";
        return $base;
      }
      public function getPrice() {
        return $this->price;
      }
    }
    $product1 = new CdProduct("cd1", "bob", "bobbleson", 4, 50 );
    print $product1->getSummaryLine()."\n";
    $product2 = new BookProduct("book1", "harry", "harrelson", 4, 30 );
    print $product2->getSummaryLine()."\n";
    ?>

输出:

cd1 ( bobbleson, bob ): playing time - 50
book1 ( harrelson, harry ): page count - 30

点评:这里进一步私有化了属性,要想获取只能通过方法。这样就确保了安全性。

更多关于PHP相关内容感兴趣的读者可查看本站专题:《php面向对象程序设计入门教程》、《PHP基本语法入门教程》、《PHP运算与运算符用法总结》、《PHP网络编程技巧总结》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总

希望本文所述对大家PHP程序设计有所帮助。

 相关文章:
PHP分页显示制作详细讲解
SSH 登录失败:Host key verification failed
将二进制数据转为16进制以便显示
获取IMSI
获取IMEI
Java生成UUID
PHP自定义函数获取搜索引擎来源关键字的方法
让你成为最历害的git提交人
在Zeus Web Server中安装PHP语言支持
指定应用ID以获取对应的应用名称
再谈PHP中单双引号的区别详解
Python 2与Python 3版本和编码的对比
php+ajax+json 详解及实例代码
Yii2汉字转拼音类的实例代码
php封装的page分页类完整实例
php数组合并array_merge()函数使用注意事项
PHP实现简单爬虫的方法
PHP设计模式之工厂模式与单例模式
php实现数组中索引关联数据转换成json对象的方法
wget使用技巧