首页 > 其他分享 >static 和 self 区别

static 和 self 区别

时间:2024-01-23 20:25:07浏览次数:25  
标签:调用 区别 demo self 实例 static new

1,在 PHP 中,我们可以使用 new static() 结合私有构造函数和一个静态方法来实现单例模式。以下是一个简单的例子

class Singleton {
    // 私有化构造函数,防止外部直接实例化
    private function __construct() {}

    // 静态变量用于存储单一实例
    private static $instance;

    // 使用 new static() 创建并返回单例对象的公共静态方法
    public static function getInstance(): self {
        if (null === static::$instance) {
            static::$instance = new static();
        }
        return static::$instance;
    }

    // 防止克隆
    private function __clone() {}

    // 示例:类中的一个简单方法
    public function doSomething() {
        echo 'Singleton is working.';
    }
}

// 获取 Singleton 类的单例对象
$singleton1 = Singleton::getInstance();
$singleton1->doSomething();

// 再次获取同一个实例
$singleton2 = Singleton::getInstance();
// 因为是单例,所以 $singleton1 和 $singleton2 实际上指向的是同一对象

在这个例子中,getInstance() 方法使用 new static() 来创建并返回类的唯一实例。由于构造函数是私有的,因此无法通过其他方式实例化这个类。这样就确保了在整个应用程序中,无论何时调用 getInstance() 方法,都只会返回同一个实例,从而实现了单例模式。

在 PHP 中,new static() 和 new self() 都是用来创建对象的表达式,但它们之间存在一定的区别: 
1. new self(): - self 关键字指向当前类,无论是在哪个类中调用,它始终指向定义该方法的类。 - 当你在某个类的方法中使用 new self() 时,它会创建该类的一个新实例。
2. new static(): - static 关键字指向的是实际运行时的类,也就是说,在继承层次结构中,如果子类重写了父类的方法并在这个方法内部使用 new static(),那么它将创建
的是当前上下文中的类(即子类)的实例,而不是父类的实例。 - 这种动态绑定的行为使得 new static() 在处理继承关系时更加灵活,特别是在工厂方法、单例模式或者构造函数等需要创建当前类实例的场景下非常有用。
总结一下:
- 如果你希望总是创建当前类的新实例,而不考虑继承和覆盖的情况,使用 new self()。
- 如果你希望根据实际调用类来创建相应类的新实例(即支持多态性),尤其是在面向对象设计中处理继承关系时,应使用 new static()。

 

<?php

class Father {
    // 父类中的 say 方法
    public function say() {
        return 'PHP';
    }

    // 父类中的静态 demo 方法
    public static function demo() {
        $obj = new static();

        // 猜想一下,应该调用哪个 say 方法呢?
        return $obj->say();
    }
}

class Sub extends Father {
    // 子类中的 say 方法
    public function say() {
        return 'ThinkPHP5';
    }
}

// 调用父类的静态 demo 方法
echo Father::demo();  // 返回: PHP

// 调用子类的静态 demo 方法,实际会调用子类重写的 say 方法
echo Sub::demo();  // 返回: ThinkPHP5
在上述代码中,Father::demo() 和 Sub::demo() 都是调用静态方法。
在 demo 方法内部使用了 new static() 创建对象,
由于 static 关键字指向调用该静态方法的类,
因此: - 当调用 Father::demo() 时,new static() 实际创建的是 Father 类的对象,
所以调用的是父类的 say 方法。 - 当调用 Sub::demo() 时,new static() 实际创建的是 Sub 类的对象,所以调用的是子类重写的 say 方法

标签:调用,区别,demo,self,实例,static,new
From: https://www.cnblogs.com/abcdefghi123/p/17983331

相关文章

  • Vue与微信小程序开发时的区别
    Vue与微信小程序开发时的区别一,生命周期vue:跳转页面时,钩子函数都会被重新出发一次,每次进入页面所有得钩子函数都会被触发一次小程序:onload()一个页面只会被加载一次,可以在onLoad中获取打开当前页面所调用的query参数。onShow():每次打开页面都会调用一次。二、数......
  • rocketmq--两种消息模型的区别及demo
    RocketMQ主要支持两种消息模型:集群消费(Clustering)和广播消费(Broadcasting)。集群消费(Clustering):在集群消费模式下,同一个消费者组(ConsumerGroup)中的消费者实例平均分摊消费消息,即一个消息只会被消费者组中的一个消费者消费一次。这种模式适用于负载均衡场景,可以提高消费的并......
  • redo和undo的区别
    edo-->undo-->datafileinsert一条记录时,表跟undo的信息都会放进redo中,在commit或之前,redo的信息会放进硬盘上.故障时,redo便可恢复那些已经commit了的数据.redo->每次操作都先记录到redo日志中,当出现实例故障(像断电),导致数据未能更新到数据文件,则数据库重启时须redo,......
  • 背离、背驰的区别及简单的判断方法
    背离:我们把价格与指标的反向走势,称为背离。可以观察MACD红绿柱长短、快慢线的位置以及形态的变化。在走势中经常是背离了又背离之后,继续上涨,只有小级别的买卖点出现,致使不明背驰的初学者,在大级别上容易操作失误,错过大好时机。背离就是一方犹豫了,一方坚决了,造成力度钝化,表现在结构上......
  • vector 和 list的区别
    vectorlist定义动态数组双向链表增加push_backpush_back,push_front,insert删除pop_backpop_back,pop_front,remove排序头文件sort成员函数sortlist经过排序、插入操作后,迭代器不会失效,仍指向原来的元素#include<iostream>#include<list>......
  • [转]js 正则相关的两个方法match和exec的区别
    原文地址:jsmatch和exec的区别_javascriptmatchexec-CSDN博客一、使用方法不同exec()是正则对象的方法;reg.exec(str);match()是字符串的正则表达方法;str.match(reg);二、返回结果不同w3cSchool是这么说的:match()方法将检索字符串stringObject,以找到一个或多个与regex......
  • [转帖]OS、PFS、DFS 有啥区别?一文搞懂 6 大临床试验终点
    https://oncol.dxy.cn/article/670607 说到肿瘤临床研究,就不得不说临床试验终点(EndPoint),比如大家熟知的OS、PFS、ORR还有DFS、TTP、TTF……不同的终点服务于不同的研究目的。让我们一起来看看常用的临床试验终点都有什么区别以及优缺点。总生存overallsurvival,OS......
  • 详解static关键字在Java中的各种适应场景,这个很重要!
    写在开头静态(static)关键字在Java的众多关键字中举足轻重!也是很多大厂面试官特别喜欢问的面试高频知识点,今天我们就一起学习,梳理,重温一下这个关键吧,之所以用重温修饰是因为在过往的文章中早已提到了static,无论是变量中还是方法中甚至于类中,static都是不可或缺的!我们知道要想调用......
  • pip list 与 conda list 的区别
    condaconda是Anaconda发行版中的包管理工具,主要用于管理包含Python及其相关库的科学计算环境,如NumPy、SciPy、Pandas、Matplotlib等等,它支持创建和管理Python环境,可以方便地在不同的项目中使用不同的库及其版本。condalist命令用于列举当前Python环境下所有使用cond......
  • Git必知必会基础(11):merge和rebase的区别
     本系列汇总,请查看这里:https://www.cnblogs.com/uncleyong/p/10854115.htmlmerge和rebase使用回顾上两篇我们分别演示了merge和rebase的使用,分别详见:https://www.cnblogs.com/uncleyong/p/17967432https://www.cnblogs.com/uncleyong/p/17978213下面我们来总结下二者的差异......