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


Posted in PHP onDecember 02, 2016

本文实例讲述了PHP面向对象程序设计高级特性。分享给大家供大家参考,具体如下:

静态属性

<?php
class StaticExample {
  static public $aNum = 0; // 静态共有属性
  static public function sayHello() { // 静态共有方法
    print "hello";
  }
}
print StaticExample::$aNum;
StaticExample::sayHello();
?>

输出:0    hello

点评:静态属性和方法,可以通过类直接调用。

SELF

<?php
class StaticExample {
  static public $aNum = 0;
  static public function sayHello() { // 这里的static 和 public的顺序可以颠倒
    self::$aNum++;
    print "hello (".self::$aNum.")\n"; // self 指向当前类, $this指向当前对象。
  }
}
StaticExample::sayHello();
StaticExample::sayHello();
StaticExample::sayHello();
?>

输出:

hello (1)
hello (2)
hello (3)

点评:self 指向当前类, this指向当前对象。self可以调用当前类的静态属性和方法。this指向当前对象。self可以调用当前类的静态属性和方法。this可以调用当前类的正常属性和方法。

常量属性

<?php
class ShopProduct {
  const AVAILABLE   = 0; // 只能用大写字母命名常量
  const OUT_OF_STOCK  = 1;
  public $status;
}
print ShopProduct::AVAILABLE;
?>

输出:0

点评:常量只能用大写字母,并且可以通过类直接调用。

接口

<?php
interface Chargeable { // 接口,抽象类是介于基类与接口之间的东西
  public function getPrice();
}
class ShopProduct implements Chargeable {
  // ...
  protected $price;
  // ...
  public function getPrice() {
    return $this->price;
  }
  // ...
}
$product = new ShopProduct();
?>

如果没有实现getPrice方法,将会报错。

Fatal error: Class ShopProduct contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Chargeable::getPrice)

继承类与接口

<?php
class TimedService{ }
interface Bookable{ }
interface Chargeable{ }
class Consultancy extends TimedService implements Bookable, Chargeable { // 继承类与接口
  // ...
}
?>

抽象类

先来看一段代码

<?php
abstract class DomainObject {
}
class User extends DomainObject {
  public static function create() {
    return new User();
  }
}
class Document extends DomainObject {
  public static function create() {
    return new Document();
  }
}
$document = Document::create();
print_r( $document );
?>

输出:

Document Object
(
)

静态方法

<?php
abstract class DomainObject {
  private $group; // 私有属性group
  public function __construct() {
    $this->group = static::getGroup();//static 静态类
  }
  public static function create() {
    return new static();
  }
  static function getGroup() { // 静态方法
    return "default";
  }
}
class User extends DomainObject {
}
class Document extends DomainObject {
  static function getGroup() { // 改变了内容
    return "document";
  }
}
class SpreadSheet extends Document { // 继承之后,group也就与document相同了
}
print_r(User::create());
print_r(SpreadSheet::create());
?>

输出:

User Object
(
  [group:DomainObject:private] => default
)
SpreadSheet Object
(
  [group:DomainObject:private] => document
)

final字段

使类无法被继承,用的不多

<?php
final class Checkout { // 终止类的继承
  // ...
}
class IllegalCheckout extends Checkout {
  // ...
}
$checkout = new Checkout();
?>

输出:

Fatal error: Class IllegalCheckout may not inherit from final class (Checkout)

final方法不能够被重写

<?php
class Checkout {
  final function totalize() {
    // calculate bill
  }
}
class IllegalCheckout extends Checkout {
  function totalize() { // 不能重写final方法
    // change bill calculation
  }
}
$checkout = new Checkout();
?>

输出:

Fatal error: Cannot override final method Checkout::totalize()

析构函数

<?php
class Person {
  protected $name;
  private $age;
  private $id;
  function __construct( $name, $age ) {
    $this->name = $name;
    $this->age = $age;
  }
  function setId( $id ) {
    $this->id = $id;
  }
  function __destruct() { // 析构函数
    if ( ! empty( $this->id ) ) {
      // save Person data
      print "saving person\n";
    }
    if ( empty( $this->id ) ) {
      // save Person data
      print "do nothing\n";
    }
  }
}
$person = new Person( "bob", 44 );
$person->setId( 343 );
$person->setId( '' ); // 最后执行析构函数,使用完之后执行
?>

输出:

do nothing

__clone方法

克隆的时候执行

<?php
class Person {
  private $name;
  private $age;
  private $id;
  function __construct( $name, $age ) {
    $this->name = $name;
    $this->age = $age;
  }
  function setId( $id ) {
    $this->id = $id;
  }
  function __clone() { // 克隆时候执行
    $this->id = 0;
  }
}
$person = new Person( "bob", 44 );
$person->setId( 343 );
$person2 = clone $person;
print_r( $person );
print_r( $person2 );
?>

输出:

Person Object
(
  [name:Person:private] => bob
  [age:Person:private] => 44
  [id:Person:private] => 343
)
Person Object
(
  [name:Person:private] => bob
  [age:Person:private] => 44
  [id:Person:private] => 0
)

再看一个例子

