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 相关文章推荐
Apache2 httpd.conf 中文版
Dec 06 PHP
php中随机显示图片的函数代码
Jun 23 PHP
解析php如何将日志写进syslog
Jun 28 PHP
php中sprintf与printf函数用法区别解析
Feb 17 PHP
浅谈discuz密码加密的方式
May 22 PHP
php实现批量压缩图片文件大小的脚本
Jul 04 PHP
ThinkPHP自动填充实现无限级分类的方法
Aug 22 PHP
php打包压缩文件之ZipArchive方法用法分析
Apr 30 PHP
Zend Framework校验器Zend_Validate用法详解
Dec 09 PHP
PHP实现的大文件切割与合并功能示例
Apr 10 PHP
浅谈PHP中的Trait使用方法
Mar 22 PHP
PHP 实现链式操作
Mar 09 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
php.ini-dist 和 php.ini-recommended 的区别介绍(方便开发与安全的朋友)
2012/07/01 PHP
php实现以只读方式打开文件的方法
2015/03/16 PHP
jQuery 处理网页内容的实现代码
2010/02/15 Javascript
ExtJS 设置级联菜单的默认值
2010/06/13 Javascript
读jQuery之十 事件模块概述
2011/06/27 Javascript
利用jquery动画特效和css打造的侧边弹出垂直导航
2014/04/04 Javascript
JS判断客户端是手机还是PC的2个代码
2014/04/12 Javascript
使用jquery实现放大镜效果
2014/09/02 Javascript
js onmousewheel事件多次触发问题解决方法
2014/10/17 Javascript
深入理解JavaScript系列(38):设计模式之职责链模式详解
2015/03/04 Javascript
js中setTimeout()与clearTimeout()用法实例浅析
2015/05/12 Javascript
AngularJS入门教程之控制器详解
2016/07/27 Javascript
Javascript 6里的4个新语法
2016/08/25 Javascript
使用PBFunc在Powerbuilder中支付宝当面付款功能
2016/10/01 Javascript
JSON字符串和JSON对象相互转化实例详解
2017/01/05 Javascript
使用vue.js2.0 + ElementUI开发后台管理系统详细教程(一)
2017/01/21 Javascript
JavaScript实现的文本框placeholder提示文字功能示例
2018/07/25 Javascript
学习LayUI时自研的表单参数校验框架案例分析
2019/07/29 Javascript
浅析Python中的序列化存储的方法
2015/04/28 Python
详解Python各大聊天系统的屏蔽脏话功能原理
2016/12/01 Python
Python中摘要算法MD5,SHA1简介及应用实例代码
2018/01/09 Python
python爬虫获取淘宝天猫商品详细参数
2020/06/23 Python
Python 3.x 安装opencv+opencv_contrib的操作方法
2018/04/02 Python
Python3实现飞机大战游戏
2020/04/24 Python
25个CSS3动画按钮和菜单教程分享
2012/10/03 HTML / CSS
Html5 new XMLHttpRequest()监听附件上传进度
2021/01/14 HTML / CSS
Banggood官网:面向全球客户的综合商城
2017/04/19 全球购物
科颜氏法国官网:Kiehl’s法国
2019/08/20 全球购物
2014全国两会大学生学习心得体会
2014/03/10 职场文书
房屋买卖委托公证书
2014/04/08 职场文书
工厂采购员岗位职责
2014/04/08 职场文书
2014年党员发展工作总结
2014/12/02 职场文书
2015元旦家电促销活动策划方案
2014/12/09 职场文书
2014年财政工作总结
2014/12/10 职场文书
2016年第二十五次全国助残日活动总结
2016/04/01 职场文书
mysql 带多个条件的查询方式
2021/06/05 MySQL