PHP面向对象程序设计中的self、static、parent关键字用法分析


Posted in PHP onAugust 14, 2019

本文实例讲述了PHP面向对象程序设计中的self、static、parent关键字用法.分享给大家供大家参考,具体如下:

看到php里面有关于后期静态绑定的内容,虽然没有完全看懂,但是也收获不少东西。

php官方手册介绍:
http://php.net/manual/zh/language.oop5.late-static-bindings.php

不存在继承的时候

不存在继承的意思就是,就书写一个单独的类来使用的时候。self和static在范围解析操作符 (::) 的使用上,并无区别。

  • 在静态函数中,self和static可以调用静态属性和静态函数(没有实例化类,因此不能调用非静态的属性和函数)。
  • 在非静态函数中,self和static可以调用静态属性和静态函数以及非静态函数

此时,self和static的表现是一样的,可以替换为该类名::的方式调用。

<?php
class Demo{
 public static $static;
 public $Nostatic; 
 public function __construct(){
  self::$static = "static";
  $this->Nostatic = "Nostatic";
 }
 public static function get(){
  return __CLASS__;
 }
 public function show(){
  return "this is function show with ".$this->Nostatic;
 }
 public function test(){
  echo Demo::$static."<br/>"; //使用类名调用静态属性
  echo Demo::get()."<br/>"; //使用类名调用静态属性
  echo Demo::show()."<br/>"; //使用类名调用静态属性
  echo self::$static."<br/>"; //self调用静态属性
  echo self::show()."<br/>"; //self调用非静态方法
  echo self::get()."<br/>"; //self调用静态方法
  echo static::$static."<br/>";//static调用静态属性
  echo static::show()."<br/>";//static调用非静态方法
  echo static::get()."<br/>"; //static调用静态方法
 }
}
$obj = new Demo();
$obj->test();

输出结果:

static
Demo
this is function show with Nostatic
static
this is function show with Nostatic
Demo
static
this is function show with Nostatic
Demo

继承的时候

在继承时,self和static在范围解析操作符 (::) 的使用上有差别。parent也是在继承的时候使用的。

<?php
class A{
 static function getClassName(){
  return "this is class A";
 }
 static function testSelf(){
  echo self::getClassName();
 }
 static function testStatic(){
  echo static::getClassName();
 }
}
class B extends A{
 static function getClassName(){
  return "this is class B";
 }
}
B::testSelf();
echo "<br/>";
B::testStatic();

输出结果:

this is class A
this is class B

self调用的静态方法或属性始终表示其在使用的时候的当前类(A)的方法或属性,可以替换为其类名,但是在类名很长或者有可能变化的情况下,使用self::的方式无疑是更好的选择。

static调用的静态方法或属性会在继承中被其子类重写覆盖,应该替换为对应的子类名(B)。

parent关键字用于调用父类的方法和属性。在静态方法中,可以调用父类的静态方法和属性;在非静态方法中,可以调用父类的方法和属性。

<?php
class A{
 public static $static;
 public $Nostatic; 
 public function __construct(){
  self::$static = "static";
  $this->Nostatic = "Nostatic";
 }
 public static function staticFun(){
  return self::$static;
 }
 public function noStaticFun(){
  return "this is function show with ".$this->Nostatic;
 }
}
class B extends A{
 static function testS(){
  echo parent::staticFun();
 }
 function testNoS(){
  echo parent::noStaticFun();
 }
}
$obj = new B();
$obj->testS();
echo "<br/>";
$obj->testNoS();

输出结果

static
this is function show with Nostatic

在文章的最后,我们分析一个手册上的例子

<?php
class A {
 public static function foo() {
  static::who();
 }
 public static function who() {
  echo __CLASS__."\n";
 }
}
class B extends A {
 public static function test() {
  A::foo();
  parent::foo();
  self::foo();
 }
 public static function who() {
  echo __CLASS__."\n";
 }
}
class C extends B {
 public static function who() {
  echo __CLASS__."\n";
 }
}
C::test();
?>

输出结果

A
C
C

我们单独拿出test方法进行分析:

public static function test() {
  A::foo();
  parent::foo();
  self::foo();
}

1)A::foo();这个语句是可以在任何地方执行的,它表示使用A去调用静态方法foo()得到'A'。

2)parent::foo();C的parent是B,B的parent是A,回溯找到了A的foo方法;static::who();语句中的static::调用的方法会被子类覆盖,所以优先调用C的who()方法,如果C的who方法不存在会调用B的who方法,如果B的who方法不存在会调用A的who方法。所以,输出结果是'C'。[注1]

3)self::foo();这个self::是在B中使用的,所以self::等价于B::,但是B没有实现foo方法,B又继承自A,所以我们实际上调用了A::foo()这个方法。foo方法使用了static::who()语句,导致我们又调用了C的who函数。[注2]

注1:补充解释上面的(2)

