屬性 (編程)

屬性（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：

```JavaScript
document.createElement('pre');
```

### 方括號表示法

JavaScript也可以用方括號來訪問屬性：

```JavaScript
document['createElement']('pre');
```

## 具體語言實現舉例

### C#

```CSharp
class Pen 
{
    private int color; // private field
    
    // public property
    public int Color 
    {  
        get
        {
            return this.color;
        }
        set 
        {
            if (value > 0) {
                this.color = value;
            }
        }
    }
}
```

```CSharp
// 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#支持編譯器自動實現屬性。

```CSharp
class Shape 
{
    
    public Int32 Height { get; set; }
    public Int32 Width  { get; private set; }
    
}
```

### C++

C++有多種方法模擬屬性實現。

```cpp
#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：

```Cpp
// 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

```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;
        }
    }
});
```

```JavaScript
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支持了定義屬性的裝飾器語法。

```python
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
```

```python
pen = Pen()
# Accessing:
pen.color = ~pen.color  # Bitwise complement ...
```