php Trait基類use trait,本類不use

来源:https://www.cnblogs.com/bushuwei/archive/2023/03/31/17277267.html
-Advertisement-
Play Games

一 回顧trait使用 https://blog.csdn.net/bushuwei/article/details/103514174發現之前本人說明很模糊,自己居然不知道為什麼其實這裡的$c,就是class B再次回顧邏輯 二 分析 self和static區別說的沒毛病 Trait基類use t ...


一 回顧trait使用

https://blog.csdn.net/bushuwei/article/details/103514174
發現之前本人說明很模糊,自己居然不知道為什麼
其實這裡的$c,就是class B
再次回顧邏輯

二 分析

  • self和static區別說的沒毛病
  • Trait基類use trait,本類不use。那麼如果用的new self,則你new 出來的就是 use trait者。如果new static,則因為有繼承關係, 它會判斷類是否存在(父子會被認為都是同一個static,則不再new),那麼,誰先調用instance,那麼new出來的就是誰。‘Trait基類use trait,本類不use’->直接‘其實這裡的$c,就是class B’是錯的。之所以有這個‘幻覺’,是因為單例模式,且static

三 上代碼

  1. self+單例
    trait A{
        private static $instance;
        static function getInstance()
        {
            if(!isset(self::$instance)){
                self::$instance = new self();
            }
            return self::$instance;
        }
    }
    
    class B{
        use A;
        function a()
        {
            var_dump('call at B');
        }
    }
     
    class C extends B{
        function a()
        {
            var_dump('call at c');
            parent::a();
        }
    }
     
    class D extends B{
        use A;
        function a()
        {
            var_dump('call at D');
            parent::a(); 
        }
    }
    $b = B::getInstance();
    $c = C::getInstance();
    $d = D::getInstance();
     
    $c->a();
    echo "<br/>";
    $d->a();
    echo "<br/>";
    

      

    string(9) "call at B"
    string(9) "call at D" string(9) "call at B" 

    註視掉

    // $b = B::getInstance();
    結果不變
  2. static+單例
    trait A{
        private static $instance;
        static function getInstance()
        {
            if(!isset(self::$instance)){
                self::$instance = new static();
            }
            return self::$instance;
        }
    }
    
    class B{
        use A;
        function a()
        {
            var_dump('call at B');
        }
    }
     
    class C extends B{
        function a()
        {
            var_dump('call at c');
            parent::a();
        }
    }
     
    class D extends B{
        use A;
        function a()
        {
            var_dump('call at D');
            parent::a(); 
        }
    }
    $b = B::getInstance();
    $c = C::getInstance();
    $d = D::getInstance();
     
    $c->a();
    echo "<br/>";
    $d->a();
    echo "<br/>";
    
    string(9) "call at B"
    string(9) "call at D" string(9) "call at B" 
    

     

    註視掉

    // $b = B::getInstance();
    string(9) "call at c" string(9) "call at B"
    string(9) "call at D" string(9) "call at B" 

     

  3. 
    

     self+非單例

      

    trait A{
        private static $instance;
        static function getInstance()
        {
            self::$instance = new self();
            return self::$instance;
        }
    }
    
    class B{
        use A;
        function a()
        {
            var_dump('call at B');
        }
    }
     
    class C extends B{
        function a()
        {
            var_dump('call at c');
            parent::a();
        }
    }
     
    class D extends B{
        use A;
        function a()
        {
            var_dump('call at D');
            parent::a(); 
        }
    }
    $b = B::getInstance();
    $c = C::getInstance();
    $d = D::getInstance();
     
    $c->a();
    echo "<br/>";
    $d->a();
    echo "<br/>";
    

      

    string(9) "call at B"
    string(9) "call at D" string(9) "call at B" 
    

      註釋掉

    // $b = B::getInstance();

    結果不變

  4.  static+非單例
    trait A{
        private static $instance;
        static function getInstance()
        {
            // if(!isset(self::$instance)){
            //     self::$instance = new static();
            // }
            // return self::$instance;
            self::$instance = new static();
            return self::$instance;
        }
    }
    
    class B{
        use A;
        function a()
        {
            var_dump('call at B');
        }
    }
     
    class C extends B{
        function a()
        {
            var_dump('call at c');
            parent::a();
        }
    }
     
    class D extends B{
        use A;
        function a()
        {
            var_dump('call at D');
            parent::a(); 
        }
    }
    $b = B::getInstance();
    $c = C::getInstance();
    $d = D::getInstance();
     
    $c->a();
    echo "<br/>";
    $d->a();
    echo "<br/>";
    

      

    string(9) "call at c" string(9) "call at B"
    string(9) "call at D" string(9) "call at B" 
    

      註釋掉
    $b = B::getInstance();
    結果不變

四 結論

  • self的話,就是誰use的,就是誰
  • static的話,誰調用的就是誰
  • 但是static會出現‘誰use就是誰’的幻覺,那是因為單例模式,前面創建了相同類型的單例。




