面向物件程式設計(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的論述:

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