맨위로가기

프로퍼티 (프로그래밍)

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

프로퍼티는 프로그래밍 언어에서 객체의 속성에 접근하고 수정하는 방식을 정의하는 기능이다. 프로퍼티를 지원하는 언어로는 ActionScript 3, C#, D, Delphi/Free Pascal, eC, F#, Kotlin, JavaScript, Objective-C, Python, Scala, Swift, Lua, Visual Basic 등이 있으며, Java와 C++는 프로퍼티를 직접 지원하지 않아 접근자 메서드를 사용한다. 프로퍼티는 캡슐화를 통해 데이터 접근을 제어하고, 필드를 프로퍼티로 쉽게 변환하여 코드 유지 보수성을 높인다.

더 읽어볼만한 페이지

  • 객체 지향 프로그래밍 - Is-a
    Is-a 관계는 객체 지향 프로그래밍에서 한 유형이 다른 유형의 하위 유형임을 나타내는 관계로, 상속, 서브타이핑, 리스코프 치환 원칙과 관련되며, C++, Python, Java 등에서 표현된다.
  • 객체 지향 프로그래밍 - 객체 (컴퓨터 과학)
    객체는 객체 지향 프로그래밍에서 데이터와 조작을 묶어 메시지를 수신하고, 프로그램의 개념을 표현하며 가시성과 재사용성을 높이는 실체이다.
프로퍼티 (프로그래밍)
'개요'
'정의''객체 지향 프로그래밍에서 클래스의 속성을 나타내는 멤버'
'역할''클래스 외부에서 속성에 접근하고 수정하는 데 사용'
'특징''값을 저장하는 필드와 값을 읽거나 쓰는 접근자(getter/setter)로 구성될 수 있음'
'다른 이름''속성(property)'
'개념'
'캡슐화''클래스 내부 데이터의 직접적인 접근을 막고 메서드를 통해 접근하도록 하여 데이터 보호'
'정보 은닉''클래스 내부 구현을 숨기고 외부에는 필요한 인터페이스만 제공'
'접근 제어''속성에 대한 읽기, 쓰기 권한을 제어하여 데이터 무결성 유지'
'구현'
'C#''get 및 set 접근자를 사용하여 속성 정의'
'Java''getter 및 setter 메서드를 사용하여 속성에 접근'
'Python''@property 데코레이터를 사용하여 속성 정의'
'JavaScript''Object.defineProperty() 메서드를 사용하여 속성 정의'
'Objective-C''@property 키워드를 사용하여 속성 정의'
'Swift''stored property 및 computed property를 사용하여 속성 정의'
'장점'
'유연성''속성에 대한 접근 방식을 변경하지 않고 내부 구현 변경 가능'
'제어''속성에 대한 접근 및 수정에 대한 추가 로직 추가 가능'
'유지 보수성''코드 변경 시 영향 범위를 최소화하여 유지 보수 용이'
'단점'
'복잡성 증가''단순한 속성에 대한 접근을 위해 추가 코드 작성 필요'
'성능 저하 가능성''접근자 메서드 호출로 인한 오버헤드 발생 가능'
'활용 예시'
'자동차 클래스의 속도''속도 속성에 대한 읽기 전용 접근자를 제공하여 외부에서 속도 수정 방지'
'사람 클래스의 이름''이름 속성에 대한 쓰기 접근자에 유효성 검사 로직을 추가하여 잘못된 이름 설정 방지'
'관련 용어'
'필드 (Field)''클래스 내부에 값을 저장하는 변수'
'메서드 (Method)''클래스 내부에 정의된 함수'
'접근자 (Accessor)''속성의 값을 읽거나 쓰는 데 사용되는 메서드 (getter/setter)'

2. 지원 언어

프로퍼티는 다양한 프로그래밍 언어에서 지원되며, 각 언어는 고유한 문법과 특징을 가지고 프로퍼티를 구현한다.

프로퍼티를 지원하는 언어로는 ActionScript 3, C#, D, 델파이/Free Pascal, eC, F#, Kotlin, JavaScript, Objective-C 2.0, Python, Scala, Swift, Lua, Visual Basic 등이 있다.[1]

자바 및 C++와 같은 일부 객체 지향 언어는 프로퍼티를 지원하지 않아 프로그래머가 대신 접근자 및 변경자 메서드 쌍을 정의해야 한다.[1]

