• 技术文章 >php教程 >PHP开发

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

    高洛峰高洛峰2016-12-30 09:57:19原创726

    本文实例讲述了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中文网!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:Yii2 framework学习笔记(五) -- 为后台更换皮肤 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • PHP 高手之路(二)• 如何优化设置phpcms v9的url规则?• 另类操作dedecms 文章的审核状态• MySQL命令行参数完整版• 静态html文件执行php语句的方法(推荐)
    1/1

    PHP中文网