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

yipeiwu_com7年前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过滤危险html代码的函数

#用户发布的html,过滤危险代码  function uh($str)  {  $farr = array(  "...

php class类的用法详细总结

一:结构和调用(实例化): class className{} ,调用:$obj = new className();当类有构造函数时,还应传入参数。如$obj = new classN...

PHP 高级课程笔记 面向对象

例一: 复制代码 代码如下:<?php // 类的定义 class User { // 属性,注意public、private、protected的作用范围 public $nam...

php session的应用详细介绍

php session的应用详细介绍

php session高级应用 session在web技术中非常重要,由于网页是一种无状态的连接程序,因此无法得知用户的浏览状态。通过session则可以记录用户的有关信息,以供用户再次...

PHP 图像处理与SESSION制作超简单验证码的方法示例

本文实例讲述了PHP 图像处理与SESSION制作超简单验证码的方法。分享给大家供大家参考,具体如下: 验证码的实现 首先我们要清楚,无论是做什么东西,在做之前一定要有思路,譬如这个验证...