Oberon-2는 객체 변수 가시성 플래그를 사용하는 대체 메커니즘을 제공한다.[1] 자바 가상 머신을 위해 설계된 Groovy와 같은 다른 언어는 프로퍼티를 기본적으로 지원한다.[1]

2. 1. 프로퍼티 지원 언어

다음은 프로퍼티를 직접 지원하거나 유사한 기능을 제공하는 언어들이다.

  • ActionScript 3
  • C#
  • D
  • 델파이/Free Pascal
  • eC
  • F#
  • Groovy
  • Kotlin
  • JavaScript
  • Objective-C 2.0
  • Python
  • Scala
  • Swift
  • Lua
  • Visual Basic


자바 및 C++와 같은 일부 객체 지향 언어는 프로퍼티를 지원하지 않아 프로그래머가 대신 접근자 및 변경자 메서드 쌍을 정의해야 한다.

C++연산자 오버로딩을 사용하여 프로퍼티를 에뮬레이션할 수 있다. 또한 일부 C++ 컴파일러는 언어 확장의 일환으로 프로퍼티를 지원한다.

루비, 스몰토크와 같은 일부 언어는 일반 메서드를 사용하여 프로퍼티와 유사한 구문을 구현한다.

2. 2. 프로퍼티 미지원 언어

프로퍼티를 직접 지원하지는 않지만, 접근자(getter)와 변경자(setter) 메서드를 통해 유사한 기능을 구현할 수 있는 언어는 다음과 같다.

2. 3. 기타

자바 가상 머신(JVM)을 위해 설계된 Groovy와 같은 언어는 프로퍼티를 기본적으로 지원한다. Oberon-2는 객체 변수 가시성 플래그를 사용하는 대체 메커니즘을 제공한다. Perl과 같은 일부 언어에서는 호출 컨텍스트에 따라 기본 데이터를 반환하거나 변경하는 단일 메서드로 유사한 구문을 구현할 수 있다.

3. 문법 예시

객체 지향 프로그래밍에서 객체 조작의 공통화는 매우 중요하다. 클래스가 다른 객체 간에 조작을 공통화하려 할 때, 특정 객체에만 존재하는 필드를 직접 조작하는 처리가 있으면 공통화를 방해하게 된다. 이 때문에 객체 지향 프로그래밍에서는 접근자라고 불리는 메서드를 통해 필드를 조작하는 것이 정석이 되었다. 그러나 같은 필드만 조작하는 상태에서 접근자를 정의하는 것은 번거로울 수 있다. 그래서 Object Pascal(델파이)에서 '''프로퍼티'''가 도입되었다.

Object Pascal에서 프로퍼티는 클래스 외부에서 공개된 필드와 동일하게 조작할 수 있다. 하지만, 프로퍼티 정의에서는 실체를 메서드 호출로 구현하거나, 읽고 쓰기에 제한을 두거나, 파생형에서 재정의 가능하게 하는 등 유연성을 부여할 수 있다.

```delphi

type

TValueHolder = class

private

FValue1: Integer;

protected

function GetValue: Integer;

procedure SetValue( aValue: Integer );

public

FValue2: Integer;

published

// 프로퍼티 정의 예시

// 메서드로 구현한 프로퍼티 (Value1 조작은 GetValue와 SetValue 호출)

property Value1: Integer read GetValue write SetValue;

// 읽기 전용 프로퍼티

property Value2: Integer read FValue1;

// 쓰기 전용 프로퍼티

property Value3: Integer write FValue1;

// 필드 읽고 쓰기에 특화된 프로퍼티 (파생형에서 재정의하지 않으면 거의 필드와 동일)

property Value4: Integer read FValue1 write FValue1;

end;

function TValueHolder.GetValue: Integer;

begin

Result := FValue1;

end;

procedure TValueHolder.SetValue( aValue: Integer );

begin

FValue1 := aValue;

end;

var

Example: TValueHolder;

ResultValue: Integer;

begin

Example := TValueHolder.Create;

// 프로퍼티 사용 예시

Example.Value1 := 0; // SetValue 호출

ResultValue := Example.Value1; // GetValue 호출

// 참고: 필드 직접 조작

Example.FValue2 := 0;

ResultValue := Example.FValue2;

end;

```

