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程序设计有所帮助。

(0)

相关推荐

  • PHP面向对象程序设计之接口用法

    接口是PHP面向对象程序设计中非常重要的一个概念.本文以实例形式较为详细的讲述了PHP接口的用法.具体如下: 接口:interface 在PHP中,我们可以规定,一个对象应该具有哪些公共的外部操作,即可使用interface来规定. 公共的方法就是接口.用于规定一个对象应该用于哪些公共的操作方法(接口),这个也叫接口(公共操作方法的集合) 即:接口(interface结构,公共方法集合) 公共方法(接口方法) 定义:用于限定某个对象所必须拥有的公共操作方法的一种结构,称之为接口(interfac

  • php学习笔记 面向对象中[接口]与[多态性]的应用

    复制代码 代码如下: <?php /* 接口技术 * * 接口是一种特殊的抽象类,抽象类又是一种特殊的类 * * 接口和抽象类是一样的作用 * * 因为在PHP是单继承的,如果使用抽象类,子类实现抽象类就不能再去继承其他的类了 * * 如果既想实现一些规范,又想继承其他类.就要使用接口. * * 接口和抽象类的对比 * * 1.作用相同,都不能创建对象,都需要子类去实现 * * 2.接口的声明和抽象类不一样 * * 3.接口被实现方式不一样 * * 4.接口中的所有方法必须是抽象方法,只能声明抽

  • PHP入门教程之面向对象的特性分析(继承,多态,接口,抽象类,抽象方法等)

    本文实例讲述了PHP面向对象的特性.分享给大家供大家参考,具体如下: Demo1.php <?php header('Content-Type:text/html; charset=utf-8;'); //创建一个电脑类 class Computer { //什么叫做类内,就是创建类的花括号内的范围叫做类内,其他地方则类外. //public 是对字段的公有化,这个字段类外即可访问,赋值和取值 public $_name = '联想'; } $computer = new Computer();

  • php面向对象全攻略 (十四) php5接口技术

    20.PHP5 接口技术 PHP 与大多数面向对象编程语言一样,不支持多重继承.也就是说每个类只能继承一个父 类.为了解决这个问题,PHP 引入了接口,接口的思想是指定了一个实现了该接口的类必须 实现的一系列方法.接口是一种特殊的抽象类,抽象类又是一种特殊的类,所以接口也是一 种特殊的类,为什么说接口是一种特殊的抽象类呢?如果一个抽象类里面的所有的方法都是 抽象方法,那么我们就换一种声明方法使用"接口":也就是说接口里面所有的方法必须都是 声明为抽象方法,另外接口里面不能声明变量,而且

  • PHP接口继承及接口多继承原理与实现方法详解

    本文实例讲述了PHP接口继承及接口多继承原理与实现方法.分享给大家供大家参考,具体如下: 在PHP的接口中,接口可以继承接口.虽然PHP类只能继承一个父类(单继承),但是接口和类不同,接口可以实现多继承,可以继承一个或者多个接口.当然接口的继承也是使用extends关键字,要多个继承的话只要用逗号把继承的接口隔开即可. 需要注意的是当你接口继承其它接口时候,直接继承父接口的静态常量属性和抽象方法,所以类实现接口时必须实现所有相关的抽象方法. 现在你对PHP接口的继承有所了解了吧,下面的例子可供参

  • PHP 面向对象程序设计(oop)学习笔记(一) - 抽象类、对象接口、instanceof 和契约式编程

    1.PHP中的抽象类 PHP 5 支持抽象类和抽象方法.定义为抽象的类不能被实例化.任何一个类,如果它里面至少有一个方法是被声明为抽象的,那么这个类就必须被声明为抽象的.被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现.在类的声明中使用 abstract 修饰符可以将某个类声明为抽象的. 可以这样理解,抽象类作为一个基类,它把特定的细节留给继承者来实现.通过抽象概念,可以在开发项目中创建扩展性很好的架构. 复制代码 代码如下: abstract class Abstrac

  • PHP面向对象程序设计高级特性详解(接口,继承,抽象类,析构,克隆等)

    本文实例讲述了PHP面向对象程序设计高级特性.分享给大家供大家参考,具体如下: 静态属性 <?php class StaticExample { static public $aNum = 0; // 静态共有属性 static public function sayHello() { // 静态共有方法 print "hello"; } } print StaticExample::$aNum; StaticExample::sayHello(); ?> 输出:0   

  • php面向对象全攻略 (七) 继承性

    11.类的继承 继承作为面向对象的三个重要特性的一个方面,在面向对象的领域有着极其重要的作用, 好像没听说哪个面向对象的语言不支持继承.继承是PHP5 面向对象程序设计的重要特性之 一,它是指建立一个新的派生类,从一个或多个先前定义的类中继承数据和函数,而且可以 重新定义或加进新数据和函数,从而建立了类的层次或等级.说的简单点就是,继承性是子 类自动共享父类的数据结构和方法的机制,这是类之间的一种关系.在定义和实现一个类的 时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的

  • PHP面向对象程序设计OOP继承用法入门示例

    本文实例讲述了PHP面向对象程序设计OOP继承用法.分享给大家供大家参考,具体如下: <?php class Person { var $name;//protected var $sex; var $age; function __construct($name = "", $sex = "男", $age = 22) { $this->name = $name; $this->sex = $sex; $this->age = $age;

  • PHP面向对象的进阶学习(抽像类、接口、final、类常量)

    一.抽像类(abstract) 在我们实际开发过程中,有些类并不需要被实例化,如前面学习到的一些父类,主要是让子类来继承,这样可以提高代码复用性 语法结构: 复制代码 代码如下: abstract class 类名{ 属性 $name; 方法(){} //方法也可以为abstract 修饰符 function 方法名(){} } 例: 复制代码 代码如下: abstract class animal{ public $name; public $age; //抽象方法不能有方法体,主要是为了让子

  • PHP面向对象三大特点学习(充分理解抽象、封装、继承、多态)

    面象对向的三大特点:封装性.继承性.多态性 首先简单理解一下抽象:我们在前面定义一个类的时候,实际上就是把一类事物共有的属性和行为提取出来,形成一个物理模型(模版),这种研究问题的方法称为抽象一.封装性 封装就是把抽取出来的数据和对数据的操作封装在一起,数据被保护在内部,程序的其他部分只有被授权的操作(方法)才能对数据进行操作. php提供了三种访问控制修饰符 public 表示全局,本类内部,类外部,子类都可以访问 protected 表示受保护的,只有本类或子类可以访问 private 表示

随机推荐