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基础知识:类与对象(5) static
Dec 13 PHP
解析CI即CodeIgniter框架在Nginx下的重写规则
Jun 03 PHP
PHP页面间参数传递的四种方法详解
Jun 09 PHP
php过滤所有恶意字符(批量过滤post,get敏感数据)
Mar 18 PHP
PHP的Socket网络编程入门指引
Aug 11 PHP
PHP上传Excel文件导入数据到MySQL数据库示例
Oct 25 PHP
PHP之十六个魔术方法详细介绍
Nov 01 PHP
PHP递归遍历指定文件夹内的文件实现方法
Nov 15 PHP
PHP使用curl函数发送Post请求的注意事项
Nov 26 PHP
PHP7数组的底层实现示例
Aug 25 PHP
Laravel 微信小程序后端搭建步骤详解
Nov 26 PHP
Laravel5.3+框架定义API路径取消CSRF保护方法详解
Apr 06 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
《逃离塔科夫》——“萌新劝退,老手自嗨”的硬核FPS游戏
2020/04/03 其他游戏
简单的php文件上传(实例)
2013/10/27 PHP
JavaScript判断两种格式的输入日期的正确性的代码
2007/03/25 Javascript
JavaScript获取table中某一列的值的方法
2014/05/06 Javascript
JavaScript实现找出数组中最长的连续数字序列
2014/09/03 Javascript
基于jQuery Bar Indicator 插件实现进度条展示效果
2015/09/30 Javascript
bootstrapfileinput实现文件自动上传
2016/11/08 Javascript
angular十大常见问题
2017/03/07 Javascript
angular.js中解决跨域问题的三种方式
2017/07/12 Javascript
详解win7 cmd执行vue不是内部命令的解决方法
2017/07/27 Javascript
Node.js使用Angular简单示例
2018/05/11 Javascript
vue.js+element-ui动态配置菜单的实例
2018/09/07 Javascript
微信小程序如何获取用户收货地址
2018/11/27 Javascript
javascript中call()、apply()的区别
2019/03/21 Javascript
vue祖孙组件之间的数据传递案例
2020/12/07 Vue.js
python二叉树遍历的实现方法
2013/11/21 Python
浅析Python的Django框架中的Memcached
2015/07/23 Python
Python初学时购物车程序练习实例(推荐)
2017/08/08 Python
Python使用遗传算法解决最大流问题
2018/01/29 Python
Python实现删除时保留特定文件夹和文件的示例
2018/04/27 Python
python对html过滤处理的方法
2018/10/21 Python
Python获取Redis所有Key以及内容的方法
2019/02/19 Python
python基于gevent实现并发下载器代码实例
2019/11/01 Python
Python抓新型冠状病毒肺炎疫情数据并绘制全国疫情分布的代码实例
2020/02/05 Python
Python rabbitMQ如何实现生产消费者模式
2020/08/24 Python
python压包的概念及实例详解
2021/02/17 Python
利用CSS3的定位页面元素
2009/08/29 HTML / CSS
基于html5实现的图片墙效果
2014/10/16 HTML / CSS
印尼穆斯林时尚购物网站:Hijabenka
2016/12/10 全球购物
VICHY薇姿俄罗斯官方网上商店:法国护肤品牌,火山温泉水
2019/11/22 全球购物
地质工程专业毕业生求职信
2014/08/08 职场文书
食品安全演讲稿
2014/09/01 职场文书
2015年大学团支部工作总结
2015/05/13 职场文书
高一军训口号
2015/12/25 职场文书
Nginx+Windows搭建域名访问环境的操作方法
2022/03/17 Servers
教你nginx跳转配置的四种方式
2022/07/07 Servers