zoukankan      html  css  js  c++  java
  • 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 "
    ";
    
    $product2 = new BookProduct("book1", "harry", "harrelson", 4, 30 );
    print $product2->getSummaryLine();
    print "
    ";
    ?>
    输出:
    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 "
    ";
    
    $product2 = new BookProduct("book1", "harry", "harrelson", 4, 30 );
    print $product2->getSummaryLine();
    print "
    ";
    
    ?>
    输出:
    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 "
    ";
    
    $product2 = new BookProduct("book1", "harry", "harrelson", 4, 30 );
    print $product2->getSummaryLine();
    print "
    ";
    
    ?>
    输出:
    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 "
    ";
    
    $product2 = new BookProduct("book1", "harry", "harrelson", 4, 30 );
    print $product2->getSummaryLine();
    print "
    ";
    
    ?>
    输出:
    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 "
    ";
    print "price: {$product1->getPrice()}
    ";
    
    $product2 = new BookProduct("book1", "harry", "harrelson", 4, 30 );
    $product2->setDiscount( 3 ); // 折扣对book无效
    print $product2->getSummaryLine();
    print "
    ";
    print "price: {$product2->getPrice()}
    ";
    
    ?>
    输出:
    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()."
    ";
    $product2 = new BookProduct("book1", "harry", "harrelson", 4, 30 );
    print $product2->getSummaryLine()."
    ";
    ?>
    
    输出:
    cd1 ( bobbleson, bob ): playing time - 50
    book1 ( harrelson, harry ): page count - 30
    

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

  • 相关阅读:
    Host IP地址 is not allowed to connect to this MySQL server
    本地或远程连接mysql:Unable to connect to any of the specified MySQL hosts.
    Table xxx is marked as crashed and should be repaired
    使用Linq 做数据去重
    SharePoint2010与Reporting Services集成方案
    上下左右布局(DIV+CSS)
    .NET 内存管理—CLR的工作
    删除数据库所有用户表
    未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序
    c# 10位数int时间单位换算为datetime
  • 原文地址:https://www.cnblogs.com/jiqing9006/p/5169350.html
Copyright © 2011-2022 走看看