필드를 직접 조작하면 필드가 존재하지 않는 객체를 공통 함수(예시에서는 Count)에서 재사용할 수 없게 된다. 이를 방지하기 위해 객체 지향 프로그래밍에서는 접근자를 사용하지만, 프로퍼티가 없는 언어에서는 공개된 필드를 접근자로 바꾸려면 필드를 조작하는 모든 부분을 수정해야 한다. 그래서 접근자를 항상 정의하는 것이 일반적이었다.

Object Pascal에서 필드 직접 조작 문제 예시:

```delphi

// 필드를 직접 조작하는 범용 함수 예시

function Count( Collection : T ): Integer;

begin

// 예시용이며 현실적으로 의미 있는 처리는 아니다. fCount는 공개되지 않음.

Result := Collection.FCount // 필드를 직접 참조

end;

// 호출 측

// ◯: "TArray에 fCount"가 있으므로 구문 오류 없음

Count( TArray.Create );

// ✗: "TLinkedList에 fCount"가 없으므로 구문 오류 발생

Count( TLinkedList.Create );

// 접근자를 경유하여 조작하는 범용 함수 예시

function Count( Collection : T ): Integer;

begin

// 예시용이며 현실적으로 의미 있는 처리는 아니다.

Result := Collection.Count // 접근자(프로퍼티) 경유 참조

end;

// 호출 측

// 어느 쪽도 구문 오류 없음

Count( TArray.Create );

Count( TLinkedList.Create );

```

프로퍼티를 가진 언어에서는 필드에서 접근자로 변경이 쉽다. 아래 예시에서는 필드로 공개했던 Value를 프로퍼티 Value로 대체했지만, 필드를 조작했던 부분은 변경할 필요가 없다. 따라서 프로퍼티가 있는 언어에서는 우선 필드를 공개하고 필요하면 프로퍼티로 변경하는 방식이 가능하다.

Object Pascal에서 프로퍼티화 예시:

```delphi

type

// Value를 프로퍼티화

TValueHolder = class

private

// 추가

FValue: Integer;

public

// 삭제

//Value: Integer;

published

// 추가

property Value: Integer read FValue write FValue;

end;

var

Example: TValueHolder;

ResultValue: Integer;

begin

Example := TValueHolder.Create;

// 프로퍼티화해도 변경 필요 없음

Example.Value := 0;

ResultValue := Example.Value;

end;

```

필드에 제약을 걸기 쉬운 언어일수록 운용성이 높아진다. 필드를 Const 등으로 수식하여 읽기 전용으로 할 수 있다면, 필드를 읽기 전용 프로퍼티로 쉽게 변경할 수 있다. Objective-C는 프로퍼티 선언과 필드 선언이 일체화되어, 단순한 프로퍼티는 파생형에서 재정의 가능 여부를 제외하고 필드와 거의 같다.[7]

```objective-c

@property float value;

```

Swift는 Objective-C와 호환되며, 저장 방법 지정이 속성 정의 안에 포함되어 필드와 프로퍼티 융합이 더 진행되었다.[8]

```swift

@SmallNumber var value: Int

```

프로퍼티를 지원하는 언어는 다음과 같다.[2]

3. 1. C#

C#에서는 `get` 및 `set` 접근자를 사용하여 프로퍼티를 정의한다. 이를 통해 [백킹 필드](https://ko.wikipedia.org/wiki/%EB%B0%B1%ED%82%B9_%ED%95%84%EB%93%9C)의 값을 읽고 쓸 수 있다. 명시적 백킹 필드를 직접 사용하거나, 컴파일러가 백킹 필드를 자동으로 생성하는 "자동 구현 프로퍼티"를 사용할 수도 있다.

다음은 명시적 백킹 필드를 사용하는 프로퍼티의 예시이다.

```csharp

class Pen

{

private int color; // private 필드

// public 프로퍼티

public int Color

{

get

{

return this.color;

}

set

{

if (value > 0) {

this.color = value;

}

}

}

}

```

```csharp

// 접근:

Pen pen = new Pen();

int color_tmp = 0;

// ...

pen.Color = 17;

color_tmp = pen.Color;

// ...

pen.Color = ~pen.Color; // 비트 보수 ...

// 또 다른 어리석은 예시:

pen.Color += 1; // "pen.set_Color(pen.get_Color() + 1)"보다 훨씬 더 명확하다!

```

다음은 자동 구현 프로퍼티의 예시이다.

```csharp

class Shape

{

public int Height { get; set; }

public int Width { get; private set; }

}

3. 1. 1. 명시적 백킹 필드를 가지는 프로퍼티

C#에서 클래스와 구조체는 프로퍼티를 가질 수 있다. 명시적 백킹 필드를 사용하는 기본적인 프로퍼티의 예시는 다음과 같다.

```csharp

