屬性 (編程)
屬性(Property),在一些物件導向程式設計語言中,是類的特殊成員,功能上居於欄位(或資料成員)與方法之間。可讀可寫屬性的語法類似於欄位,但屬性的讀寫操作通常被編譯為getter與setter方法呼叫。屬性使用類似於欄位的讀寫語法,比普通的方法呼叫的語法形式更易於讀寫操作;但屬性讀寫編譯為內部的方法呼叫,則可以支援資料確認、主動修改或實現唯讀欄位等功能。
語言支援
支援屬性的程式語言有:ActionScript 3、C#、D、Delphi/Free Pascal、eC、F#、Kotlin、JavaScript、Objective-C 2.0、Python、Scala、Swift、Lua、Visual Basic。
一些物件導向語言,如Java與C++,不支援屬性,而要求編程者寫一對accessor與mutator方法。 C++可以通過運算子多載來類比屬性。
不同的語法
一些語言用點表示,另一些語言用方括號表示,來訪問屬性。
點表示法
如JavaScript:
document.createElement('pre');
方括號表示法
JavaScript也可以用方括號來訪問屬性:
document['createElement']('pre');
具體語言實現舉例
C#
class Pen
{
private int color; // private field
// public property
public int Color
{
get
{
return this.color;
}
set
{
if (value > 0) {
this.color = value;
}
}
}
}
// accessing:
Pen pen = new Pen();
int color_tmp = 0;
// ...
pen.Color = 17;
color_tmp = pen.Color;
// ...
pen.Color = ~pen.Color; // bitwise complement ...
// another silly example:
pen.Color += 1; // a lot clearer than "pen.set_Color(pen.get_Color() + 1)"!
高版本的C#支援編譯器自動實現屬性。
class Shape
{
public Int32 Height { get; set; }
public Int32 Width { get; private set; }
}
C++
C++有多種方法類比屬性實現。
#include <iostream>
template <typename T> class property {
T value;
public:
T & operator = (const T &i) {
return value = i;
}
// This template class member function template serves the purpose to make
// typing more strict. Assignment to this is only possible with exact identical types.
// The reason why it will cause an error is temporary variable created while implicit type conversion in reference initialization.
template <typename T2> T2 & operator = (const T2 &i) {
T2 &guard = value;
throw guard; // Never reached.
}
// Implicit conversion back to T.
operator T const & () const {
return value;
}
};
struct Foo {
// Properties using unnamed classes.
class {
int value;
public:
int & operator = (const int &i) { return value = i; }
operator int () const { return value; }
} alpha;
class {
float value;
public:
float & operator = (const float &f) { return value = f; }
operator float () const { return value; }
} bravo;
};
struct Bar {
// Using the property<>-template.
property <bool> alpha;
property <unsigned int> bravo;
};
int main () {
Foo foo;
foo.alpha = 5;
foo.bravo = 5.132f;
Bar bar;
bar.alpha = true;
bar.bravo = true; // This line will yield a compile time error
// due to the guard template member function.
::std::cout << foo.alpha << ", "
<< foo.bravo << ", "
<< bar.alpha << ", "
<< bar.bravo
<< ::std::endl;
return 0;
}
C++, Microsoft & C++Builder的方言語法
例子來自MSDN documentation page (頁面存檔備份,存於網際網路檔案館):
// declspec_property.cpp
struct S
{
int i;
void putprop(int j)
{
i = j;
}
int getprop()
{
return i;
}
__declspec(property(get = getprop, put = putprop)) int the_prop;
};
int main()
{
S s;
s.the_prop = 5;
return s.the_prop;
}
JavaScript
function Pen() {
this._color = 0;
}
// Add the property to the Pen type itself, can also
// be set on the instance individually
Object.defineProperties(Pen.prototype, {
color: {
get: function () {
return this._color;
},
set: function (value) {
this._color = value;
}
}
});
var pen = new Pen();
pen.color = ~pen.color; // bitwise complement
pen.color += 1; // Add one
Python
Python 2.2開始的new-style classes (即衍生自object
的類)支援屬性。見the relevant section of the tutorial Unifying types and classes in Python 2.2 (頁面存檔備份,存於網際網路檔案館)。Python 2.6支援了定義屬性的裝飾器語法。
class Pen:
def __init__(self) -> None:
self._color = 0 # "private" variable
@property
def color(self):
return self._color
@color.setter
def color(self, color):
self._color = color
pen = Pen()
# Accessing:
pen.color = ~pen.color # Bitwise complement ...