프로퍼티 (프로그래밍)

프로퍼티(property)는 일부 객체 지향 프로그래밍 언어에서 필드(데이터 멤버)와 메소드 간 기능의 중간인 클래스 멤버의 특수한 유형이다. 프로퍼티의 읽기와 쓰기는 일반적으로 게터(getter)와 세터(setter) 메소드 호출로 변환된다. 프로퍼티를 지원하는 프로그래밍 언어에는 액션스크립트 3, C#, D, 델파이/프리 파스칼, eC, 코틀린, 자바스크립트, 오브젝티브-C 2.0, 파이썬, 스칼라, 스위프트, 루아, 비주얼 베이직이 있다. 자바, C++과 같은 일부 객체 지향 언어들은 프로퍼티를 지원하지 않기 때문에 프로그래머가 한 쌍의 액세서(accessor)와 뮤테이터(mutator) 메소드를 대신 정의해야 한다. 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; } } #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. 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; } 예시 출처: 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; } 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; } } 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.) *) 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 } }; type Pen() = class let mutable _color = 0 member this.Color with get() = _color and set value = _color <- value end 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 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 @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)]; 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; 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 ... 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 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 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 ' 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 속성 (컴퓨터 과학) 데이터 바인딩 인덱서 (프로그래밍) 메서드 (컴퓨터 프로그래밍) 뮤테이터 메소드