class Person {

/// 백킹 필드

private string name;

/// name을 캡슐화하는 프로퍼티

public string Name {

get { return name; }

set {

if (value == null) { throw new ArgumentNullException(); }

name = value;

}

}

}

```

프로퍼티 구문 내에서 `get`과 `set`은 컨텍스트(문맥) 키워드로 기능하며, `set` 접근자 내에서는 `value`가 컨텍스트 키워드로 기능한다.

```csharp

var person = new Person();

// set 접근

person.Name = "John";

// get 접근

string userName = person.Name;

```

호출 측에서는 필드에 접근하는 것과 같은 구문으로 프로퍼티의 기능을 호출한다.

`get` 및 `set` 접근자를 사용하여 [백킹 필드](https://ko.wikipedia.org/wiki/%EB%B0%B1%ED%82%B9_%ED%95%84%EB%93%9C)의 값을 읽고 쓴다.

```csharp

class Pen

{

private int color; // private 필드

// public 프로퍼티

public int Color

{

get

{

return this.color;

}

set

{

if (value > 0) {

this.color = value;

}

}

}

}

```

```csharp

// 접근:

Pen pen = new Pen();

int color_tmp = 0;

// ...

pen.Color = 17;

color_tmp = pen.Color;

// ...

pen.Color = ~pen.Color; // 비트 보수 ...

// 또 다른 어리석은 예시:

pen.Color += 1; // "pen.set_Color(pen.get_Color() + 1)"보다 훨씬 더 명확하다!

```

최신 C# 버전에서는 컴파일 중에 프로퍼티의 백킹 필드가 컴파일러에 의해 생성되는 "자동 구현 프로퍼티"도 허용한다. 이는 프로퍼티가 setter를 가져야 함을 의미한다. 그러나 private으로 설정할 수 있다.

```csharp

class Shape

{

public int Height { get; set; }

public int Width { get; private set; }

}

```

Object Pascal을 예시로 프로퍼티의 구문 예를 아래에 나타낸다. 프로퍼티는 아래의 사용 예시의 Value1처럼 클래스 외부에서 공개된 필드 FValue2와 완전히 동일하게 조작할 수 있다. 하지만, 프로퍼티의 정의에서는 아래의 예시와 같이 실체를 메서드 호출로 구현하거나, 읽고 쓰기에 제한을 두거나, 필드의 값을 조작하는 데에는 변함이 없지만 파생형에서 재정의 가능하게 하거나 별칭으로 하는 등 유연성을 부여할 수 있다.

```delphi

type

TValueHolder = class

private

FValue1: Integer;

protected

function GetValue: Integer;

procedure SetValue( aValue: Integer );

public

FValue2: Integer;

published

// 프로퍼티의 정의 예시

// 메서드로 구현한 프로퍼티

// Value1에 대한 조작이 GetValue와 SetValue의 조작이 된다

property Value1: Integer read GetValue write SetValue;

// 읽기 전용으로 한 프로퍼티

property Value2: Integer read FValue1;

// 쓰기 전용으로 한 프로퍼티

property Value3: Integer write FValue1;

// 필드의 읽고 쓰기에 특화된 프로퍼티

// (파생형에서 재정의하지 않으면 거의 필드와 동일)

property Value4: Integer read FValue1 write FValue1;

end;

function TValueHolder.GetValue: Integer;

begin

Result := FValue1;

end;

procedure TValueHolder.SetValue( aValue: Integer );

begin

FValue1 := aValue.

end;

var

Example: TValueHolder;

ResultValue: Integer;

begin

Example := TValueHolder.Create;

// 프로퍼티의 사용 예시

Example.Value1 := 0; // SetValue의 호출이 된다

ResultValue := Example.Value1; // GetValue의 호출이 된다

// 참고: 필드의 직접 조작

Example.FValue2 := 0;

ResultValue := Example.FValue2;

end;

3. 1. 2. 자동 구현 프로퍼티

C# 최신 버전에서는 컴파일러가 자동으로 프로퍼티의 백킹 필드(backing field)를 생성하는 "자동 구현 프로퍼티"를 사용할 수 있다. 자동 구현 프로퍼티는 `get` 및 `set` 접근자를 간단하게 선언하여 사용할 수 있도록 한다. 이때, 프로퍼티는 `setter`를 가져야 하지만, `private`으로 설정할 수도 있다.

