由於中文翻譯的原因,我們在很多情況下將Attribute與Property混為一談,或者說不是很清楚兩者的區別。其實這兩者的真實含義與具體功能還是差別比較大的:
property是指類向外提供的資料區域。而attribute則是描述對象在編譯時間或運行時屬性的,分為固有型和使用者自訂型,其中使用者自訂型可以利用Reflection在運行期擷取。這兩者是有本質區別的。
資料上說二者一個是service的屬性,而另一個是interface的。
第一種好象更準確,摘要如下:
在很多人的腦海中,Attribute就是類的屬性,Property呢?好像也是類的屬性?因此有很多人不加區別的統一稱為類的屬性,尤其是在寫中文文章的時候。這種心理是典型的鴕鳥心態,眼不見為淨。其實稍微用腳想一下就知道,事實肯定不是這樣的,UML中既然發明了這兩個術語,顯然不是用來冗餘的。它們之間肯定有著千絲萬縷的聯絡與區別。
各種各樣的物件導向語言、各種組件技術、模板技術、Web Service技術,其中大部分涉及到了“屬性”這個概念,而其英文術語則常常是Attribute、Property或者Field。很多人一概稱之為“屬性”,有的地方確實可以不加區分,但有的地方卻是差之毫釐、謬以千裡。我對於這些紛紛擾擾的技術和術語也很苦惱,但是我們至少可以通過UML中的這兩個術語的解釋找到一個可以參考的標準。無論如何,UML是物件導向技術的集大成者和事實上的標準。
很客觀的說,UML1.4中對於這兩個術語並沒有很清晰的定義,但是其區別還是顯而易見的。Attribute應該是UML1.4中的寵兒,而Property連一個單獨的術語都沒有撈到。誰也沒想到在UML2.0中風雲突變,Attribute從類圖中消失了,而Property堂而皇之入主中原。
1.4中 Attribute是與Classifier相關聯的術語,它比Property的影響範圍要小。Class是Classifier的子類,因此Attribute也可以表示Class的屬性。從上面的定義還可以看出,Attribute可以是Classifier的執行個體的命名的槽。對於Class來說,其執行個體就是Object,Object的槽就是對象的屬性值槽。因此,Attribute是可以作為對象的屬性的。而Property似乎沒有這一層的含義。按MOF(元對象設施,OMG的另一個規範,後面會有詳細解釋)的模型層次劃分,Attribute涉及的模型層從M2到M0,而Property似乎只是M2層的概念。
2.0中 Attribute這裡僅僅指一個類元的結構特徵,可以將類元的執行個體聯絡到一個或者一組具體值。而沒有提到執行個體的槽(slot)等等。我猜想,這是因為UML2.0中已經把Attribute作為Property的一個子集了,所以關於執行個體的槽(slot)等等的具體賦值方法,都歸結到Property的定義中解釋了。
另外一點值得注意的是,Attribute的定義來自於術語表,而沒有在元模型圖中出現。而Property出現在元模型圖中,並且都做了詳細而具體的解釋。這一點可以看出,UML強化Property,弱化Attribute的決心。
Attribute和Property的總結
這一節對Attribute和Property作一個小結,基於目前最新的UML2.0規範:
- 總體上來說,Attribute是Property的子集,Property會在適當的時機表現為Attribute;
Property出現在類圖的元模型中,代表了Class的所有結構化特徵;Attribute沒有出現在元模型中,它僅僅在Class的概念中存在,沒有相應的文法了;
- Property有詳細的定義和約束,而Attribute沒有詳細的定義,因此也不能用OCL寫出其約束。
- Property和Attribute都是M2層的概念。在M1層,它們的執行個體是具體類的屬性;在M0層,它們的執行個體的執行個體是具體對象的槽中儲存的值。
對於property和attribute這兩個名詞都叫“屬性”的問題,來源於國內it書籍翻譯界的疏忽。
其實它們來源於兩個不同的領域,attribute屬於OOA/OOD的概念,而property屬於程式設計語言中的概念。下面我們來說明它們的異同。
Attribute
Attributes是Microsoft .NET Framework檔案的中繼資料,可以用來向運行時描述你的代碼,或者在程式啟動並執行時候影響應用程式的行為。
Property
屬性是物件導向編程的基本概念,提供了對私人欄位的訪問封裝,在C#中以get和set訪問器方法實現對可讀可寫屬性的操作,提供了安全和靈活的資料訪問封裝。關於屬性的概念,不是本文的重點,而且相信大部分的技術人員應該對屬性有清晰的概念。以下是簡單的屬性
區別
可以說兩者沒有可比性,只不過我們國家的語言特點才引起的歧異,其實只要記住Attribute是派生於System,Attribute類之下,它的主要作用是描述,比如某為了描述某個方法是來自與外部的dll,
可以寫如下代碼,這就是一個Attribute,他是一個描述(或者說聲明)
[DllImport("User32.dll")]
Attribute也有很多系統的“預設”屬性,見下表
| 預定義的屬性 |
有效目標 |
說明 |
| AttributeUsage |
Class |
指定另一個屬性類的有效使用方式 |
| CLSCompliant |
全部 |
指出程式元素是否與 CLS 相容 |
| Conditional |
Method |
指出如果沒有定義相關聯的字串,編譯器就可以忽略對這個方法的任何調用 |
| DllImport |
Method |
指定包含外部方法的實現的 DLL 位置 |
| STAThread |
Method(Main) |
指出程式的預設執行緒模式為 STA |
| MTAThread |
Method(Main) |
指出程式的預設模型為多線程 (MTA) |
| Obsolete |
除了 Assembly 、 Module 、 Parameter 和 Return |
將一個元素標示為不可用,通知使用者此元素將被從未來的產品 |
| ParamArray |
Parameter |
允許單個參數被隱式地當作 params( 數組 ) 參數對待 |
| Serializable |
Class 、 Struct 、 enum 、 delegate |
指定這種類型的所有公用和私人欄位可以被序列化 |
| NonSerialized |
Field |
應用於被標示為可序列化的類的欄位,指出這些欄位將不可被序列化 |
| StructLayout |
Class 、 struct |
指定類或結構的資料布局的性質,比如 Auto 、 Explicit 或 sequential |
| ThreadStatic |
Field( 靜態 ) |
實現線程局部儲存 (TLS) 。不能跨多個線程共用給定的靜態欄位,每個線程擁有這個靜態欄位的副本 |
而 Property 是指編程過程中的欄位,也即類的成員。如:
private int hour; //定義私人變數表示"小時",外部是訪問不到的public int Hour// 定義Hour程式介面{ set { hour=value; } get { return hour;}}
參考資料:http://wenku.baidu.com/view/c932fbd049649b6648d747b2.html
http://www.cnblogs.com/winner/archive/2008/12/11/1353314.html
http://www.cnblogs.com/mfryf/archive/2012/02/14/2350988.html