반응형

열거(Enums)

열거(Enum)는 상수(변경 불가능한 변수)의 그룹을 정의할 때 사용하는 특별한 “클래스”다. 게임 개발에서 로직을 구현할 때도 자주 사용된다. 예를 들어 난이도 설정, 게임 상태 등을 구현할 때 사용된다. 예시1은 난이도 설정에 대한 간단한 로직이다.

예시1:

class Program
{
  enum Level
  {
    Low,
    Medium,
    High
  }
  static void Main(string[] args)
  {
    Level myVar = Level.Medium;
    Console.WriteLine(myVar);
  }
}

// 출력 : Medium
// 출처 : w3schools

열거형에는 값도 설정할 수 있다

문자열의 인덱스 값과 마찬가지로 열거형도 첫 번째 항목의 값은 0으로 시작한다. 한 가지 신경써야 하는 점은 정수값을 얻기 위해서 명시적 변환이 필요하다는 점이다.

예시2:

enum Months
{
  January,    // 0
  February,   // 1
  March,      // 2
  April,      // 3
  May,        // 4
  June,       // 5
  July        // 6
}

static void Main(string[] args)
{
  int myNum = (int) Months.April; // int로 명시적 변환
  Console.WriteLine(myNum);
}

// 출력 : 3
// 출처 : w3schools

또한 열거형 값을 임의로 할당할 수 도 있다.

예시3:

enum Months
{
  January,    // 0
  February,   // 1
  March=6,    // 6
  April,      // 7
  May,        // 8
  June,       // 9
  July        // 10
}

static void Main(string[] args)
{
  int myNum = (int) Months.April;
  Console.WriteLine(myNum);
}

// 출력 : 7
// 출처 : w3schools

예시3에서 March의 값을 6으로 변경해주었다. 그 뒤의 값들도 순차적으로 변화하는 것을 확인할 수 있다. 변경된 값만 바뀌는 것이 아니라 그 뒤의 값들도 오름차순으로 값이 바뀐다는 점을 유의하자.

열거형과 Switch

열거형은 스위치 문과 함께 자주 사용된다고 한다.

enum Level 
{
  Low,
  Medium,
  High
}

static void Main(string[] args) 
{
  Level myVar = Level.Medium;
  switch(myVar) 
  {
    case Level.Low:
      Console.WriteLine("Low level");
      break;
    case Level.Medium:
       Console.WriteLine("Medium level");
      break;
    case Level.High:
      Console.WriteLine("High level");
      break;
  }
}

// 출력 : Medium level

요약정리

  1. 열거형은 변하지 않는 값(상수)들의 그룹을 정의할 때 사용하는 특수 클래스다.
  2. 열거형의 항목들은 0부터 시작하는 값을 가지고 있으며, 별도로 설정할 수 도 있다.
반응형
반응형

인터페이스(Interfaces)는 무엇인가?

인터페이스는 C#에서 추상화를 구현하는 또 다른 방법이다. 어떤 클래스가 어떤 메서드들을 가져야 하는지를 정의하는 일종의 규칙이라고 할 수 있다.

 

추상 클래스, 추상 메서드에 대해서는 아래 포스트에 자세히 정리해 두었으니 참고하자.

 