C# 코드 예시는 다음과 같다.

```csharp

class Shape

{

public int Height { get; set; }

public int Width { get; private set; }

}

```

위 코드에서 `Height` 프로퍼티는 `get`과 `set` 접근자를 모두 가지며, `Width` 프로퍼티는 `get` 접근자는 `public`, `set` 접근자는 `private`으로 설정되어 있다.

3. 2. C++

C++는 기본적으로 프로퍼티를 지원하지 않지만, 연산자 오버로딩 등을 사용하여 유사하게 구현할 수 있다. 일부 컴파일러는 언어 확장 기능을 통해 프로퍼티를 지원한다.

  • Microsoft Visual C++, GCC, LLVM/clang 컴파일러는 `__declspec(property)`를 지원한다.
  • C++Builder에서는 `__property` 키워드를 사용하여 프로퍼티를 정의할 수 있다.

3. 2. 1. 표준 C++

cpp

#include

template class property {

T value;

public:

T & operator = (const T &i) {

return value = i;

}

// 이 템플릿 클래스 멤버 함수 템플릿은 자료형을 더 엄격하게 만드는 역할을 한다.

// 이 연산자에 할당하는 것은 정확히 동일한 유형에서만 가능하다.

// 오류가 발생하는 이유는 참조 초기화 시 암시적 형식 변환 중에 임시 변수가 생성되기 때문이다.

template T2 & operator = (const T2 &i) {

T2 &guard = value;

throw guard; // 절대 도달하지 않음.

}

// T로의 암시적 변환.

operator T const & () const {

return value;

}

};

