4. 캡슐화 - 프로퍼티

1. 참고자료
1. 영상 링크
https://youtu.be/zgeCwYWzK-k?si=rJFngC_y71cOcVSm
2. 용어 체크리스트
맴버,
필드: 프로퍼티의 실제 값
프로퍼티: 객체의 상태 값
캡슐화,
접근제어자,
어트리뷰트,
유효성
2. Member(멤버) vs Field(필드) vs Property(전통적 프로퍼티) vs Property(자동완성 프로퍼티)
1. Member(멤버)
C/C++ 로 프로그래밍을 입문하는 경우
C# Class 내부의 변수와 함수를 멤버라고 C++에서 사용하는 맴버라는 용어로 지칭하는 경우가 많다.
손쉬운 구분을 위해, 맴버는 클래스에 사용하고, 필드와 프로퍼티는 객체에 사용한다.
2. Field(필드) vs Property(전통적 프로퍼티)
public class Class { private int _field; // 필드(클래스, 구조체 내부에 선언된 변수) public int Property // 프로퍼티(클래스 외부에서 필드에 접근시 사용) { get { return _field; // 필드 값 리턴 } set { _field = value; // 필드 값 할당 } } }
3. Property(자동완성 프로퍼티)
→ C# 3.0 자동 구현 프로퍼티(Auto Implemented Property)는 필드와 거의 동일하게 보인다.
내부적으로는 Property(전통적 프로퍼티)와 동일하게 동작한다.
public class Class { public int Property { get; set; } // 프로퍼티 }
3. Field(필드) vs Property(프로퍼티)
1. Field(필드) vs Property(프로퍼티), 무엇을 사용해야 하는가?
- Field(필드)는
- 객체 내부에서 단순한 값(Data)을 저장하는 기능 역할일 때 사용한다.
- Property(프로퍼티)는
- 객체 외부에서 내부의 Field에 접근할 때, 일반적으로 유효성 검증 및 제어를 수행한다.
그렇기에, 객체 외부에서 접근 가능 값(Data)은 전부 프로퍼티로 구현한다. - OOP의 기본 원칙 - 캡슐화, 데이터 은닉
- 객체 외부에서 내부의 Field에 접근할 때, 일반적으로 유효성 검증 및 제어를 수행한다.
2. 유효성 검증이란?
→ Class를 설계한 사람의 의도에 맞게, 메소드를 통해서만 필드에 접근하도록 한다.
class Person { private int age; // ❗ private: 클래스 외부에서 직접 접근 불가 (캡슐화) // ✅ Setter: 유효한 값만 설정 가능하도록 제어 public void SetAge(int newAge) { if (newAge >= 0 && newAge <= 120) age = newAge; else Console.WriteLine("⚠️ 유효하지 않은 나이입니다."); } }
3. Property(프로퍼티) 확장성
- *Field로 구현 불가능한 기능
- 디버깅 중단점
(변수처럼 사용하지만, 실제 메서드로 동작한다) - 인터페이스에 정의
- 상속 및 오버라이드
- 리블렉션
- 데이터 바인딩
- 디버깅 중단점
4. OOP - 캡슐화를 통한 정보은닉과 private field, property
OOP가 등장한 근본적인 이유는, 기존 프로그래밍 방식인 절차지향이 가지는 데이터 접근에 대한 문제점이다.
이를 객체를 캡슐화시키고, 클래스 내부의 데이터를 은닉하기 위한 private 접근 제어자를 사용한다.
5. 기타
프로퍼티의 이름은 대문자로,
필드의 이름은 소문자로 그리고, 객체 내부에서 사용되므로 _언더바를 붙인다.
4. private + Getter/Setter vs Property
1. private 필드 + Getter/Setter 예제
- private 접근 제어자를 사용해 캡슐화를 구현
- 내부 데이터를 보호하면서도 안전하게 외부와 통신하기 위한 Getter/Setter 메서드 구현
- 클래스의 데이터를 외부 클래스로부터 보호, 의도치 않은 기능을 수행 차단, 각 객체의 데이터 오염을 방지
using System; class Person { private int age; // ❗ private: 클래스 외부에서 직접 접근 불가 (캡슐화) // ✅ Getter: 나이 값을 읽을 수 있도록 제공 public int GetAge() { return age; } // ✅ Setter: 유효한 값만 설정 가능하도록 제어 public void SetAge(int newAge) { if (newAge >= 0 && newAge <= 120) age = newAge; else Console.WriteLine("⚠️ 유효하지 않은 나이입니다."); } } class Program { static void Main() { Person p = new Person(); // 나이 설정 (setter 사용) p.SetAge(25); // 정상 설정 Console.WriteLine(p.GetAge()); // 25 출력 p.SetAge(-5); // 유효하지 않은 값 Console.WriteLine(p.GetAge()); // 여전히 25 } }
*핵심 요약
구성 | 요소역할 |
private int age; | 외부에서 직접 접근을 차단 (캡슐화 핵심) |
SetAge() | 값을 설정할 때 유효성 검사 수행 |
GetAge() | 값을 안전하게 외부에 제공 |
2. Property 사용 버전
using System; class Person { private int age; // ❗ private 필드 (속성 내부에서 사용됨) // ✅ 속성 Property: 외부에서 get/set으로 접근 가능 public int Age { get => age; // Getter: 나이 조회 set { if (value >= 0 && value <= 120) age = value; else Console.WriteLine("⚠️ 유효하지 않은 나이입니다."); } } } class Program { static void Main() { Person p = new Person(); p.Age = 25; // set 호출 (정상 값) Console.WriteLine(p.Age); // get 호출 → 25 출력 p.Age = -10; // set 호출 (유효성 검사) Console.WriteLine(p.Age); // 여전히 25 출력 } }
3. 비교, 내부 데이터를 외부로 내보낼 때 (Getter 역할)
- 외부에서는 필드를 할당하는 것처럼 사용하지만, 내부에서는 값을 계산하거나 가공한 후 제공 가능
// Getter 메서드 방식: int age = person.GetAge(); // 코드상 메서드처럼 보임
// Property 방식: int age = person.Age; // 마치 필드처럼 보임 → 직관적
4. 비교, 외부 데이터를 내부로 가져올 때 (Setter 역할)
- 외부에서는 필드를 할당하는 것처럼 사용하지만, 내부에서는 유효성 검사, 로깅, 이벤트 처리 등이 가능
// Setter 메서드 방식: person.SetAge(25); // 메서드처럼 보임
// Property 방식: person.Age = 25; // 필드처럼 보임 → 간결하고 직관적
5. 차이점 정리
항목 | Getter/Setter 메서드 방식 | C# 속성(Property) 방식 |
호출 방식 | GetAge(), SetAge(value) | Age, Age = value |
문법 복잡도 | 비교적 길고 전통적인 방식 | 간결하고 직관적인 문법 |
C# 스타일 | 전통적인 객체지향 스타일 | C#에서 권장하는 접근 방식 |
유효성 검사 포함 가능 | 가능 | 가능 (속성 내부에서 처리 가능) |
5. 프로퍼티 (Property) 요약
1. 클래스 내부 private 필드를 클래스 외부에서 public 필드처럼 사용하도록 도와주는 특수한 멤버(Member)
class Person { private int age; // 실제 데이터는 감춰져 있음 (캡슐화) public int Age // 속성(Property)으로 안전하게 접근 제공 { get => age; set { if (value >= 0) age = value; } } }
person.Age = 25; // 내부 유효성 검사 자동 수행 Console.WriteLine(person.Age); // 내부 값을 안전하게 반환
2. 목적
클래스 내부에서 private 필드의 사용은
객체 지향 프로그래밍(OOP)의 캡슐화(Encapsulation)를 구현하는 핵심 요소 입니다.
프로퍼티는
클래스 외부에서 public 필드처럼 사용하도록 도와주는 특수한 멤버(Member)입니다.
내부에서는 Getter/Setter 메서드로 동작하지만, 외부에서 사용할 때 변수처럼 보임
→ 사용성과 캡슐화의 절묘한 균형
프로퍼티를 이용하는 이유 결론부터 말해 객체 무결성 보장을 위해서입니다.
C# 필드(Field) vs. 프로퍼티(Property) 차이 비교
6. 참고(1)
Getter/Setter가 비대해지는 예시 (Java)
public class Employee { private String name; private int age; private String department; private double salary; private String address; private String phoneNumber; private String email; private String position; private String employeeId; // Getter/Setter for name public String getName() { return name; } public void setName(String name) { this.name = name; } // Getter/Setter for age public int getAge() { return age; } public void setAge(int age) { this.age = age; } // Getter/Setter for department public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } // Getter/Setter for salary public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } // ... 이하 나머지 멤버 변수들에 대한 Getter/Setter 반복 // 총 9개의 필드 → 최소 18개의 메소드 추가됨 }
자동 구현 프로퍼티라 해도 필드가 많아지면 클래스 크기가 커지고 구조가 복잡해짐
public class Employee { public string Name { get; set; } public int Age { get; set; } public string Department { get; set; } public double Salary { get; set; } public string Address { get; set; } public string PhoneNumber { get; set; } public string Email { get; set; } public string Position { get; set; } public string EmployeeId { get; set; } // 클래스의 목적은 단순한 데이터 저장임에도 // 수많은 프로퍼티가 존재하면서 클래스가 비대해짐 }
전통적인 프로퍼티 (Traditional Property)
[C#] Public Field vs Auto-Implemented Property :: 맴매레인저
프로퍼티 - 1 (구현과 사용법, 자동구현 프로퍼티, 프로퍼티와 생성자, 무명형식)
[C#] 속성 (Property) (2) — 나는야 프로그래머
무명,
객체 초기화 코드
+ 캡슐화 프로퍼티
1. 접근제한자와 필
[c# 기초] c# 접근 제한자(Access modifier) / private, protected, public
[c#] 프로퍼티(property)란? - 사용 이유/ 사용법
C# 필드(Field) vs. 프로퍼티(Property) 차이 비교
[c# ] 필드 | 프러퍼티 앞에 붙어 있는 required는 뭘까?
댓글을 사용할 수 없습니다.