成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

PHP繼承竟然也需要顯性基因?

原創
開發 開發工具 后端
雖然寫php已經是將近8年的功底了,但因為工作關系,經常需要涉及前后端的各種代碼,容易精分,也總會記岔。最近發生的一件事情讓我覺得,或許寫下來能夠讓自己清醒一點。

網上經常流傳出php是語言鄙視鏈***端的那個,曾經大學學java,畢設用java,剛出來培訓用java的我,在最初工作的2、3年時對php的面向對象也是頗有意見,總覺得【不倫不類】,更別提對js的看法了。但是這些觀點都在經歷越來越多的項目之后逐漸的淡化,甚至改觀。這里面包含著自己對項目、技術有著更多的理解,同時,在這些年里,Web環境、技術也在不停的更新。不過今天不是來聊這些東西的,對于以上的問題,我的觀點可以總結為:技術是工具、手段,不合適就升級、換,就這么簡單。

[[167999]]

話歸原題。雖然寫php已經是將近8年的功底了,但因為工作關系,經常需要涉及前后端的各種代碼,容易精分,也總會記岔。最近發生的一件事情讓我覺得,或許寫下來能夠讓自己清醒一點。 

在某一年寫某個模塊時用到了static成員,在實現子類的過程中發現他們也共享著父類這個成員的值,具體來說就是我在某個子類A中改變了那個成員值,在另外一個子類B使用的時候結果意外的得到了A覆蓋后的值。當時以為,原來static成員是在從聲明的地方開始的整個類別樹中共享的。后來一直隱約記得這個結論,在平常的代碼里面更謹慎的使用static成員,除非確認寫的類是個獨立的工具類,不然不輕易使用static。 