<?php
class Account { // 账户类
  public $balance; // 余额
  function __construct( $balance ) {
    $this->balance = $balance;
  }
}
class Person {
  private $name;
  private $age;
  private $id;
  public $account;
  function __construct( $name, $age, Account $account ) {
    $this->name = $name;
    $this->age = $age;
    $this->account = $account;
  }
  function setId( $id ) {
    $this->id = $id;
  }
  function __clone() {
    $this->id  = 0;
  }
}
$person = new Person( "bob", 44, new Account( 200 ) ); // 以类对象作为参数
$person->setId( 343 );
$person2 = clone $person;
// give $person some money
$person->account->balance += 10;
// $person2 sees the credit too
print $person2->account->balance; // person的属性account也是一个类,他的属性balance的值是210
// output:
// 210
?>

点评:学习还是能够开拓大脑的,今天终于明白为什么有多个箭头的概念了$person->account->balance。这里的account属性是一个对象。

__toString

<?php
class Person {
  function getName() { return "Bob"; }
  function getAge() { return 44; }
  function __toString() {
    $desc = $this->getName()." (age ";
    $desc .= $this->getAge().")";
    return $desc;
  }
}
$person = new Person();
print $person; // 打印时候集中处理
// Bob (age 44)
?>

点评:必须是print或echo时才有效,print_r就输出对象。

Person Object()

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
使用PHP 5.0创建图形的巧妙方法
Oct 12 PHP
php 按指定元素值去除数组元素的实现方法
Nov 04 PHP
浅析php适配器模式(Adapter)
Nov 25 PHP
PHP如何将log信息写入服务器中的log文件
Jul 29 PHP
如何把php5.3版本升级到php5.4或者php5.5
Jul 31 PHP
CodeIgniter配置之database.php用法实例分析
Jan 20 PHP
php中遍历二维数组并以表格的形式输出的方法
Jan 03 PHP
php+resumablejs实现的分块上传 断点续传功能示例
Apr 18 PHP
解决php 处理 form 表单提交多个 name 属性值相同的 input 标签问题
May 11 PHP
one.php 多项目、函数库、类库 统一为一个版本的方法
Aug 24 PHP
PHP配置文件php.ini中打开错误报告的设置方法
Jan 09 PHP
详解thinkphp的Auth类认证
May 28 PHP
PHP面向对象程序设计之命名空间与自动加载类详解
Dec 02 #PHP
PHP面向对象程序设计之类与反射API详解
Dec 02 #PHP
PHP面向对象程序设计之对象生成方法详解
Dec 02 #PHP
PHP面向对象程序设计组合模式与装饰模式详解
Dec 02 #PHP
PHP与jquery实时显示网站在线人数实例详解
Dec 02 #PHP
谈谈php对接芝麻信用踩的坑
Dec 01 #PHP
PHP自定义函数获取汉字首字母的方法
Dec 01 #PHP
You might like
获取URL文件名后缀
2013/10/24 PHP
php ZipArchive压缩函数详解实例
2013/11/06 PHP
ThinkPHP3.1新特性之内容解析输出详解
2014/06/19 PHP
php实现的通用图片处理类
2015/03/24 PHP
php基于PDO连接MSSQL示例DEMO
2016/07/13 PHP
php微信支付之公众号支付功能
2018/05/30 PHP
图片之间的切换
2006/06/26 Javascript
jquery实现商品拖动选择效果代码(自写)
2013/05/28 Javascript
JavaScript操纵窗口的方法小结
2013/06/28 Javascript
jQuery插件实现控制网页元素动态居中显示
2015/03/24 Javascript
jQuery验证插件validation使用指南
2015/04/21 Javascript
jqGrid表格应用之新增与删除数据附源码下载
2015/12/02 Javascript
把JavaScript代码改成ES6语法不完全指南(分享)
2017/09/10 Javascript
解析Json字符串的三种方法日常常用
2018/05/02 Javascript
详解基于vue的服务端渲染框架NUXT
2018/06/20 Javascript
JavaScript实现构造json数组的方法分析
2018/08/17 Javascript
jQuery实现鼠标移入显示蒙版效果
2020/01/11 jQuery
vue element el-transfer增加拖拽功能
2021/01/15 Vue.js
使用python实现正则匹配检索远端FTP目录下的文件
2015/03/25 Python
深入Python解释器理解Python中的字节码
2015/04/01 Python
Python文本统计功能之西游记用字统计操作示例
2018/05/07 Python
Python迭代器与生成器用法实例分析
2018/07/09 Python
Python编程深度学习绘图库之matplotlib
2018/12/28 Python
Python实现生成密码字典的方法示例
2019/09/02 Python
Django 框架模型操作入门教程
2019/11/05 Python
加州风格的游泳和沙滩装品牌:Cupshe
2019/06/10 全球购物
Linux中如何用命令创建目录
2016/12/02 面试题
租车协议书范本
2014/04/22 职场文书
党的群众路线对照检查材料范文
2014/09/24 职场文书
2014年个人委托书范本
2014/10/13 职场文书
2014财务部年度工作总结
2014/12/08 职场文书
劳保用品管理制度范本
2015/08/06 职场文书
幼儿园小班教育随笔
2015/08/14 职场文书
2016年学校综治宣传月活动总结
2016/03/16 职场文书
协议书格式模板
2016/03/24 职场文书
Node.js实现爬取网站图片的示例代码
2022/04/04 NodeJs