struct Foo {

// 이름 없는 클래스를 사용한 프로퍼티.

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 {

// property<>-템플릿 사용.

property alpha;

property bravo;

};

int main () {

Foo foo;

foo.alpha = 5;

foo.bravo = 5.132f;

Bar bar;

bar.alpha = true;

bar.bravo = true; // 이 줄은 컴파일 시간 오류를 발생시킨다.

// 가드 템플릿 멤버 함수 때문에.

::std::cout << foo.alpha << ", "

<< foo.bravo << ", "

<< bar.alpha << ", "

<< bar.bravo

<< ::std::endl;

return 0;

}

```

C++는 일급 프로퍼티를 가지고 있지 않지만, 템플릿과 연산자 오버로딩을 사용하여 프로퍼티를 비슷하게 만들 수 있다. 위의 코드는 그 예시 중 하나이다.

자세한 예시는 https://stackoverflow.com/a/5924594 Stack Overflow에서 확인할 수 있다.

3. 2. 2. C++ 컴파일러 확장

C++는 일급 프로퍼티를 지원하지 않지만, `__declspec(property)` 키워드를 사용하여 프로퍼티를 에뮬레이션할 수 있다. 이는 마이크로소프트 Visual C++ 컴파일러 확장 기능이다. GCC와 LLVM/clang 컴파일러도 `__declspec(property)`를 지원한다. C++Builder에서는 `__property` 키워드를 사용하여 프로퍼티를 정의할 수 있다.

다음은 `__declspec(property)`를 사용한 예시이다.

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

}

```

위 코드에서 `the_prop`는 `getprop` 함수를 getter로, `putprop` 함수를 setter로 사용하는 프로퍼티로 정의된다. `s.the_prop = 5;`와 같이 프로퍼티에 값을 할당하면 `putprop` 함수가 호출되고, `return s.the_prop;`와 같이 프로퍼티 값을 읽으면 `getprop` 함수가 호출된다.

3. 3. D

D는 `get` 및 `set` 프로퍼티를 명시적으로 정의할 수 있다. D 2.0부터는 `@property` 어노테이션을 사용하여 프로퍼티 접근자와 변경자를 표시해야 한다.[1]

```d

class Pen

{

private int m_color; // private 필드

// public get 프로퍼티

@property public int color () {

return m_color;

}

// public set 프로퍼티

@property public void color (int value) {

m_color = value;

}

}

3. 4. Delphi/Free Pascal

delphi

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;

```

```delphi

// 접근:

var Pen: TPen;

// ...

Pen.Color := not Pen.Color;

(*

Delphi와 Free Pascal은 또한 '직접 필드' 구문을 지원합니다.

property Color: TColor read FColor write SetColor;

또는

property Color: TColor read GetColor write FColor;

여기서 컴파일러는 필드를 읽고 쓰는 것과 정확히 동일한 코드를 생성합니다. 이는 속성의 안전성과 함께 필드의 효율성을 제공합니다.

(속성에 대한 포인터를 얻을 수 없으며, 멤버 접근을 항상 메서드 호출로 바꿀 수 있습니다.)

  • )

```

Delphi/Free Pascal에서는 `read` 및 `write` 지시자를 사용하여 프로퍼티를 정의한다. `read`에는 읽을 때의 동작, `write`에는 쓸 때의 동작을 지정한다. 위의 코드에서 `Color` 프로퍼티는 `GetColor` 메서드를 통해 읽고, `SetColor` 메서드를 통해 쓴다.

또한, 직접 필드 접근 방식을 지원하여 효율성과 안전성을 동시에 제공한다.[7] 예를 들어, `property Color: TColor read FColor write SetColor;` 또는 `property Color: TColor read GetColor write FColor;` 와 같이 선언하면 컴파일러가 필드를 읽고 쓰는 것과 동일한 코드를 생성한다.

3. 5. eC

eC에서는 `property` 키워드를 사용하여 프로퍼티를 정의한다. 다음은 그 예시이다.

```eC

class Pen

{

// private data member

색상 color;

public:

// public property

property 색상 color

{

get { return color; }

set { color = value; }

}

}

Pen blackPen { color = 검정 };

Pen whitePen { color = 흰색 };

Pen pen3 { color = { 30, 80, 120 } };

Pen pen4 { color = ColorHSV { 90, 20, 40 } };

3. 6. F#

fsharp

type Pen() =

class

let mutable _color = 0

member this.Color

with get() = _color

and set value = _color <- value

end

```

```fsharp

let pen = new Pen()

pen.Color <- pen.Color

```

F#에서는 `member` 키워드와 `get`, `set` 접근자를 사용하여 프로퍼티를 정의한다.[1]

프로퍼티를 지원하는 언어는 다음과 같다.[2]

3. 7. JavaScript

javascript

function Pen() {

this._color = 0;

}

// 프로퍼티를 Pen 타입 자체에 추가하며,

// 인스턴스 개별적으로 설정할 수도 있습니다.

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; // 비트 보수

pen.color += 1; // 1 더하기

```

`Object.defineProperties` 메서드를 사용하여 프로퍼티를 정의한다. `get` 및 `set` 접근자를 사용하여 프로퍼티 값을 읽고 쓴다.[1]

3. 8. ActionScript 3.0

actionscript3

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;

}

}

}

```

```actionscript3

var pen:Pen = new Pen();

pen.color = ~pen.color; // 비트 보수

pen.color += 1; // 1 더하기

3. 9. Objective-C 2.0

Objective-C 2.0에서는 `@property` 및 `@synthesize` 지시어를 사용하여 프로퍼티를 정의하고 접근자 메서드를 자동으로 생성할 수 있다.[7]

```objc

@interface Pen : NSObject

@property (copy) NSColor *colour; // "copy" 속성은 객체의 복사본을 원본 대신 보존하게 한다.

@end

@implementation Pen

@synthesize colour; // 접근자 메소드를 합성하도록 하는 컴파일러 지시어이다.

// Xcode 4.5 이상에서는 생략할 수 있다.

@end

```

위 예제는 다음과 같이 임의의 메서드에서 사용될 수 있다.

```objc

Pen *pen =

pen.colour = NSColor blackColor;

float red = pen.colour.redComponent;

[pen.colour drawSwatchInRect: NSMakeRect(0, 0, 100, 100)];

```

Objective-C에서는 프로퍼티 선언과 필드 선언이 일체화되어 있어, 가장 단순한 프로퍼티는 파생형에서 재정의 가능 여부를 제외하고는 필드와 다르지 않다.[7]

```objc

@property float value;

3. 10. PHP

PHP에서는 `__get` 및 `__set` 매직 메서드를 사용하여 프로퍼티를 구현할 수 있다. 다음은 그 예시이다.

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

}

}

```

위 코드에서 `Pen` 클래스는 `$color`라는 private 프로퍼티를 가진다. `__set` 메서드는 프로퍼티에 값을 할당할 때 호출되며, `__get` 메서드는 프로퍼티의 값을 가져올 때 호출된다. `property_exists` 함수는 해당 프로퍼티가 클래스에 존재하는지 확인한다.

다음은 위 클래스를 사용하는 예시이다.

```php

