📚 Chapter 1.6: 클래스와 구조체 완전 정복
✅ 이 챕터에서 배울 것
"class랑 struct 둘 다 비슷하게 생겼는데 뭐가 다른데?"
"힙? 스택? 값 형식? 참조 형식?"
→ 헷갈리는 개념을 예제 + 메모리 구조로 딱! 정리한다
- class와 struct의 정의 및 차이
- 힙(heap)과 스택(stack) 메모리 구조
- 복사 방식 차이 (값 복사 vs 참조 복사)
- 실무에서 어느 상황에 뭘 써야 하는지
🧱 클래스(class)란?
참조 형식(Reference Type)
힙 메모리에 저장되고,
변수는 객체 주소(참조)를 저장한다!
class Person
{
public string Name;
public int Age;
}
🧱 구조체(struct)란?
값 형식(Value Type)
스택 메모리에 직접 값이 저장된다!
struct Point
{
public int X;
public int Y;
}
🧪 예제: 값 형식과 참조 형식의 차이
// 클래스는 참조형
Person a = new Person { Name = "철수", Age = 20 };
Person b = a; // b는 a와 같은 객체를 가리킴
b.Name = "영희"; // a.Name도 바뀜!
Console.WriteLine(a.Name); // 결과: "영희"
// 구조체는 값형
Point p1 = new Point { X = 1, Y = 2 };
Point p2 = p1; // 값 복사 (새 객체)
p2.X = 100;
Console.WriteLine(p1.X); // 결과: 1 (안 바뀜!)
✅ 구조체는 완전한 복사본 생성
클래스는 주소만 복사하기 때문에 원본이 같이 바뀐다!
🔍 힙과 스택 개념 요약
구분 | 스택(Stack) | 힙(Heap) |
저장 위치 | 값 형식 저장 | 참조 형식 저장 |
접근 속도 | 빠름 | 느림 (주소 따라가야 함) |
자동 해제 | 스코프 벗어나면 자동 해제 | GC(Garbage Collector)가 관리 |
예시 | int, float, struct | class, string, 배열 등 |
⚠️ struct 사용 시 주의사항
항목 | 주의점 |
값 복사 | 무거운 데이터일수록 복사 부담 커짐 |
상속 불가 | 구조체는 상속 못 받는다! |
매개변수 전달 시 | 큰 구조체는 ref 키워드 고려 |
기본 생성자 X | C# 10 이전엔 매개변수 없는 생성자 정의 불가 |
💡 실무에서 어떤 걸 써야 할까?
조건 | 추천 타입 |
데이터 양 적고, 빠르게 처리 | struct |
복잡한 기능 / 동작 필요 | class |
동등 비교 (==) 간편히 하고 싶을 때 | struct |
상속이 필요한 경우 | 무조건 class |
🎯 struct vs class 비교 요약
항목 | class | struct |
형식 | 참조형 | 값형 |
저장 위치 | 힙 | 스택 |
복사 방식 | 참조 복사 | 값 복사 |
상속 | 가능 | ❌ 불가능 |
생성자 | 사용자 정의 가능 | 기본 생성자 제한 있음 |
속도 | GC 영향 받음 | 상대적으로 빠름 (작을 경우) |
✅ 장선생의 실전 꿀팁
- Point, Color, Rectangle 같은 단순 좌표/값 덩어리는 struct로 좋다!
- Person, Order, Product 등 동작/기능 중심 객체는 class가 정석
- struct는 필드 수가 3~4개 이하, 불변(immutable) 형태일 때 가장 효율적이다
✅ 요약 정리
구분 | 핵심 요약 |
class | 참조형, 힙, 상속 가능, 복잡한 객체 설계 |
struct | 값형, 스택, 상속 불가, 가볍고 빠름 |
복사 방식 | class는 참조 복사, struct는 값 복사 |
📘 Chapter 1.6.1: 접근 제한자 완전 정복
✅ 이 챕터에서 배울 것
클래스 만들다 보면 앞에 public, private, internal, protected 요런 거 붙어있더라?
대체 언제 뭘 써야 하는데??
→ 이걸 제대로 알아야 객체지향 설계의 '은닉성'을 챙길 수 있다!
- C#에서 사용되는 5가지 접근 제한자
- 각 제한자의 범위와 쓰임새
- 실무에서 어떤 조합으로 쓰는지
- 클래스, 필드, 메서드에서 각각 적용되는 방식
🔐 접근 제한자란?
클래스, 메서드, 필드 등의 접근 허용 범위를 지정하는 키워드
👉 코드의 보안성, 재사용성, 캡슐화에 중요한 역할
🔍 C#의 접근 제한자 종류
키워드 | 접근 범위 | 주로 사용 위치 |
public | 모든 곳에서 접근 가능 | 클래스, 메서드, 속성 등 |
private | 해당 클래스 내부에서만 | 필드, 메서드 |
protected | 자신 + 상속받은 클래스에서만 | 상속 구조에서 멤버 공유 |
internal | 같은 프로젝트(어셈블리) 내 | 라이브러리 구조에서 자주 사용 |
protected internal | 같은 프로젝트 + 상속 클래스 | 복합 제한자 |
🧪 예제 1: 필드와 메서드에서 접근 제한자 비교
public class Person
{
public string Name; // 어디서든 접근 가능
private int age; // 클래스 내부에서만 접근 가능
protected string Secret = "비밀"; // 상속 클래스만 접근 가능
internal string Project = "내부 프로젝트"; // 같은 프로젝트면 접근 가능
public void SetAge(int value)
{
age = value;
}
public int GetAge()
{
return age;
}
}
🔍 예제 2: 상속과 protected
public class Parent
{
protected string familySecret = "유전적 비밀";
}
public class Child : Parent
{
public void RevealSecret()
{
Console.WriteLine(familySecret); // 접근 가능!
}
}
✅ protected는 외부에서는 못 보지만,
상속받은 클래스에선 "우리끼리 공유" 느낌!
🧠 실무 기준 요약
멤버 종류 | 기본 접근 제한자 | 추천 제한자 |
클래스 | internal | 대부분 public (라이브러리 제외) |
필드 | private | 항상 private → 속성 통해 노출 |
속성 | public | 캡슐화해서 getter/setter 제공 |
메서드 | private/public | 필요 따라 구분 |
💡 속성과 private 필드 조합 (실무 기본패턴)
public class Product
{
private int price;
public int Price
{
get { return price; }
set
{
if (value > 0)
price = value;
}
}
}
✅ 이렇게 해서 유효성 검사 + 정보 보호를 동시에!
💥 장선생의 실전 꿀팁
- 필드는 웬만하면 무조건 private로! → 속성으로 노출
- internal은 프로젝트 분리 구조에서 유용
- protected는 상속 없으면 외부 접근 불가
- protected internal은 라이브러리 설계 시 고려
✅ 요약 정리
제한자 | 설명 | 접근 가능 위치 |
public | 완전 공개 | 어디서나 |
private | 클래스 내부 전용 | 해당 클래스만 |
protected | 상속자 전용 | 자식 클래스만 |
internal | 프로젝트 전용 | 같은 어셈블리 내 |
protected internal | 내부 + 상속 | 같은 어셈블리 or 자식 클래스 |
📘 다음 챕터 예고 🎓
Chapter 1.7: static vs instance – 메모리 구조와 클래스 설계 차이
static은 언제 쓰고, 인스턴스는 언제 만들어야 하는지!
메모리 구조 + 설계 관점까지 확실하게 정리해준다!