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
點評:這裡進一步私有化了屬性,要想獲取只能通過方法。這樣就確保了安全性。
本文轉自TBHacker部落格園部落格,原文連結:http://www.cnblogs.com/jiqing9006/p/5169350.html,如需轉載請自行聯絡原作者
相關文章
- 物件導向之繼承物件繼承
- 物件導向之_繼承概念物件繼承
- python物件導向(二)繼承:最直接的程式碼複用Python物件繼承
- 21. 物件導向之繼承物件繼承
- 物件導向--繼承物件繼承
- 物件導向:繼承物件繼承
- 物件導向-繼承物件繼承
- 《JavaScript物件導向精要》之五:繼承JavaScript物件繼承
- 物件導向 -- 三大特性之繼承物件繼承
- java學習——物件導向之繼承Java物件繼承
- Golang物件導向_繼承Golang物件繼承
- java物件導向繼承Java物件繼承
- Python - 物件導向程式設計 - 三大特性之繼承Python物件程式設計繼承
- Javascript物件導向與繼承JavaScript物件繼承
- JS物件導向程式設計(四):繼承JS物件程式設計繼承
- java-物件導向程式設計--繼承Java物件程式設計繼承
- Java物件導向03——三大特性之繼承Java物件繼承
- Java中物件導向三大特性之繼承Java物件繼承
- ~~核心程式設計(五):物件導向——多繼承~~程式設計物件繼承
- Javascript實現物件導向繼承JavaScript物件繼承
- 理解Js中物件導向程式設計的繼承JS物件程式設計繼承
- 說清楚javascript物件導向、原型、繼承JavaScript物件原型繼承
- JavaScript物件導向 ~ 原型和繼承(1)JavaScript物件原型繼承
- JavaScript物件導向那些東西-繼承JavaScript物件繼承
- JAVA物件導向高階一:繼承Java物件繼承
- 5-Java物件導向-繼承(下)Java物件繼承
- JavaScript物件導向—繼承的實現JavaScript物件繼承
- PHP 多繼承--程式碼複用新姿勢PHP繼承
- Golang物件導向程式設計之繼承&虛基類【組合&介面】Golang物件程式設計繼承
- Dart語法篇之物件導向繼承和Mixins(六)Dart物件繼承
- JavaScript 複習之 物件的繼承JavaScript物件繼承
- JS物件導向:JS繼承方法總結JS物件繼承
- python物件導向的繼承-組合-02Python物件繼承
- go物件導向思想:封裝、繼承、多肽Go物件封裝繼承
- JAVA物件導向高階:繼承:許可權修飾符(繼承注意事項) 單繼承 Object類 方法重寫Java物件繼承Object
- PHP物件導向之&引用PHP物件
- JS的物件導向(理解物件,原型,原型鏈,繼承,類)JS物件原型繼承
- 物件導向 -- 三大特性之繼承 補充 抽象類 介面類物件繼承抽象
- Kotlin 物件導向程式設計 (OOP) 基礎:類、物件與繼承詳解Kotlin物件程式設計OOP繼承