$p = new Pen();

$p->color = ~$p->color; // 비트 보수

echo $p->color;

```

위 코드에서 `$p` 객체의 `$color` 프로퍼티에 비트 보수 연산(`~`)을 적용한 값을 할당하고, 그 값을 출력한다.

3. 11. Python

`@property` 데코레이터를 사용하여 프로퍼티를 정의하며, `@.setter` 데코레이터를 사용하여 setter 메서드를 정의한다.[1] 프로퍼티는 새로운 스타일의 클래스(`object`를 상위 클래스로 갖는 클래스)에서만 제대로 작동하며, Python 2.2 이상에서만 사용할 수 있다. Python 2.6은 프로퍼티 정의를 위한 데코레이터를 포함하는 새로운 구문을 추가했다.



class Pen:

def __init__(self) -> None:

self._color = 0 # "private" 변수

@property

def color(self):

return self._color

@color.setter

def color(self, color):

self._color = color





pen = Pen()

# 접근:

pen.color = ~pen.color # 비트 보수 ...


3. 12. Ruby

Ruby에서는 `attr_reader`, `attr_writer`, `attr_accessor` 메서드를 사용하여 프로퍼티를 정의하고 접근자 메서드를 자동으로 생성한다.

```ruby

class Pen

attr_reader :brand # @brand에 대한 getter 생성 (읽기 전용)

attr_writer :size # @size에 대한 setter 생성 (쓰기 전용)

attr_accessor :color # @color에 대한 getter와 setter 모두 생성 (읽기/쓰기)

def initialize

@color = 0 # 객체 내에서 인스턴스 변수에 직접 접근할 수 있다.

@brand = "Penbrand"

@size = 0.7 # 하지만 attr_accessor Class 인스턴스 메서드로 정의된 setter 메서드를 사용할 수도 있다.

end

end

pen = Pen.new

puts pen.brand # 생성된 getter를 통해 펜 브랜드에 접근

pen.size = 0.5 # 생성된 setter를 통해 펜의 size 필드 업데이트

pen.color = ~pen.color

```

위 코드에서 `attr_reader`는 읽기 전용 프로퍼티를, `attr_writer`는 쓰기 전용 프로퍼티를, `attr_accessor`는 읽기/쓰기 프로퍼티를 정의한다. `initialize` 메서드 내에서는 인스턴스 변수에 직접 접근하거나 (`@color`), `attr_accessor`로 정의된 setter 메서드를 사용할 수 있다 (`@size`).[1]

3. 13. Visual Basic

.NET 계열 언어인 Visual Basic .NET은 프로퍼티를 언어 사양으로 지원한다.[1]

Visual Basic .NET의 프로퍼티에 대한 자세한 내용은 하위 섹션을 참고한다.

3. 13. 1. Visual Basic (.NET 2003-2010)

vbnet

Public Class Pen

Private _color As Integer ' Private 필드

Public Property Color() As Integer ' Public 프로퍼티

Get

Return _color

End Get

Set(ByVal value As Integer)

_color = value

End Set

End Property

End Class

```

```vbnet

' Pen 클래스 인스턴스 생성

Dim pen As New Pen()

' 값 설정

pen.Color = 1

' 값 가져오기

Dim color As Int32 = pen.Color

```

`Property` 키워드와 `Get` 및 `Set` 접근자를 사용하여 프로퍼티를 정의한다. `Get` 접근자는 프로퍼티 값을 반환하고, `Set` 접근자는 프로퍼티 값을 설정한다.

3. 13. 2. Visual Basic (.NET 2010)

vbnet

Public Class Pen

Public Property Color() As Integer ' Public 프로퍼티

End Class

```

```vbnet

' Pen 클래스 인스턴스 생성

Dim pen As New Pen()

' 값 설정

pen.Color = 1

' 값 가져오기

Dim color As Int32 = pen.Color

```

VB.NET에서는 위와 같이 `Property` 키워드를 사용하여 프로퍼티를 선언한다. `Color` 프로퍼티는 정수형 값을 저장하고 가져올 수 있다. `pen` 객체를 생성하고 `Color` 프로퍼티를 통해 값을 설정하고 가져오는 예시를 보여준다.

3. 13. 3. Visual Basic 6

vb

' 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

```