<?php
class A {
 public static function foo() {
  static::who();
 }
 public static function who() {
  echo __CLASS__."\n";
 }
}
class B extends A {
 public static function test() {
  A::foo();
  parent::foo();
  self::foo();
 }
 public static function who() {
  echo __CLASS__."\n";
 }
}
class C extends B {
 // public static function who() {
 //  echo __CLASS__."\n";
 // }
}
C::test();
?>

输出结果:

A B B

注2:补充解释上面的(3)

<?php
class A {
 public static function foo() {
  static::who();
 }
 public static function who() {
  echo __CLASS__."\n";
 }
}
class B extends A {
 public static function test() {
  A::foo();
  parent::foo();
  self::foo();
 }
 public static function foo() {
  echo "fooB"."\n";
 }
 public static function who() {
  echo __CLASS__."\n";
 }
}
class C extends B {
 public static function foo() {
  echo "fooC"."\n";
 }
 public static function who() {
  echo __CLASS__."\n";
 }
}
C::test();
?>

输出结果:

A C fooB

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

PHP 相关文章推荐
php 自写函数代码 获取关键字 去超链接
Feb 08 PHP
PHP的加密方式及原理
Jun 14 PHP
PHP中几种常见的超时处理全面总结
Sep 11 PHP
PHP生成RSS文件类实例
Dec 05 PHP
浅析PHP文件下载原理
Dec 25 PHP
PHP Hash算法:Times33算法代码实例
May 13 PHP
php封装的smartyBC类完整实例
Oct 19 PHP
ThinkPHP框架表单验证操作方法
Jul 19 PHP
Laravel 加载第三方类库的方法
Apr 20 PHP
JS操作XML中DTD介绍及使用方法分析
Jul 04 PHP
php操作redis常见方法示例【key与value操作】
Apr 14 PHP
PHP中strval()函数实例用法
Jun 07 PHP
PHP命名空间定义与用法实例分析
Aug 14 #PHP
php中的依赖注入实例详解
Aug 14 #PHP
php基于 swoole 实现的异步处理任务功能示例
Aug 13 #PHP
thinkphp3.2框架中where条件查询用法总结
Aug 13 #PHP
thinkphp5框架结合mysql实现微信登录和自定义分享链接与图文功能示例
Aug 13 #PHP
php实现的表单验证类完整示例
Aug 13 #PHP
thinkphp3.2同时连接两个数据库的简单方法
Aug 13 #PHP
You might like
肝肠寸断了解下!盘点史上最伤心的十大动漫
2020/03/04 日漫
yii框架表单模型使用及以数组形式提交表单数据示例
2014/04/30 PHP
使用PHP如何实现高效安全的ftp服务器(二)
2015/12/30 PHP
PHP实现Markdown文章上传到七牛图床的实例内容
2020/02/11 PHP
js 异步处理进度条
2010/04/01 Javascript
javascript中使用css需要注意的地方小结
2010/09/01 Javascript
JavaScript编程中布尔对象的基本使用
2015/10/25 Javascript
D3.js实现折线图的方法详解
2016/09/21 Javascript
JS点击某个图标或按钮弹出文件选择框的实现代码
2016/09/27 Javascript
jQuery右下角悬浮广告实例
2016/10/17 Javascript
微信小程序 倒计时组件实现代码
2016/10/24 Javascript
JavaScript常用正则函数用法示例
2017/01/23 Javascript
高效的jQuery代码编写技巧总结
2017/02/22 Javascript
vue.js利用Object.defineProperty实现双向绑定
2017/03/09 Javascript
基于JavaScript实现的快速排序算法分析
2017/04/14 Javascript
Vue单文件组件的如何使用方式介绍
2017/07/28 Javascript
vuex实现登录状态的存储,未登录状态不允许浏览的方法
2018/03/09 Javascript
浅谈AngularJS中$http服务的简单用法
2018/05/15 Javascript
vue路由跳转传参数的方法
2019/05/06 Javascript
javascript获取元素的计算样式
2019/05/24 Javascript
[08:08]DOTA2-DPC中国联赛2月28日Recap集锦
2021/03/11 DOTA
Python发送email的3种方法
2015/04/28 Python
Python实现二叉堆
2016/02/03 Python
python的turtle库使用详解
2019/05/10 Python
Python写捕鱼达人的游戏实现
2020/03/31 Python
html5标记文字_动力节点Java学院整理
2017/07/11 HTML / CSS
英国打印机墨水和碳粉商店:Printerinks
2017/06/30 全球购物
LN-CC日本:高端男装和女装的奢侈时尚目的地
2019/09/01 全球购物
西安众合通用.net笔试题
2013/03/18 面试题
保送生自荐信范文
2013/10/06 职场文书
建筑工地门卫岗位职责
2014/04/30 职场文书
2014年保管员工作总结
2014/11/18 职场文书
跑吧孩子观后感
2015/06/10 职场文书
7个你应该知道的JS原生错误类型
2021/04/29 Javascript
Python3.8官网文档之类的基础语法阅读
2021/09/04 Python
Java时间工具类Date的常用处理方法
2022/05/25 Java/Android