PHP 函數和類的區別是什麼?

我在學習類的時候一直不懂類到底和函數有什麼區別,感覺函數也能完成類的工作

作者:eechen
鏈接:https://www.zhihu.com/question/68652979/answer/266047537
來源:知乎
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

面向對象編程(OOP)引入了相當多的特性,使編程變得更加複雜.

封裝,繼承,多態是OOP的三要素,這些是過程式中的函數所沒有的.

具體體現在:

1.封裝: class/interface/public/protected/private

2.繼承: extends/implements

3.多態: 方法重寫/方法重載


新增的class和interface加入了新的變量作用域,即類和接口裏代碼塊是函數所沒有的作用域.

在這個作用域裏,可以定義變量和函數這些類和接口的成員,並且支持使用public/protected/private關鍵字對這些成員進行訪問控制.比如public表示允許外部訪問,protected表示允許類及其子類訪問,private表示只允許所在類內部訪問.


而且OOP還引入了方法重寫和方法重載這些多態特性,即:

方法重寫:參數列表相同,方法體不同.

方法重載:參數列表不同,方法體不同.

方法重寫依賴繼承,是子類的方法覆蓋父類的方法,要求方法名和參數列表相同.

方法重載不依賴繼承,是同一個類中的兩個或兩個以上的同名方法,參數列表不同.

需要注意的是繼承並重寫的方法只能維持或放大訪問權限,不能縮小.

比如父類protected方法在子類重載爲public是可行的.

在PHP中,因爲不允許存在多個同名方法,所以不支持C++/Java那樣的方法重載.

但PHP提供了魔術方法(__call,__callStatic)用於間接實現方法重載.

PHP中方法重寫並不要求參數相同.

PHP不支持多重繼承(繼承多個父類),但可以實現多個接口,也可以用trait特性間接支持多重繼承.


有些人認爲繼承會增加子類和父類的耦合,所以反對繼承,甚至有些新的編程語言如Go等,直接不支持繼承,而是使用組合來取代繼承.比如依賴注入,本質上也是一種組合的思想,用於實現解耦.PHP中可以final修飾一個類,禁止這個類被繼承.


你看,這麼多特性,是不是增加了編程的複雜性.

所以說,一個開發者,如果你過程式編程都用不好,那肯定也玩不裝OOP.

如果連函數都搞不明白,那也肯定搞不懂類.


最後轉一段王垠關於OOP的論述:

“對象思想”作爲數據訪問的方式,是有一定好處的。 然而“面向對象”(多了“面向”兩個字),就是把這種本來良好的思想東拉西扯,牽強附會,發揮過了頭。 很多面嚮對象語言號稱“所有東西都是對象”,把所有函數都放進所謂對象裏面,叫做“方法”,把普通的函數叫做“靜態方法”。 實際上只有極少需要抽象的時候,需要使用內嵌於對象之內,跟數據緊密結合的“方法”。 其他的時候,你其實只是想表達數據之間的變換操作,這些完全可以用普通的函數表達,而且這樣做更加簡單和直接。 把所有函數放進對象的做法是本末倒置的,因爲函數本身並不屬於對象,它們只是對象上面的變換操作。 絕大部分函數是獨立於對象的,它們不能被叫做“方法”。 強制把所有函數放進它們本來不屬於的對象裏面,把它們全都作爲“方法”,導致了面向對象代碼邏輯過度複雜。 很簡單的想法,非得繞好多道彎子才能表達清楚。 很多人至今不知道自己所用的“面嚮對象語言”裏面的很多優點,都是從過程式語言繼承來的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章