```vb

' 접근:

Dim pen As New clsPen

' ...

pen.Color = Not pen.Color

```
설명:

  • `Visual Basic 6`에서는 `Property Get`과 `Property Let` 문을 사용하여 프로퍼티를 정의한다.
  • 위 코드는 `clsPen` 클래스 내에서 `Color` 프로퍼티를 정의하고 사용하는 예시를 보여준다.
  • `m_Color`는 클래스 내부에서 사용되는 private 변수이며, `Color` 프로퍼티를 통해 외부에서 접근 가능하다.
  • `Property Get Color()`는 프로퍼티 값을 읽을 때 사용되며, `m_Color` 값을 반환한다.
  • `Property Let Color(ByVal RHS As Long)`은 프로퍼티 값을 설정할 때 사용되며, 입력받은 값(`RHS`)을 `m_Color`에 저장한다.
  • `pen.Color = Not pen.Color` 코드는 `Color` 프로퍼티의 값을 변경하는 예시이다.

4. 필드의 프로퍼티화

객체 지향 프로그래밍에서 객체 조작의 공통화는 매우 중요한 핵심이다. 클래스가 다른 객체 간에 조작을 공통화하려 할 때, 특정 객체에만 존재하는 필드를 직접 조작하는 처리가 있으면 공통화를 방해하게 된다. 이를 방지하기 위해 객체 지향 프로그래밍에서는 접근자를 사용하지만, 프로퍼티가 존재하지 않는 언어에서는 한 번 공개한 필드를 접근자로 변환하는 것은 필드를 조작하고 있는 모든 부분을 수정해야 하므로 쉽지 않다.

반면 프로퍼티를 가진 언어에서는 소스 코드 호환 범위 내에서 필드에서 접근자로 변경이 매우 쉬워진다. 프로퍼티가 필드와 호환성을 가지므로 필드를 조작했던 부분은 변경할 필요가 없다. 따라서 프로퍼티가 존재하는 언어에서는 우선 필드를 공개하고 필요하면 프로퍼티로 변경하는 방식으로 운용할 수 있다.

필드에 제약을 걸기 쉬운 언어일수록 운용성이 높아진다. 필드를 Const 등으로 수식하여 객체 외부에서는 읽기 전용으로 할 수 있는 언어라면 필드의 쓰기 조작을 신경 쓰지 않고 필드를 읽기 전용 프로퍼티로 변경할 수 있다. Objective-C는 프로퍼티 선언과 필드 선언이 일체화되어 있으며, 가장 단순한 프로퍼티는 파생형에서 재정의 가능 여부를 제외하고는 필드와 다르지 않다.[7] Objective-C와 호환되는 Swift는 저장 방법의 지정 방법이 속성 정의 안에 포함되어[8], 필드와 프로퍼티의 융합이 더 진행되었다.

5. 결론

객체 지향 프로그래밍에서 객체 조작의 공통화는 매우 중요하며 핵심이다. 클래스가 다른 객체 간에 조작을 공통화하려 할 때, 특정 객체에만 존재하는 필드를 직접 조작하는 처리가 있으면 공통화를 방해하게 된다. 이 때문에 객체 지향 프로그래밍에서는 액세서라고 불리는 메서드를 통해 필드를 조작하는 것이 정석이 되었다. 그러나 같은 필드만 조작하는 상태에서 액세서를 정의하는 것은 번거롭다. 또한, 메서드 호출 방식이 필드와 같다면 굳이 필요하지 않을 때 액세서를 준비하지 않아도 된다. 그래서 Object Pascal(델파이)에서 도입된 것이 '''프로퍼티'''이다.

참조

[1] 웹사이트 Accessors And Mutators In Java https://www.c-sharpc[...] 2022-01-05
[2] 웹사이트 Portability of Native C++ properties https://stackoverflo[...] Stack Overflow 2022-01-05
[3] 웹사이트 property (C++) https://docs.microso[...] Microsoft 2022-01-05
[4] 웹사이트 clang::MSPropertyDecl Class Reference https://clang.llvm.o[...] 2022-01-05
[5] 웹사이트 __property Keyword Extension https://docwiki.emba[...] 2022-01-05
[6] 웹사이트 Properties (Delphi) - RAD Studio https://docwiki.emba[...] 2023-10-13
[7] 웹사이트 Declared Properties https://developer.ap[...] 2023-10-13
[8] 웹사이트 Documentation https://docs.swift.o[...] 2023-10-16



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com