프로퍼티 (프로그래밍)

프로퍼티(property)는 일부 객체 지향 프로그래밍 언어에서 필드(데이터 멤버)와 메소드 간 기능의 중간인 클래스 멤버의 특수한 유형이다. 프로퍼티의 읽기와 쓰기는 일반적으로 게터(getter)와 세터(setter) 메소드 호출로 변환된다.

**지원 언어**
프로퍼티를 지원하는 프로그래밍 언어에는 액션스크립트 3, C#, D, 델파이/프리 파스칼, eC, 코틀린, 자바스크립트, 오브젝티브-C 2.0, 파이썬, 스칼라, 스위프트, 루아, 비주얼 베이직이 있다.
자바, C++과 같은 일부 객체 지향 언어들은 프로퍼티를 지원하지 않기 때문에 프로그래머가 한 쌍의 액세서(accessor)와 뮤테이터(mutator) 메소드를 대신 정의해야 한다.

**문법 예시**

**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)"!
class Shape 
{

public Int32 Height { get; set; }
public Int32 Width  { get; private set; }

}

**C++**
#include 
template  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.
template  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  alpha;
property  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 

**C++, Microsoft & C++Builder-specific**
예시 출처: MSDN  설명 문서
// 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;
}

**D**
class Pen
{
private int m_color; // private field

// public get property
public int color () {
return m_color;
}

// public set property
public void color (int value) {
m_color = value;
}
}
auto pen = new Pen;
pen.color = ~pen.color; // bitwise complement
// the set property can also be used in expressions, just like regular assignment
int theColor = (pen.color = 0xFF0000);
In D version 2, each property accessor or mutator must be marked with @property:
class Pen
{
private int m_color; // private field

// public get property
@property public int color () {
return m_color;
}

// public set property
@property public void color (int value) {
m_color = value;
}
}

**Delphi/Free Pascal**
type TPen = class
private
FColor: TColor;
function GetColor: TColor;
procedure SetColor(const AValue: TColor);
public
property Color: Integer read GetColor write SetColor;
end;
function TPen.GetColor: TColor;
begin
Result := FColor;
end;
procedure TPen.SetColor(const AValue: TColor);
begin
if FColor  AValue
then FColor := AValue;
end;
// accessing:
var Pen: TPen;
// ...
Pen.Color := not Pen.Color;
(Delphi also supports a 'direct field' syntax -
property Color: TColor read FColor write SetColor;
or
property Color: TColor read GetColor write FColor;
where the compiler generates the exact same code as for reading and writing
a field. This offers the efficiency of a field, with the safety of a property.
(You can't get a pointer to the property, and you can always replace the member
access with a method call.)
*)

**eC**
class Pen 
{
// private data member
Color color;
public:
// public property
property Color color 
{  
get { return color; }
set { color = value; }
}
}
Pen blackPen { color = black };
Pen whitePen { color = white };
Pen pen3 { color = { 30, 80, 120 } };
Pen pen4 { color = ColorHSV { 90, 20, 40 } };

**F#**
type Pen() = class
let mutable _color = 0
member this.Color
with get() = _color
and set value = _color 

**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

**ActionScript 3.0**
package  {
	public class Pen {
		private var _color:uint = 0;
		
		public function get color():uint {
			return _color;
		}
		
		public function set color(value:uint):void {
			_color = value;
		}
	}
}
var pen:Pen = new Pen();
pen.color = ~pen.color; // bitwise complement
pen.color += 1; // add one

**Objective-C 2.0**
@interface Pen : NSObject
@property (copy) NSColor *colour;	// The "copy" attribute causes the object's copy to be
					// retained, instead of the original.
@end
@implementation Pen
@synthesize colour;			// Compiler directive to synthesise accessor methods.
					// It can be left behind in Xcode 4.5 and later.
@end
위 예제는 다음과 같이 임의의 메소드 안에 사용이 가능하다:
Pen *pen = Pen alloc init;
pen.colour = NSColor blackColor;
float red = pen.colour.redComponent;
pen.colour drawSwatchInRect: NSMakeRect(0, 0, 100, 100);

**PHP**
class Pen
{
private int $color = 1;
function __set($property, $value)
{
if (property_exists($this, $property)) { 
$this->$property = $value;
}
}
function __get($property)
{
if (property_exists($this, $property)) {
return $this->$property;
}
return null;
}
}

$p = new Pen();
$p->color = ~$p->color; // Bitwise complement
echo $p->color;

**Python**
class Pen(object):
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 ...

**Ruby**
class Pen
def initialize
@color = 0
end

# Defines a getter for the @color field
def color
@color
end
# Defines a setter for the @color field
def color=(value)
@color = value
end
end
pen = Pen.new
pen.color = ~pen.color    # Bitwise complement
루비는 또한 클래스의 인스턴스 메소드로 정의되는 자동 게터/세터 신시사이저를 제공한다.
class Pen
attr_reader :brand    # Generates a getter for @brand (Read-Only)
attr_writer :size     # Generates a setter for @size  (Write-Only)
attr_accessor :color  # Generates both a getter and setter for @color (Read/Write)
def initialize
@color = 0          # Within the object, we can access the instance variable directly
@brand = "Penbrand"
@size = 0.7         # But we could also use the setter method defined by the attr_accessor Class instance method
end
end
pen = Pen.new
puts pen.brand           # Accesses the pen brand through the generated getter
pen.size = 0.5           # Updates the size field of the pen through the generated setter
pen.color = ~pen.color   

**Visual Basic**

**Visual Basic (.NET 2003-2010)**
Public Class Pen

Private _color As Integer ' Private field
Public Property Color() As Integer ' Public property
Get
Return _color
End Get
Set(ByVal value As Integer)
_color = value
End Set
End Property
End Class
' Create Pen class instance
Dim pen As New Pen()
' Set value
pen.Color = 1
' Get value
Dim color As Int32 = pen.Color

**Visual Basic (only .NET 2010)**
Public Class Pen
Public Property Color() As Integer ' Public property
End Class

' Create Pen class instance
Dim pen As New Pen()
' Set value
pen.Color = 1
' Get value
Dim color As Int32 = pen.Color

**Visual Basic 6**
' in a class named clsPen
Private m_Color As Long
Public Property Get Color() As Long
Color = m_Color
End Property
Public Property Let Color(ByVal RHS As Long)
m_Color = RHS
End Property
' accessing:
Dim pen As New clsPen
' ...
pen.Color = Not pen.Color

**같이 보기**
 속성 (컴퓨터 과학)- 데이터 바인딩- 인덱서 (프로그래밍)- 메서드 (컴퓨터 프로그래밍)- 뮤테이터 메소드
분류:객체 지향 프로그래밍