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
  • 在C#中使用SQL Server實現事務的ACID(原子性、一致性、隔離性、持久性)屬性和使用資料庫鎖(悲觀鎖和樂觀鎖)時,你可以通過ADO.NET的SqlConnection和SqlTransaction類來實現。下麵是一些示例和概念說明。 實現ACID事務 ACID屬性是事務處理的四個基本特征, ...
  • 我們在《SqlSugar開發框架》中,Winform界面開發部分往往也用到了自定義的用戶控制項,對應一些特殊的界面或者常用到的一些局部界面內容,我們可以使用自定義的用戶控制項來提高界面的統一性,同時也增強了使用的便利性。如我們Winform界面中用到的分頁控制項、附件顯示內容、以及一些公司、部門、菜單的下... ...
  • 在本篇教程中,我們學習瞭如何在 Taurus.MVC WebMVC 中進行數據綁定操作。我們還學習瞭如何使用 ${屬性名稱} CMS 語法來綁定頁面上的元素與 Model 中的屬性。通過這些步驟,我們成功實現了一個簡單的數據綁定示例。 ...
  • 是在MVVM中用來傳遞消息的一種方式。它是在MVVMLight框架中提供的一個實現了IMessenger介面的類,可以用來在ViewModel之間、ViewModel和View之間傳遞消息。 Send 接受一個泛型參數,表示要發送的消息內容。 Register 方法用於註冊某個對象接收消息。 pub ...
  • 概述:在WPF中,通過EventHandler可實現基礎和高級的UI更新方式。基礎用法涉及在類中定義事件,併在UI中訂閱以執行更新操作。高級用法藉助Dispatcher類,確保在非UI線程上執行操作後,通過UI線程更新界面。這兩種方法提供了靈活而可靠的UI更新機制。 在WPF(Windows Pre ...
  • 概述:本文介紹了在C#程式開發中如何利用自定義擴展方法測量代碼執行時間。通過使用簡單的Action委托,開發者可以輕鬆獲取代碼塊的執行時間,幫助優化性能、驗證演算法效率以及監控系統性能。這種通用方法提供了一種便捷而有效的方式,有助於提高開發效率和代碼質量。 在軟體開發中,瞭解代碼執行時間是優化程式性能 ...
  • 概述:Cron表達式是一種強大的定時任務調度工具,通過配置不同欄位實現靈活的時間規定。在.NET中,Quartz庫提供了簡便的方式配置Cron表達式,實現精準的定時任務調度。這種靈活性和可擴展性使得開發者能夠根據需求輕鬆地制定和管理定時任務,例如每天備份系統日誌或其他重要操作。 Cron表達式詳解 ...
  • 概述:.NET提供多種定時器,如System.Windows.Forms.Timer適用於UI,System.Web.UI.Timer用於Web,System.Diagnostics.Timer用於性能監控,System.Threading.Timer和System.Timers.Timer用於一般 ...
  • 問題背景 有同事聯繫我說,在生產環境上,訪問不了我負責的common服務,然後我去檢查common服務的health endpoint, 沒問題,然後我問了下異常,timeout導致的System.OperationCanceledException。那大概率是客戶端的問題,會不會是埠耗盡,用ne ...
  • 前言: 在本篇 Taurus.MVC WebMVC 入門開發教程的第四篇文章中, 我們將學習如何實現數據列表的綁定,通過使用 List<Model> 來展示多個數據項。 我們將繼續使用 Taurus.Mvc 命名空間,同時探討如何在視圖中綁定並顯示一個 Model 列表。 步驟1:創建 Model ...