看過了一些trait的介紹,也在架構中看到了。但是感覺trait做的事情,用interface是不是也能做呢?
個人感覺每個trait實現的功能都非常集中,也非常輕量,這個很贊,但是相對的有些class可能要同時用好幾個trait,而且假如同時繼承了類,實現了介面,並且其中包含覆蓋,那理清這個類的關係感覺會很困難,這是我最困惑的地方,當然也可能是我技術還不夠。
但是既然出了這個文法,肯定還是有他的道理的,所以就想問一下,項目中使用trait的意義是什麼呢?
回複內容:
看過了一些trait的介紹,也在架構中看到了。但是感覺trait做的事情,用interface是不是也能做呢?
個人感覺每個trait實現的功能都非常集中,也非常輕量,這個很贊,但是相對的有些class可能要同時用好幾個trait,而且假如同時繼承了類,實現了介面,並且其中包含覆蓋,那理清這個類的關係感覺會很困難,這是我最困惑的地方,當然也可能是我技術還不夠。
但是既然出了這個文法,肯定還是有他的道理的,所以就想問一下,項目中使用trait的意義是什麼呢?
有不少目的,我相信其他的答案會從各個角度提及。
我所知道的一個重要目的是:方便代碼產生器的工作。
如果一個類的部分代碼是產生器產生的,部分代碼是自己寫的,那麼我們肯定希望產生器產生的代碼在trait
裡,我們自己寫的代碼引用這個trait
。這樣如果產生器需要重新運行,自寫的代碼就無需任何變化。
這一點用繼承也許也能做到,但PHP沒有多繼承。同時引用多個產生器產生的代碼,只能依賴trait
。
這一點你可以看一下 C# 的“部分類”(partial class)。在目的上是很相似的。
你可以這麼理解
1、trait
用來複用代碼的
2、解決了 php
不能多繼承的問題(多繼承也會產生問題,這裡不展開)
3、使用 trait
的類,跟 trait
本身是可以沒有任何關係的
.......
trait
裡面定義了實現
interface
只是聲明
這兩個還是有區別的
......
PHP
和Java
等大多數物件導向的語言一樣是單繼承,既一個類只能繼承於一個父類。雖然單繼承是公認使代碼清晰準確的方式,但有時候多繼承也有自己的優勢。trait
的出現就是一種解決需要多繼承情境的方式。多繼承的好處就是讓一個類繼承多個父類的功能,雖然這違反了類單一職責原則,但是在某些場合下,一些小功能使用多繼承是最合適不過的。比如Laravel
中定義了一個宏trait
,只是很簡單的讓類實現一些類似C
宏定義的方法,因為這其中含有一些實體方法和屬性,所以通過interface
定義是不能實現的,而需要使用這個功能的類又有可能已經繼承於其他類,所以通過abstract class
定義也是不能實現的,所以這種場合下trait
就能體現它的優勢了。
在解決多繼承的代碼中用的較多
減少複製粘貼造成的維護不便問題
通俗一點,就是能把重複的方法拆分到一個檔案,通過 use 引入以達到代碼複用的目的