게임 개발_HISTORY

C# STUDY_TIL251008 [클래스 기초 문제 풀이, 제너릭] 본문

Development In Unity/Study : C#

C# STUDY_TIL251008 [클래스 기초 문제 풀이, 제너릭]

EVANJ 2025. 10. 8. 10:28

📝 학습 요약

  • 클래스 객체 기초 문제 풀어보기
  • 제너릭

🧩 학습 내용

✔️ 클래스 객체 기초 문제 풀어보기

 

🎯 아래 조건에 맞는 Car 클래스를 만든다.

  • 자동차의 brand(브랜드), color(색상)를 저장하는 필드를 가진다.
  • ShowInfo() 메서드를 만들어 “이 자동차는 [색상] [브랜드]입니다.”를 출력한다.
  • Main() 메서드에서 객체를 생성하고 ShowInfo()를 호출한다.

🏹 나의 풀이

    class Car()
    {
        public string brand;
        public string color;
        public void ShowInfo()
        {
            Console.WriteLine("이 자동차는" + color + brand + "입니다.");
        }
    }
    internal class Program
    {
        static void Main()
        {
            Car myCar = new Car();

            myCar.brand = "현대";
            myCar.color = "빨간색";
            myCar.ShowInfo();
        }
    }

 

🎯 학생의 이름과 나이를 저장하는 Student 클래스를 만들기

  • 생성자를 이용해 name과 age를 초기화한다.
  • PrintInfo() 메서드로 “이름: [name], 나이: [age]”를 출력한다.
  • Main()에서 두 명의 학생 객체를 생성하고 각각의 정보를 출력한다.

🏹 나의 풀이

 class Student
 {
     public string name;
     public int age;
     public Student(string name, int age)
     {
         this.name = name;
         this.age = age;
     }
     public void PrintInfo()
     {
         Console.WriteLine("이름 : " + name + ", 나이 : " + age);
     }
 }
 internal class Program
 {
     static void Main()
     {
         Student student1 = new Student("민수", 20);
         Student student2 = new Student("지연", 22);

         student1.PrintInfo();
         student2.PrintInfo();
     }
 }

 

🎯 Animal 클래스를 만들고, 이를 상속받는 Dog 클래스를 정의한다.

  • Animal 클래스에는 Speak() 메서드가 있고 “동물이 소리를 냅니다.”를 출력한다.
  • Dog 클래스에서는 Speak()를 재정의(override)하여 “멍멍!”을 출력한다.
  • Main()에서 두 클래스를 각각 호출하여 결과를 비교한다.

🏹 나의 풀이

  class Animal
  {
      public virtual void Speak()
      {
          Console.WriteLine("동물이 소리를 냅니다.");
      }
  }
  class Dog : Animal
  {
      public override void Speak()
      {
          Console.WriteLine("멍멍!");
      }
  }
  internal class Program
  {
      static void Main()
      {
          Animal A = new Animal();
          Dog B = new Dog();

          A.Speak();
          B.Speak();
      }
  }

 

🎯 Shape 클래스를 만들고, Circle과 Rectangle 클래스를 각각 상속받게 한다.

  • Shape에는 Draw()라는 메서드가 있다.
  • Circle과 Rectangle 클래스는 Draw()를 오버라이드하여 각각 “원을 그립니다.”, “사각형을 그립니다.”를 출력한다.
  • Main()에서 Shape 타입의 리스트(List)를 만들어 Circle, Rectangle 객체를 담고 반복문으로 Draw()를 호출한다.

🏹 나의 풀이

using System;
using System.Collections.Generic;

class Shape
{
    public virtual void Draw()
    {
        Console.WriteLine("도형을 그립니다.");
    }
}
class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("원을 그립니다.");
    }
}
class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("사각형을 그립니다.");
    }
}
internal class Program
{
    static void Main()
    {
        List<Shape> shapes = new List<Shape>();
        shapes.Add(new Circle());
        shapes.Add(new Rectangle());
        foreach (Shape s in shapes)
        {
            s.Draw();
        }
    }
}

여기서 리스트 관련 문법은 익숙하지 않아 이해하고 풀어내는것이 어려웠다. 이부분은 아직도 내 머릿속에 담기지 않아 몇일 더 반복 학습이 필요해 보인다.

 

✔️ 제너릭

데이터 형식(Type)을 일반화 해서 재사용성을 높이는 문법이다. 개념을 "자료형이 정해지지 않은 틀(설계도)"로 이해할 수도 있다.

보통 클래스를 만들 때 미리 데이터 형식을 쓴다. 예를 들어 int만 저장하는 리스트라면 

class IntBox
{
    public int Data;
}

위와 같이 만들 것이다. 그런데 string을 저장하려면 이에 따른 자료형 클래스를 따로 만들어야 하는데 이런 형식별 중복을 피하기 위해 제너릭을 이용한다.

제너릭은 클래스, 구조체, 인터페이스, 메서드 등 여러 곳에 적용할 수 있다.

class Box<T>
{
    public T Data; // T는 '아직 정해지지 않은 타입'을 의미
}

여기서 T는 Type의 약자로, 나중에 사용할 때 구체적인 형식으로 바꿔준다.

Box<int> intBox = new Box<int>();
intBox.Data = 123;

Box<string> strBox = new Box<string>();
strBox.Data = "Hello";

Console.WriteLine(intBox.Data);  // 출력: 123
Console.WriteLine(strBox.Data);  // 출력: Hello

T는 사용할 때 int, string, float 등 원하는 타입으로 지정할 수 있다.

▫️제너릭의 장점

장점 설명
형식 안정성(Type Safety) 잘못된 자료형을 넣을 수 없다.(컴파일 시점에 오류를 잡기 때문)
성능 향상 boxing/unboxing 없이 바로 값 형식을 다룸
재사용성 한 번 만든 제너릭 클래스를 여러 타입에서 재활용 가능

 

▫️가장 자주 쓰이는 제너릭 클래스

  • List<T>
  • Dictionary<TKey, TValue>
  • Queue<T>
  • Stack<T>