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 mail 通过Windows的SMTP发送邮件失败的解决方案
May 27 PHP
php中批量替换文件名的实现代码
Jul 20 PHP
url decode problem 解决方法
Dec 26 PHP
基于PHP magic_quotes_gpc的使用方法详解
Jun 24 PHP
PHP垃圾回收机制引用计数器概念分析
Jun 24 PHP
用php守护另一个php进程的例子
Feb 13 PHP
Yii2――使用数据库操作汇总(增删查改、事务)
Dec 19 PHP
PHP实现上传多文件示例代码
Feb 20 PHP
Laravel如何友好的修改.env配置文件详解
Jun 07 PHP
php实现微信支付之现金红包
May 30 PHP
laravel 5.3 单用户登录简单实现方法
Oct 14 PHP
tp5 实现列表数据根据状态排序
Oct 18 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
星际中的相关伤害
2020/03/04 星际争霸
php构造函数实例讲解
2013/11/13 PHP
微信公众平台开发教程③ PHP实现微信公众号支付功能图文详解
2019/04/10 PHP
js innerHTML 的一些问题的解决方法
2008/06/22 Javascript
XMLHTTPRequest的属性和方法简介
2010/11/23 Javascript
仿猪八戒网左下角的文字滚动效果
2011/10/28 Javascript
js正则表达exec与match的区别说明
2014/01/29 Javascript
jquery淡化版banner异步图片文字效果切换图片特效
2014/04/08 Javascript
js实现的捐赠管理完整实例
2015/01/20 Javascript
JS实现的通用表单验证插件完整实例
2015/08/20 Javascript
详解JavaScript基于面向对象之继承实例
2015/12/16 Javascript
在web中js实现类似excel的表格控件
2016/09/01 Javascript
BootStrap中Table分页插件使用详解
2016/10/09 Javascript
mongoose中利用populate处理嵌套的方法
2017/05/26 Javascript
two.js之实现动画效果示例
2017/11/06 Javascript
Vue 将后台传过来的带html字段的字符串转换为 HTML
2018/03/29 Javascript
微信小程序实现两边小中间大的轮播效果的示例代码
2018/12/07 Javascript
[03:26]《DAC最前线》之EG经理自述DOTA2经历
2015/02/02 DOTA
Python中用于返回绝对值的abs()方法
2015/05/14 Python
Python 基础之字符串string详解及实例
2017/04/01 Python
python爬虫入门教程--正则表达式完全指南(五)
2017/05/25 Python
Python中with及contextlib的用法详解
2017/06/08 Python
Python错误处理操作示例
2018/07/18 Python
Python实现FM算法解析
2019/06/18 Python
python实现在cmd窗口显示彩色文字
2019/06/24 Python
python pytest进阶之xunit fixture详解
2019/06/27 Python
Python内置异常类型全面汇总
2020/05/28 Python
浅析HTML5页面元素及属性
2021/01/20 HTML / CSS
感恩节活动方案
2014/01/27 职场文书
2014年重阳节敬老活动方案
2014/09/16 职场文书
股权转让协议范本
2014/12/07 职场文书
2014年办公室人员工作总结
2014/12/09 职场文书
2015年党员创先争优承诺书
2015/01/22 职场文书
银行自荐信范文
2015/03/25 职场文书
实习报告范文
2019/07/30 职场文书
SpringBoot使用ip2region获取地理位置信息的方法
2022/06/21 Java/Android