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数据库连接
Oct 09 PHP
杏林同学录(一)
Oct 09 PHP
用php获取远程图片并把它保存到本地的代码
Apr 07 PHP
php 文件上传系统手记
Oct 26 PHP
PHP查询网站的PR值
Oct 30 PHP
php实例分享之通过递归实现删除目录下的所有文件详解
May 15 PHP
phpcms手机内容页面添加上一篇和下一篇
Jun 05 PHP
利用“多说”制作留言板、评论系统
Jul 14 PHP
Smarty环境配置与使用入门教程
May 11 PHP
详解PHP数据压缩、加解密(pack, unpack)
Dec 17 PHP
老生常谈php 正则中的i,m,s,x,e分别表示什么
Mar 02 PHP
利用Laravel事件系统如何实现登录日志的记录详解
May 20 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
怎样在UNIX系统下安装MySQL
2006/10/09 PHP
2014年10个最佳的PHP图像操作库
2014/07/14 PHP
详解php比较操作符的安全问题
2015/12/03 PHP
php 删除指定文件夹的实例讲解
2017/07/25 PHP
php实现的顺序线性表示例
2019/05/04 PHP
JScript的条件编译
2007/05/29 Javascript
jQuery.query.js 取参数的两点问题分析
2012/08/06 Javascript
javascript结合Canvas 实现简易的圆形时钟
2015/03/11 Javascript
jQuery实现漂亮实用的商品图片tips提示框效果(无图片箭头+阴影)
2016/04/16 Javascript
Bootstrap进度条组件知识详解
2016/05/01 Javascript
使用AJAX实现Web页面进度条的实例分享
2016/05/06 Javascript
JQuery遍历元素的后代和同胞实现方法
2016/09/18 Javascript
详解nodeJS中读写文件方法的区别
2017/03/06 NodeJs
优雅的elementUI table单元格可编辑实现方法详解
2018/12/23 Javascript
小程序新版订阅消息模板消息
2019/12/31 Javascript
[49:41]NB vs NAVI Supermajor小组赛A组 BO3 第一场 6.2
2018/06/03 DOTA
在Python的gevent框架下执行异步的Solr查询的教程
2015/04/16 Python
Django objects.all()、objects.get()与objects.filter()之间的区别介绍
2017/06/12 Python
python虚拟环境virtualenv的安装与使用
2017/09/21 Python
Python实现提取XML内容并保存到Excel中的方法
2018/09/01 Python
Python 普通最小二乘法(OLS)进行多项式拟合的方法
2018/12/29 Python
对Pytorch中Tensor的各种池化操作解析
2020/01/03 Python
GOLFINO英国官网:高尔夫服装
2020/04/11 全球购物
北大自主招生自荐信
2013/10/19 职场文书
研究生考核个人自我鉴定
2014/03/27 职场文书
2015试用期转正工作总结
2014/12/12 职场文书
优秀少先队员事迹材料
2014/12/24 职场文书
初中英语教师个人工作总结
2015/02/09 职场文书
辞职信怎么写
2015/02/27 职场文书
解放思想大讨论活动总结
2015/05/09 职场文书
2015年客房服务员工作总结
2015/05/15 职场文书
2015年酒店销售部工作总结
2015/07/24 职场文书
JavaScript 语句之常用 for 循环详解
2021/03/29 Javascript
Java中API的使用方法详情
2022/04/06 Java/Android
从结婚开始的恋爱故事。小说《我的美好婚事》TV动画化决定
2022/04/07 日漫
搭建Yolov5服务器
2022/04/30 Servers