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 skymvc 一款轻量、简单的php
Jun 28 PHP
深入掌握include_once与require_once的区别
Jun 17 PHP
PHP变量内存分配问题记录整理
Nov 27 PHP
PHP中调用SVN命令更新网站方法
Jan 07 PHP
php上传大文件失败的原因及应对策略
Oct 20 PHP
PHP使用pear实现mail发送功能 windows环境下配置pear
Apr 15 PHP
PHP两种实现无级递归分类的方法
Mar 02 PHP
PHP解耦的三重境界(浅谈服务容器)
Mar 13 PHP
PHP迭代器和迭代的实现与使用方法分析
Apr 19 PHP
php连接mysql数据库最简单的实现方法
Sep 24 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
Nov 23 PHP
php使用redis的有序集合zset实现延迟队列应用示例
Feb 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
多文件上传的例子
2006/10/09 PHP
PHP数组操作汇总 php数组的使用技巧
2011/07/17 PHP
PHP include任意文件或URL介绍
2014/04/29 PHP
Laravel中使用自己编写类库的3种方法
2015/02/10 PHP
解决Yii2邮件发送结果返回成功,但接收不到邮件的问题
2017/05/23 PHP
解决windows上php xdebug 无法调试的问题
2020/02/19 PHP
js常见表单应用技巧
2008/01/09 Javascript
JS模拟自动点击的简单实例
2013/08/08 Javascript
js实现的标题栏新消息闪烁提示效果
2014/06/06 Javascript
用js传递value默认值的示例代码
2014/09/11 Javascript
jquery实现用户信息修改验证输入方法汇总
2015/07/18 Javascript
Boostrap入门准备之border box
2016/05/09 Javascript
详解javascript中对数据格式化的思考
2017/01/23 Javascript
jQuery遮罩层实例讲解
2017/05/11 jQuery
Node.js服务器开启Gzip压缩教程
2017/08/11 Javascript
vue-cli 自定义指令directive 添加验证滑块示例
2017/10/19 Javascript
vue中手机号,邮箱正则验证以及60s发送验证码的实例
2018/03/16 Javascript
关于RxJS Subject的学习笔记
2018/12/05 Javascript
JS Math对象与Math方法实例小结
2019/07/05 Javascript
Vue环境搭建+VSCode+Win10的详细教程
2020/08/19 Javascript
Python使用scrapy采集数据过程中放回下载过大页面的方法
2015/04/08 Python
Python开发之身份证验证库id_validator验证身份证号合法性及根据身份证号返回住址年龄等信息
2020/03/20 Python
深入浅析css3 border-image边框图像详解
2015/11/24 HTML / CSS
wordpress添加Html5的表单验证required方法小结
2020/08/18 HTML / CSS
阿提哈德航空官方网站:Etihad Airways
2017/01/06 全球购物
智能室内花园:Click & Grow
2021/01/29 全球购物
Java里面如何创建一个内部类的实例
2015/01/19 面试题
《值日生》教学反思
2014/02/17 职场文书
求职信格式要求
2014/05/23 职场文书
525心理活动总结
2014/07/04 职场文书
小学校园广播稿集锦
2014/10/04 职场文书
2014年个人工作总结报告
2014/11/27 职场文书
关于空气污染危害的感想
2015/08/11 职场文书
养成教育工作总结
2015/08/13 职场文书
导游词范文之颐和园/重庆/云台山
2019/09/10 职场文书
pytorch 6 batch_train 批训练操作
2021/05/28 Python