直到有一天我的老大跟我商量升級我之前寫的一個BaseModel,他無意中問我:好像你不喜歡用static成員?我說沒有啊,因為考慮到BaseModel會被經常繼承成各種Model,如果我在這里用了static的話,將來容易踩坑。他表示不理解,然后過來與我辯論。我很義正言辭的說明了因為static成員會被共享,如果要調用兩個不同的子類的時候,那個static成員的變量的值就會像一個全局變量一樣不可控。他不同意。于是本著科學的精神,我們寫下了一個簡短的代碼來驗證: 

  1. class A { 
  2.   protected static $var1 = null; 
  3.   public static function test(){ 
  4.      echo get_called_class().' '.static::$var1.'<br/>'
  5.   } 
  6. class B extends A { 
  7.   protected static $var1 = 'b';   
  8. class C extends A { 
  9.   protected static $var1 = 'c';   
  10. B::test(); 
  11. C::test(); 

很顯然,這次是我敗了。我期待的結果是c c,不過其實是b c。那么這樣看起來其實子類的static成員是只在子類這一層共享的。但是我總覺得不對勁,明明在寫BaseModel的時候我已經又栽過跟頭了,為什么這個驗證出來并不支持我那個時候遇到的問題呢?于是我發現我記岔了。年輕多好。后來想起來,原來我這里不用static的原因僅僅是因為設計需要。

我以為我錯了。直到前幾天又寫了幾個父子類(不是BaseModel了),大膽的用上了static成員,結果是轟轟烈烈的在自測中又摔了一跤。怎么回事!然后我仔細留意了一下自己這次的用法,將上面的例子改了一下運行:

  1. class A { 
  2.   protected static $var1 = null; 
  3.   protected static $var2 = null; 
  4.   public static function test(){ 
  5.      if(!static::$var2){ 
  6.           static::$var2 = static::$var1
  7.      } 
  8.      echo get_called_class().' '.static::$var2.'<br/>'
  9.   } 
  10. class B extends A { 
  11.   protected static $var1 = 'b';   
  12. class C extends A { 
  13.   protected static $var1 = 'c';   
  14. B::test(); 
  15. C::test(); 

結果是

  1. B b 
  2. C b 

如果說上次的結論是對了,那么這次又怎么解釋?這里明明就是表示$var2是A,B,C共享的。$var1和$var2的差別這樣看起來僅僅是有聲明和沒聲明的區別。于是我又改成這樣:

  1. class A { 
  2.   protected static $var1 = null; 
  3.   protected static $var2 = null; 
  4.   public static function test(){ 
  5.      if(!static::$var2){ 
  6.           static::$var2 = static::$var1
  7.      } 
  8.      echo get_called_class().' '.static::$var2.'<br/>'
  9.   } 
  10. class B extends A { 
  11.   protected static $var1 = 'b'
  12.   protected static $var2 = null; 
  13. class C extends A { 
  14.   protected static $var1 = 'c'
  15.   protected static $var2 = null; 
  16. B::test(); 
  17. C::test(); 

結果是

  1. B b 
  2. C c

我當時內心是崩潰的。于是我上了Stack Overflow,發現栽坑的不止我一個。

只有顯式的聲明出來的static成員才會被視為是只從屬于子類的。

只有顯式的聲明出來的static成員才會被視為是只從屬于子類的。

只有顯式的聲明出來的static成員才會被視為是只從屬于子類的。

重要的事情說三遍!不過如果子類很多的話, 動態決定值的成員 每個都這樣去聲明,就從寫代碼這件事上失去了用static的意義。一個更好的方法是,把$var2變成一個數組,每個類要用的值放在$var[__CLASS__]里面使用。

不過不管怎么說,如非必要,還是盡量不用static成員繼承吧。

還有一個有點類似的“坑”。我們說到private成員的時候,都知道private是指私有的,不會被子類繼承。但是有時候寫代碼的時候會忘記,直到載跟頭了才想起來原來是private導致子類找不到該有的成員,或者說是private都在子類聲明了,但是因為調用函數時是調用父類函數,結果得到的是父類這個private的值而不是子類的。遇到這種情況不可能又將函數原樣的重寫在子類里。所以使用private要特別小心。

曾經在使用Rackspace的SDK的時候就看到有些類里面使用了private成員,但是由于他們給出了不必要的打開文件權限,導致代碼在我們的服務器上運行不了。那么這個時候本想寫個子類覆蓋一下這個成員的初始值就好了,結果就因為這是個private成員,而***需要把所有引用到的地方都拷到自己寫的子類里面。為什么我們不直接改SDK,讓成員變成protected?因為開發包也許下次就升級了呢?修正之后我們把子類移除就好了。如果修改庫代碼成了習慣,想升級的時候就沒這么歡了。所以說,private成員的使用一定要慎之又慎,如果你也在開發SDK,就更需要考慮使用者是不是需要繼承?如果你必須寫private,你是不是能夠保證代碼能夠適應各種場景的使用?

除非你有非常充分的理由,static和private都是需要慎重使用的。

責任編輯:陳琳 來源: 51cto
相關推薦

2020-07-30 12:33:36

惡意軟件Emotet網絡攻擊

2019-03-01 08:20:26

2019-07-01 10:48:13

Tomcat中間件TPM

2021-09-03 06:46:36

工具Selenium元素

2009-12-08 17:29:26

PHP extends

2017-02-10 12:01:07

2024-05-24 08:42:29

智能體訓練

2011-07-01 08:41:12

PHP

2012-07-09 13:21:51

2011-06-14 10:17:28

埃洛普微軟諾基亞

2020-09-23 16:05:42

Python手繪圖表編程語言

2022-02-15 08:49:29

繼承C++variant

2011-07-07 14:28:23

PHP

2009-11-24 17:01:39

PHP5多重繼承

2009-12-07 16:07:03

PHP類的繼承

2009-01-08 09:51:00

2018-03-07 10:03:40

2013-05-20 09:59:50

2017-09-05 15:42:36

語言開發Python

2011-06-16 11:01:56

PHP繼承
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产成人精品久久二区二区91 | 中文字幕在线网 | 国产精品久久久乱弄 | 在线成人av| 大伊人久久 | 国产毛片久久久久久久久春天 | 国内自拍偷拍一区 | 午夜影院网站 | 精品粉嫩aⅴ一区二区三区四区 | 天天操夜夜操 | 成人三级网址 | 五月综合久久 | 在线观看视频亚洲 | 色综合久 | 欧美一级二级视频 | 国产99久久久国产精品下药 | 欧美一区二区三区在线视频 | 日韩精品1区2区 | 亚洲国产一区在线 | 黑人巨大精品欧美一区二区一视频 | 亚洲精品在线视频 | av在线一区二区三区 | 韩日有码 | 黄色精品 | 91精品一区二区三区久久久久久 | 高清视频一区二区三区 | 亚洲九九 | 一区二区视频在线观看 | 奇米久久| 狠狠狠| 亚洲国产成人精品久久 | 免费看黄色小视频 | 久草成人 | 人妖无码 | 久久精品99久久 | 一区二区三区视频在线 | 国产区精品视频 | 欧美在线一区二区三区四区 | 国产精品99视频 | 一级黄在线观看 | 亚洲一区二区视频 |