[C#] 인터페이스, 열거형, 예외처리와 참조형

고현규·2023년 11월 13일

오늘 배운 내용

1. 인터페이스
2. 열거형
3. 예외처리
4. 값형과 참조형(박싱 언박싱)

1. 인터페이스

인터페이스를 사용하는 이유

  • 코드의 재사용성
    서로 다른 클래스에서 동일한 기능을 이용할 수 있다. 코드의 재사용성이 향상된다.
  • 다중 상속 제공
    C#의 클래스는 다중 상속이 불가능하지만, 인터페이스는 다중 상속이 제공된다.
  • 유연한 설계
    클래스와 인터페이스간의 느슨한 결합을 형성할 수 있다.
    클래스 내부 구현 변경없이 유연한 유지보수가 가능하다.

인터페이스 특징

  • 클래스가 정의해야할 멤버들을 정의한다. 클래스에 대한 제약 조건을 명시한다.
  • 인터페이스를 상속받은 클래스는 클래스 내부에서 해당 내용을 정의해야 한다.

인터페이스 구현

인터페이스 및 멤버 정의하기 
interface IMyInterface
{
    void Method1();
    int Method2(string str);
}
인터페이스 구현하기 
class MyClass : IMyInterface
{
    public void Method1()
    {
        // 구현
    }

    public int Method2(string str)
    {
        // 구현
        return 0;
    }
}

2. 열거형

사용하는 이유

  • 가독성
    연관된 일련의 상수를 명명하여 편하게 사용한다.
  • 자기 문서화
    열겨형으로 의미 있는 이름을 사용하여 가독성을 향상시킨다.
  • 스위치문과의 호환성
    다양한 분기에 활용할 수 있다.

열거형 정의

enum MyEnum
{
    Value1,
    Value2,
    Value3
}
// 열거형 사용
MyEnum myEnum = MyEnum.Value1;

스위치문과의 사용

switch(enumValue)
{
    case MyEnum.Value1:
        // Value1에 대한 처리
        break;
    case MyEnum.Value2:
        // Value2에 대한 처리
        break;
    case MyEnum.Value3:
        // Value3에 대한 처리
        break;
    default:
        // 기본 처리
        break;
}

3. 예외처리

예외처리를 사용하는 이유

  • 예기지 않는 오류 상황에 대처하기 위하 사용한다.
  • 안정성을 높이고 디버깅을 용이하게 한다.

예외처리 구현

try
{
    // 예외가 발생할 수 있는 코드
}
catch (ExceptionType1 ex)
{
    // ExceptionType1에 해당하는 예외 처리
}
catch (ExceptionType2 ex)
{
    // ExceptionType2에 해당하는 예외 처리
}
finally
{
    // 예외 발생 여부와 상관없이 항상 실행되는 코드
}

예제 1

try
{
    int result = 10 / 0;  // ArithmeticException 발생
    Console.WriteLine("결과: " + result);
}
catch (DivideByZeroException ex)
{
    Console.WriteLine("0으로 나눌 수 없습니다.");
}
catch (Exception ex)
{
    Console.WriteLine("예외가 발생했습니다: " + ex.Message);
}
finally
{
    Console.WriteLine("finally 블록이 실행되었습니다.");
}

예제 2

// 플레이어 이동
try
{
    // 플레이어 이동 코드
    if (IsPlayerCollidingWithWall())
    {
        throw new CollisionException("플레이어가 벽에 충돌했습니다!");
    }
}
catch (CollisionException ex)
{
    // 충돌 예외 처리
    Debug.Log(ex.Message);
    // 예외에 대한 추가 처리
}


// 리소스 로딩
try
{
    // 리소스 로딩 코드
    LoadResource("image.png");
}
catch (ResourceNotFoundException ex)
{
    // 리소스가 없는 경우 예외 처리
    Debug.Log(ex.Message);
    // 예외에 대한 추가 처리
}
catch (ResourceLoadException ex)
{
    // 리소스 로딩 중 오류가 발생한 경우 예외 처리
    Debug.Log(ex.Message);
    // 예외에 대한 추가 처리
}


// 게임 상태 전이
try
{
    // 상태 전이 코드
    if (currentGameState != GameState.Playing)
    {
        throw new InvalidStateException("게임이 실행 중이 아닙니다!");
    }
    // 게임 상태 전이 실행
}
catch (InvalidStateException ex)
{
    // 상태 예외 처리
    Debug.Log(ex.Message);
    // 예외에 대한 추가 처리
}

4. 값형과 참조형(박싱 언박싱)

값형

  • 변수에 값을 직접 지정한다.
  • 값이 복사되고 다른 변수에 영향을 주지 않는다.
struct MyStruct
{
    public int Value;
}

MyStruct struct1 = new MyStruct();
struct1.Value = 10;

MyStruct struct2 = struct1; // struct2는 struct1의 값 복사

struct2.Value = 20;

Console.WriteLine(struct1.Value); // 출력 결과: 10

참조형

  • 참조 메모리 주소를 저장하고 변수를 생성(할당)하면 해당 주소를 가르킨다.
  • 해당 참조형 변수를 다른 변수에 할당하면 참조(주소값)가 복사된다.
  • 클래스, 배열, 인터페이스가 이에 해당한다.
class MyClass
{
    public int Value;
}

MyClass obj1 = new MyClass();
obj1.Value = 10;

MyClass obj2 = obj1; // obj2는 obj1과 동일한 객체를 참조

obj2.Value = 20;

Console.WriteLine(obj1.Value); // 출력 결과: 20

박싱과 언박싱

  • 박싱값형 -> 참조형 으로 변환하는 과정이다.
    값형 변수의 값을 메모리의 힙 영역에 할당하여 참조형의 특징을 갖게된다.

  • 언박싱참조형 -> 값형 으로 다시 변환하는 과정이다.
    박싱된 객체에서 값을 추출하여 값형 변수에 할당한다.

사용 예제

박싱 그리고 언박싱
using System;

class Program
{
    static void Main()
    {
        // 값형
        int x = 10;
        int y = x;
        y = 20;
        Console.WriteLine("x: " + x); // 출력 결과: 10
        Console.WriteLine("y: " + y); // 출력 결과: 20

        // 참조형
        int[] arr1 = new int[] { 1, 2, 3 };
        int[] arr2 = arr1;
        arr2[0] = 4;
        Console.WriteLine("arr1[0]: " + arr1[0]); // 출력 결과: 4
        Console.WriteLine("arr2[0]: " + arr2[0]); // 출력 결과: 4

        // 박싱과 언박싱
        int num1 = 10;
        object obj = num1; // 박싱
        int num2 = (int)obj; // 언박싱
        Console.WriteLine("num1: " + num1); // 출력 결과: 10
        Console.WriteLine("num2: " + num2); // 출력 결과: 10
    }
}
리스트 활용 예제
List<object> myList = new List<object>();

// 박싱: 값 형식을 참조 형식으로 변환하여 리스트에 추가
int intValue = 10;
myList.Add(intValue); // int를 object로 박싱하여 추가

float floatValue = 3.14f;
myList.Add(floatValue); // float를 object로 박싱하여 추가

// 언박싱: 참조 형식을 값 형식으로 변환하여 사용
int value1 = (int)myList[0]; // object를 int로 언박싱
float value2 = (float)myList[1]; // object를 float로 언박싱
profile
게임 개발과 기획

0개의 댓글