您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 還不會 Quartz?如果你還沒有接觸過Quartz,那麼你可能錯過了一個很棒的任務調度框架!Quartz 提供了一種靈活、可靠的方式來管理和執行定時任務,讓咱們的定時任務更加優雅。 ...
  • 1.標識符 程式中對類、變數等的命名,稱為標識符; 標識符命名規則: 由數字、字母、下劃線、美元符組成,不能以數字開頭; 嚴格區分大小寫; 不能與關鍵字或保留字重名; 標識符的命名最好能反應出其作用。 2.關鍵字 程式中對編譯器有特殊意義的詞,例如class被用來定義類,當程式執行遇到class時, ...
  • 模型之間的關係(Relations Between Models) 上一章介紹了為包含基本欄位的模型創建自定義視圖。然而,在任何真實的業務場景中,我們都需要不止一個模型。此外,模型之間的鏈接是必要的。人們可以很容易地想象一個模型包含客戶,另一個模型則包含用戶列表。你可能需要參考任何現有業務模型上的客 ...
  • ChatGPT是一個基於GPT-3.5架構的自然語言處理工具,它具有文本生成、文本分類、對話生成等多種能力。作為一種強大的自然語言處理工具,ChatGPT可以應用於智能客服、智能問答、內容創作等多個領域。如果您對ChatGPT感興趣,可以通過關註本公眾號瞭解更多信息,並體驗基於ChatGPT的小程式... ...
  • Spring Spring為簡化開發而生,讓程式員只關心核心業務的實現,儘可能的不在關註非業務邏輯代碼(事務控制,安全日誌等)。 1,Spring八大模塊 這八大模塊組成了Spring 1.1 Spring Core模塊 這是Spring框架的最基礎的部分,它提供了依賴註入(DependencyIn ...
  • React Native 備忘清單 適合初學者的綜合 React Native 備忘清單,在開始 React Native 之前需要先掌握 react 庫入門,為開發人員分享快速參考備忘單。 React Native (簡稱RN)是Facebook於2015年4月開源的跨平臺移動應用開發框架,是Fa ...
  • React 備忘清單 IT寶庫整理適合初學者入門的React開發速查備忘清單,為開發人員分享快速參考備忘單。 React是用於構建用戶界面的JavaScript庫,起源於Facebook的內部項目,該公司對市場上所有 JavaScript MVC框架都不滿意,決定自行開發一套,用於架設Instagr ...
  • 一、延遲計算 RDD 代表的是分散式數據形態,因此,RDD 到 RDD 之間的轉換,本質上是數據形態上的轉換(Transformations) 在 RDD 的編程模型中,一共有兩種運算元,Transformations 類運算元和 Actions 類運算元。開發者需要使用 Transformations ...
一周排行
    -Advertisement-
    Play Games
  • 前言 推薦一款基於.NET 8、WPF、Prism.DryIoc、MVVM設計模式、Blazor以及MySQL資料庫構建的企業級工作流系統的WPF客戶端框架-AIStudio.Wpf.AClient 6.0。 項目介紹 框架採用了 Prism 框架來實現 MVVM 模式,不僅簡化了 MVVM 的典型 ...
  • 先看一下效果吧: 我們直接通過改造一下原版的TreeView來實現上面這個效果 我們先創建一個普通的TreeView 代碼很簡單: <TreeView> <TreeViewItem Header="人事部"/> <TreeViewItem Header="技術部"> <TreeViewItem He ...
  • 1. 生成式 AI 簡介 https://imp.i384100.net/LXYmq3 2. Python 語言 https://imp.i384100.net/5gmXXo 3. 統計和 R https://youtu.be/ANMuuq502rE?si=hw9GT6JVzMhRvBbF 4. 數 ...
  • 本文為大家介紹下.NET解壓/壓縮zip文件。雖然解壓縮不是啥核心技術,但壓縮性能以及進度處理還是需要關註下,針對使用較多的zip開源組件驗證,給大家提供個技術選型參考 之前在《.NET WebSocket高併發通信阻塞問題 - 唐宋元明清2188 - 博客園 (cnblogs.com)》講過,團隊 ...
  • 之前寫過兩篇關於Roslyn源生成器生成源代碼的用例,今天使用Roslyn的代碼修複器CodeFixProvider實現一個cs文件頭部註釋的功能, 代碼修複器會同時涉及到CodeFixProvider和DiagnosticAnalyzer, 實現FileHeaderAnalyzer 首先我們知道修 ...
  • 在軟體行業,經常會聽到一句話“文不如表,表不如圖”說明瞭圖形在軟體應用中的重要性。同樣在WPF開發中,為了程式美觀或者業務需要,經常會用到各種個樣的圖形。今天以一些簡單的小例子,簡述WPF開發中幾何圖形(Geometry)相關內容,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 在 C# 中使用 RabbitMQ 通過簡訊發送重置後的密碼到用戶的手機號上,你可以按照以下步驟進行 1.安裝 RabbitMQ 客戶端庫 首先,確保你已經安裝了 RabbitMQ 客戶端庫。你可以通過 NuGet 包管理器來安裝: dotnet add package RabbitMQ.Clien ...
  • 1.下載 Protocol Buffers 編譯器(protoc) 前往 Protocol Buffers GitHub Releases 頁面。在 "Assets" 下找到適合您系統的壓縮文件,通常為 protoc-{version}-win32.zip 或 protoc-{version}-wi ...
  • 簡介 在現代微服務架構中,服務發現(Service Discovery)是一項關鍵功能。它允許微服務動態地找到彼此,而無需依賴硬編碼的地址。以前如果你搜 .NET Service Discovery,大概率會搜到一大堆 Eureka,Consul 等的文章。現在微軟為我們帶來了一個官方的包:Micr ...
  • ZY樹洞 前言 ZY樹洞是一個基於.NET Core開發的簡單的評論系統,主要用於大家分享自己心中的感悟、經驗、心得、想法等。 好了,不賣關子了,這個項目其實是上班無聊的時候寫的,為什麼要寫這個項目呢?因為我單純的想吐槽一下工作中的不滿而已。 項目介紹 項目很簡單,主要功能就是提供一個簡單的評論系統 ...