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 相关文章推荐
解决phpmyadmin 乱码,支持gb2312和utf-8
Nov 20 PHP
php xml-rpc远程调用
Dec 19 PHP
php简单对象与数组的转换函数代码(php多层数组和对象的转换)
May 18 PHP
php设计模式小结
Feb 15 PHP
php读取csv实现csv文件下载功能
Dec 18 PHP
PHP的switch判断语句的“高级”用法详解
Oct 01 PHP
php数组使用规则分析
Feb 27 PHP
PHP文件生成的图片无法使用CDN缓存的解决方法
Jun 20 PHP
PHP使用flock实现文件加锁的方法
Jul 01 PHP
PHP内核探索之解释器的执行过程
Dec 22 PHP
Yii2 批量插入、更新数据实例
Mar 15 PHP
用Laravel轻松处理千万级数据的方法实现
Dec 25 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
ftp类(example.php)
2006/10/09 PHP
最新的php 文件上传模型,支持多文件上传
2009/08/13 PHP
使用PHPMyAdmin修复论坛数据库的图文方法
2012/01/09 PHP
php的memcache类分享(memcache队列)
2014/03/26 PHP
php url路由入门实例
2014/04/23 PHP
php写的AES加密解密类分享
2014/06/20 PHP
php页面函数设置超时限制的方法
2014/12/01 PHP
YII Framework框架教程之国际化实现方法
2016/03/14 PHP
简单解析PHP程序的运行流程
2016/06/23 PHP
浅谈php(codeigniter)安全性注意事项
2017/04/06 PHP
Javascript中的Split使用方法与技巧
2007/03/09 Javascript
Ext.get() 和 Ext.query()组合使用实现最灵活的取元素方式
2011/09/26 Javascript
javascript 通用loading动画效果实例代码
2014/01/14 Javascript
超简单JS二级、多级联动的简单实例
2014/02/18 Javascript
ES6新特性之Object的变化分析
2017/03/31 Javascript
使用store来优化React组件的方法
2017/10/23 Javascript
vue-router 组件复用问题详解
2018/01/22 Javascript
解决vuejs 使用value in list 循环遍历数组出现警告的问题
2018/09/26 Javascript
200行HTML+JavaScript实现年会抽奖程序
2019/01/22 Javascript
bootstrap+spring boot实现面包屑导航功能(前端代码)
2019/10/09 Javascript
jQuery三组基本动画与自定义动画操作实例总结
2020/05/09 jQuery
js实现日历
2020/11/07 Javascript
python列表操作实例
2015/01/14 Python
Python中利用函数装饰器实现备忘功能
2015/03/30 Python
Python实现视频下载功能
2017/03/14 Python
Python 基础教程之str和repr的详解
2017/08/20 Python
Python3 执行系统命令并获取实时回显功能
2019/07/09 Python
python图片二值化提高识别率代码实例
2019/08/24 Python
python实现AdaBoost算法的示例
2020/10/03 Python
15个Pythonic的代码示例(值得收藏)
2020/10/29 Python
Html5应用程序缓存(Cache manifest)
2018/06/04 HTML / CSS
Three Graces London官网:英国奢侈品牌
2021/03/18 全球购物
乡村文明行动实施方案
2014/03/29 职场文书
党员干部反四风对照检查材料思想汇报
2014/09/14 职场文书
乡镇群众路线整改落实情况汇报
2014/10/28 职场文书
python保存图片的四个常用方法
2022/02/28 Python