class Monster
{
int 체력;
int 공격력;
void 피격을 받다()
{
체력 -= 공격력;
}
void 죽다()
{
체력 <= 0
}
}
class Player // 클래스 캡슐화 : 변수와 함수를 하나로 묶어서 관리
{
// skill : 100줄 -> 책임을 분산
// 인벤토리 : 800줄
// 변수(명사) : 정보
private int level = 1; // private 은 외부에서 접근 불가능, 현재 클래스(Player) 안에서만 사용가능 -> 캡슐화
private int attackPoint = 10;
// 함수(동사) : 행동
public void Attack(Monster monster) // public -> monster 라는 변수를 받아서 사용. 외부에서 사용 가능
{
Console.WriteLine("플레이어가 몬스터를 공격합니다");
monster.TakeHit(attackPoint);
Console.WriteLine("플레이어가 공격을 마칩니다");
}
}
class Monster // 클래스 캡슐화 : 변수와 함수를 하나로 묶어서 관리
{
// 변수(명사) : 정보
private string name;
private int hp; // private 은 외부에서 접근 불가능, 현재 클래스(Monster) 안에서만 사용가능 -> 캡슐화
// 함수(동사) : 행동
public void TakeHit(int attackPoint) // public -> attackPoint 라는 변수를 받아서 사용. 외부에서 사용 가능
{
Console.WriteLine("몬스터가 피격을 받습니다.");
hp -= attackPoint;
Console.WriteLine("몬스터가 현재 채력은 {0} 입니다.", hp);
if (hp <= 0)
{
Die();
}
}
// 함수(동사) : 행동
public void FallDown()
{
Die();
}
// 함수(동사) : 행동
public void Die()
{
Console.WriteLine("죽는 사운드.");
Console.WriteLine("몬스터가 쓰러집니다.");
}
}
static void Main(string[] args)
{
Monster monster = new Monster();
monster.체력 = 100;
monster.공격력 = 10;
monster.피격을 받다();
monster.죽다();
Player player = new Player();
Monster monster = new Monster();
Monster monster2 = new Monster();
Monster monster3 = new Monster();
player.Attack(monster); //player가 monster를 공격
player.Attack(monster); //player가 monster를 공격
}
(0x0000...) ┌─────────────┐
낮은주소 │ 코드 영역 │ → 프로그램 코드
├─────────────┤
│ 데이터 영역 │ → 정적변수
├─────────────┤
│ 힙 영역 │ → 클래스 인스턴스
│............│
│ │
│............│
높은주소 │ 스택 영역 │ → 지역변수, 매개변수
(0xFFFF...) └─────────────┘
│ 메모리영역 │ 접근 범위 │ 생존 범위
─────────┼────────────┼────────────┼───────────────────────────
정적변수 │ 데이터영역 │ 모든 범위 │ 프로그램 시작에서 끝까지
─────────┼────────────┼────────────┼───────────────────────────
지역변수 │ 스택영역 │ 블록 내부 │ 블록 시작에서 끝까지
매개변수 │ │ │
─────────┼────────────┼────────────┼───────────────────────────
클래스 │ 힙영역 │ 참조가능한 │ 인스턴스 생성에서
인스턴스 │ │ 모든 범위 │ 더이상 사용하지 않을때까지
<함수호출스택>
void Stack2(int a)
{
a = 3;
}
void Stack1(int a)
{
a = 2;
Stack2(a);
}
void Main1()
{
int a = 1;
Stack1(a);
}
┌────────────┐ ┌────────────┐ ┌────────────┐
│ │ │ │ │ │
│ │ │ │ ├────────────┤
│ │ │ │ │ Stack2() │
│ │ │ │ │ a = 3 │
│ │ ├────────────┤ ├────────────┤
│ │ │ Stack1() │ │ Stack1() │
│ │ │ a = 2 │ │ a = 2 │
├────────────┤ ├────────────┤ ├────────────┤
│ Main1() │ │ Main1() │ │ Main1() │
│ a = 1 │ │ a = 1 │ │ a = 1 │
Main1 호출 → └────────────┘ Stack1 호출 → └────────────┘ Stack2 호출 → └────────────┘
┌────────────┐ ┌────────────┐ ┌────────────┐
│ │ │ │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
├────────────┤ │ │ │ │
│ Stack1() │ │ │ │ │
│ a = 2 │ │ │ │ │
├────────────┤ ├────────────┤ │ │
│ Main1() │ │ Main1() │ │ │
│ a = 1 │ │ a = 1 │ │ │
Stack2 종료 → └────────────┘ Stack1 종료 → └────────────┘ Main1 종료 → └────────────┘
class HeapClass { }
void Main2()
{
// 함수 시작시
// 지역변수 local 이 스택 영역에 저장됨
HeapClass local; // 함수 시작시 이미 메모리에 할당되어 있음
local = new HeapClass(); // 인스턴스를 힙영역에 생성하고 주소값을 local에 보관
// 함수 종료시
// 지역변수 local 이 함수 종료와 함께 소멸됨
// 인스턴스 new HeapClass() 는 함수 종료와 함께 더이상 참조하는 변수가 없음
// 인스턴스 new HeapClass() 는 가비지가 되어 가비지 컬렉터가 동작할 때 소멸됨
}
┌──────────────┐ ┌──────────────┐
│ │ │ │
│ │ 0x56 ├──────────────┤
│ │ ┌──→│ HeapClass │
│ │ │ │ 인스턴스 │
│ │ │ ├──────────────┤
│ │ │ │ │
│ │ │ │ │
│ │ │ │ │
├──────────────┤ │ ├──────────────┤
| local(null) | └───│ local(0x56) │
함수시작 → └───────────────┘ 인스턴스 생성 → └──────────────┘
┌──────────────┐ ┌──────────────┐
│ │ │ │
├──────────────┤ │ │
더이상 │ HeapClass │ │ │
참조없음 │ 인스턴스 │ │ │
├──────────────┤ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ │
│ │ 가비지 콜렉터 │ │
함수종료 → └───────────────┘ 동작시 → └──────────────┘
class Student
{
public string name;
public int age;
}
struct StudentData
{
public string name;
public int age;
}
static void Main(string[] args)
{
Student student = new Student();
student.name = "김전사";
student.age = 20;
// <구조체와 클래스의 차이>
Student anotherStudent = student; // 같은 인스턴스를 가르킨다
student.age = 80;
Console.WriteLine(student.age); // 80
Console.WriteLine(anotherStudent.age); // 80
StudentData studentData;
studentData.name = "김전사";
studentData.age = 20;
StudentData anotherStudentData = studentData; // 안에 있는 내용물을 복사
studentData.age = 80;
Console.WriteLine(studentData.age); //80
Console.WriteLine(anotherStudentData.age); //20
//클래스는 참조(주소 : 바로가기)
ClassType instance = new ClassType();
ClassType addressCopy = instance; // 주소를 복사해서 같은 인스턴스를 가리킴
}
public class Monster
{
public string name;
public int hp;
public int Level;
✅기본생성자 : 생성자가 하나도 없을 때 자동으로 생성되는 생성자
public Monster()
{
}
✅생성자 오버로딩 : 생성자를 여러개 만들어서 다양한 방법으로 인스턴스를 생성할 수 있음
public Monster()
{
Console.WriteLine("몬스터 생성자.");
name = "몬스터";
hp = 100;
Level = 1;
}
public Monster(string _name)
{
name = _name;
switch(name)
{
case "슬라임":
hp = 100;
Level = 1;
break;
case "오크":
hp = 200;
Level = 3;
break;
case "드래곤":
hp = 500;
Level = 10;
break;
}
}
public Monster(string _name, int _hp, int _Level)
{
Console.WriteLine("몬스터 생성자.");
name = _name;
hp = _hp;
Level = _Level;
}
}
static void Main(string[] args)
{
// 클래스 생성자
Monster monster = new Monster(); // 클래스의 인스턴스가 생성될 때 자동으로 호출되는 메서드
Monster orc = new Monster("오크"); // 생성자 오버로딩
Monster slime = new Monster("슬라임", 100, 3); // 생성자 오버로딩
}

1. 솔루션 탐색기에서 프로젝트 마우스 오른쪽 버튼 클릭
2. 추가 -> 새항목
3. 클래스 이름 변경 후 추가 or 모든 템플릿 표시에서 선택후 추가