3월 24일 #객체지향 #클래스 #생성

sejun-Lee·2025년 3월 24일

<캡슐화>

  • 절차적으로 순서를 신경써서 제작하는 프로그래밍 기법 대신, 객체 단위로 만들어서 상호작용으로 구현하는 기법
  • 객체를 정보와 기능으로 묶는 것을 의미
  • 객체의 내부 정보와 기능을 숨기고, 허용한 기능만 외부에 노출시키는 것을 의미

✅객체(Object) : 개념

  • 몬스터란? -> 체력, 공격력, 경험치, 아이템 드랍 등을 가지고 있는 개념

✅클래스(Class) : 설계도

  • 객체를 만들기 위한 설계도 ( 정보 + 행동 )
        class Monster
        {
            int 체력;
            int 공격력;
            void 피격을 받다()
            {
                체력 -= 공격력;
            }
            void 죽다()
            {
                체력 <= 0
            }
        }

✅인스턴스(Instance) : 설계도를 바탕으로 만들어진 실제 사물 ( 실체화 결과물 )

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를 공격
}

✅<메모리 (Memory)>

  • 프로그램을 처리하기 위해 필요한 정보를 저장하는 기억장치
  • 프로그램은 메모리에 저장한 정보를 토대로 명령들을 수행함

✅메모리구조

  • 프로그램은 효율적인 메모리 관리를 위해 메모리 영역을 구분
  • 데이터는 각 역할마다 저장되는 영역을 달리하여 접근범위, 생존범위 등을 관리

✅<메모리 구조>

       (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)

  • 데이터와 관련 기능을 캡슐화할 수 있는 참조 형식
  • 객체지향 프로그래밍에 객체를 만들기 위한 설계도
  • 클래스는 객체를 만들기 위한 설계도이며, 만들어진 객체는 인스턴스라 함
  • 참조 : 원본을 가리키고 있음 == 원본의 주소를 가지고 있음

<값형식, 참조형식>

✅값형식 (Value type) :

  • 복사할 때 실제값이 복사됨 (깊은 복사)
  • 구조체는 값형식

✅참조형식 (Reference type) :

  • 복사할 때 객체주소가 복사됨 (얕은 복사)
  • 클래스는 참조형식

✅<값형식과 참조형식의 차이>

  • 값형식 : 데이터가 중요한 경우 사용, 값이 복사됨
  • 참조형식 : 객체가 중요한 경우 사용, 객체주소가 복사됨
       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;

✅<클래스 생성자>

  • 반환형이 없는 클래스이름의 함수를 생성자라 하며 클래스의 인스턴스를 만들 때 호출되는 역할로 사용
  • 인스턴스의 생성자는 new 키워드를 통해서 사용

✅기본생성자 : 생성자가 하나도 없을 때 자동으로 생성되는 생성자

    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 모든 템플릿 표시에서 선택후 추가

profile
초보 개발자

0개의 댓글