2024.04.23 - [C# 기초] - [C#기초] 추상(abstract) 클래스와 메서드

 

[C#기초] 추상(abstract) 클래스와 메서드

추상화(Abstract)란 무엇인가? 추상화는 특정 정보는 숨기고, 필수 정보만 사용자에게 표시하는 프로세스이다. 추상화는 클래스나 인터페이스를 사용하여 구현할 수 있다. 클래스 또는 메서드를

bigchoiiistudio.tistory.com

인터페이스의 특징은 선언부에 메서드 구현을 포함하지 않는다는 것이다. 단지 메서드의 이름, 매개변수, 반환값의 형식 등을 정의한다.

예시1:

// interface
interface IAnimal
{
  void animalSound(); // interface method (does not have a body)
  void run(); // interface method (does not have a body)
}

// 코드 출처 : w3schools
  • 인터페이스의 이름은 시작 부분에 문자 ‘I’로 시작하는 것이 일반적이다. 클래스와 인터페이스를 구분하기 위함이다.

인터페이스 사용 방법

인터페이스를 구현하는 방법은 클래스가 클래스를 상속할 때와 같이 ‘:’ 기호를 사용한다.

예시2:

// 인터페이스
interface IAnimal
{
  void animalSound(); // 인터페이스 메서드
}

// Pig "implements" the IAnimal interface
class Pig : IAnimal
{
  public void animalSound()
  {
    // The body of animalSound() is provided here
    Console.WriteLine("The pig says: wee wee");
  }
}

class Program
{
  static void Main(string[] args)
  {
    Pig myPig = new Pig();  // Create a Pig object
    myPig.animalSound();
  }
}

// 코드 출처 : w3schools

인터페이스의 특징

인터페이스에 정의해 놓은 메서드는 구현부에서 반드시 재정의 해야 한다. 예시2에서는 IAnimal 인터페이스에 animalSound 메서드가 정의되었다.

 

이를 Pig 클래스에서 구현할 때 animalSound 메서드를 재정의해주었다. 추상화는 추상 클래스 내에 정의된 메서드 외에도 이를 상속받은 클래스에서 새로운 메서드나 변수 등을 선언할 수 있었지만, 인터페이스는 불가능하다.

 

인터페이스는 기존에 정의된 속성과 메서드 외에는 추가할 수 없다.

예시3:

// 추상화(Abstraction) 예제

// 추상 클래스인 Animal
abstract class Animal
{
    // 추상 메서드 MakeSound 정의
    public abstract void MakeSound();
}

// Animal을 상속받은 Dog 클래스 (살)
class Dog : Animal
{
    // MakeSound 메서드 구현
    public override void MakeSound()
    {
        Console.WriteLine("멍멍!");
    }

    // Dog 클래스의 특정한 기능과 속성
    public void WagTail()
    {
        Console.WriteLine("꼬리를 흔들며 행복해요!");
    }
}

// Animal을 상속받은 Cat 클래스 (장기)
class Cat : Animal
{
    // MakeSound 메서드 구현
    public override void MakeSound()
    {
        Console.WriteLine("야옹!");
    }

    // Cat 클래스의 특정한 기능과 속성
    public void Purr()
    {
        Console.WriteLine("산소온거니까 편안해요.");
    }
}

// 인터페이스(Interface) 예제
interface IShape
{
    void Draw();
}

class Rectangle : IShape
{
    public void Draw()
    {
        Console.WriteLine("사각형을 그립니다.");
    }
}

class Circle : IShape
{
    public void Draw()
    {
        Console.WriteLine("원을 그립니다.");
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 추상화 예제
        Animal dog = new Dog();
        dog.MakeSound(); // "멍멍!" 출력
        dog.WagTail();

        Animal cat = new Cat();
        cat.MakeSound(); // "야옹~" 출력
        cat.Purr();

        // 인터페이스 예제
        IShape rectangle = new Rectangle();
        rectangle.Draw(); // "사각형을 그립니다." 출력

        IShape circle = new Circle();
        circle.Draw(); // "원을 그립니다." 출력
    }
}

또한 인터페이스는 여러 개를 한 번에 구현할 수 있다. 예시4를 살펴보자. IFirstInterface와 ISecondInterface를 선언했고, DemoClass는 이 두 인터페이스를 모두 구현했다. 이를 다중 인터페이스라고 한다. 구현은 ,기호로 구분하여한다.

 

예시4:

interface IFirstInterface 
{
  void myMethod(); // interface method
}

interface ISecondInterface 
{
  void myOtherMethod(); // interface method
}

// Implement multiple interfaces
class DemoClass : IFirstInterface, ISecondInterface 
{
  public void myMethod() 
  {
    Console.WriteLine("Some text..");
  }
  public void myOtherMethod() 
  {
    Console.WriteLine("Some other text...");
  }
}

class Program 
{
  static void Main(string[] args)
  {
    DemoClass myObj = new DemoClass();
    myObj.myMethod();
    myObj.myOtherMethod();
  }
}

다중 인터페이스를 사용하는 이유는 C#이라는 언어가 클래스의 다중 상속을 지원하지 않기 때문이다.

요약정리

  1. 인터페이스는 추상화를 구현하는 또 다른 방법이며, 어떤 클래스가 어떤 메서드를 가져야 하는지 정의하는 일종의 규칙이다.
  2. 추상 클래스와 마찬가지로 직접적으로 객체 생성을 할 수 없다.
  3. 인터페이스의 선언부의 메서드에는 구현을 포함하지 않는다.
  4. 인터페이스 구현 시 해당 메서드를 반드시 재정의해야 한다.
  5. 인터페이스에는 속성과 메서드가 포함될 수 있으나 필드/변수는 포함 될 수 없다.
  6. 인터페이스 멤버는 기본적으로 abstractpublic이다.
  7. 인터페이스는 생성자를 포함할 수 없다.
반응형
반응형

추상화(Abstract)란 무엇인가?

추상화는 특정 정보는 숨기고, 필수 정보만 사용자에게 표시하는 프로세스이다. 추상화는 클래스나 인터페이스를 사용하여 구현할 수 있다. 클래스 또는 메서드를 선언할 때 abstract 키워드를 사용하면 된다.

 

추상화를 거쳐 추상 클래스 또는 추상 메서드가 되면 직접적인 접근이 제한되고, 상속에 의해서만 접근할 수 있다.

추상 클래스와 메서드

  • 추상 클래스 : 객체를 생성하는 데 사용할 수 없다. 접근을 위해서는 상속되어야 한다.
  • 추상 메서드 : 추상 메서드가 포함된 추상 클래스에서만 사용가능하며, 추상 클래스를 상속받은 자식 클래스(파생 클래스)에서 접근할 수 있다.

추상 클래스는 왜 사용되는가?

추상 클래스를 뼈에 비유해보자. 뼈는 동물의 기본 구조를 정의한다. 이와 마찬 가지로 추상 클래스는 하위 클래스들이 공유할 수 있는 기본적인 특성을 정의하는데 사용된다. 예시1을 살펴보자.

예시1:

using System;

// 추상 클래스인 Animal
abstract class Animal
{
    // 추상 메서드 MakeSound 정의
    public abstract void MakeSound();
}

// Animal을 상속받은 Dog 클래스 (살)
class Dog : Animal
{
    // MakeSound 메서드 구현
    public override void MakeSound()
    {
        Console.WriteLine("멍멍!");
    }

    // Dog 클래스의 특정한 기능과 속성
    public void WagTail()
    {
        Console.WriteLine("꼬리를 흔들며 행복해요!");
    }
}

// Animal을 상속받은 Cat 클래스 (장기)
class Cat : Animal
{
    // MakeSound 메서드 구현
    public override void MakeSound()
    {
        Console.WriteLine("야옹!");
    }

    // Cat 클래스의 특정한 기능과 속성
    public void Purr()
    {
        Console.WriteLine("편안해요.");
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Dog 클래스의 인스턴스 생성
        Dog myDog = new Dog();
        Console.WriteLine("Dog이 소리를 냅니다:");
        myDog.MakeSound(); // Dog의 MakeSound 메서드 호출
        myDog.WagTail(); // Dog의 WagTail 메서드 호출

        Console.WriteLine();

        // Cat 클래스의 인스턴스 생성
        Cat myCat = new Cat();
        Console.WriteLine("Cat이 소리를 냅니다:");
        myCat.MakeSound(); // Cat의 MakeSound 메서드 호출
        myCat.Purr(); // Cat의 Purr 메서드 호출
    }
}

예시1에서는 Animal이 ‘뼈 역할’을 하고, 이를 상속받아 구체적인 동물 클래스들이 살이나 장기 역할을 한다고 보면 된다. 추상 클래스인 Animal에는 공통적인 동작인 MakeSound 메서드가 정의되어 있다.

 

다시 한번 정리하자면 추상 클래스는 하위 클래스들에게 상속할 ‘공통된 특성’을 정의한다. 이를 상속받은 Dog, Cat 클래스 등은 각각 저마다의 특성과 행동을 정의한다. 이런 식으로 호랑이, 염소 등 동물의 공통된 특징(예시1에서는 울음소리)을 상속받고, 각 클래스에 맞게 확장하고, 구체화하는 것이 가능해진다.

다형성과의 추상화

예시1에서 Cat 클래스와 Dog 클래스 내에 override 키워드가 사용된 것을 알 수 있다. 이전 포스트에서 다형성에 대해 이야기했는데, 다형성 역시 상속을 기반으로 한다. 다형성에 대한 자세한 설명은 아래 포스트를 참고하자.

2024.04.23 - [C# 기초] - [C#기초] 상속(Inheritance)과 다형성(Polymorphism)

 

추상화와 다형성은 객체지향 프로그래밍에서 매우 밀접한 관련이 있는 개념이라고 한다. 코드의 재사용성 측면에서 둘 다 좋은 효율을 보여주는 거 같다.

 

추상화가 공통된 특성을 정의하는 것이라면, 다형성은 이를 바탕으로 하위 클래스들이 동일한 이름의 메서드를 사용할 수 있게 해 준다. 예시1에서는 MakeSound라는 메서드를 오버라이딩하여 모든 클래스에서 같은 이름으로 사용하고 있다.

반응형

+ Recent posts