본문 바로가기
Game DevTip/C#

3. C# 클래스

by LIKE IT.라이킷 2025. 4. 21.
  • 클래스의 구분
    • 내장형식(built-in Type, 닷넷 프레임 워크)
    • Console, String, math…
    • 사용자 정의 현식(user defined type)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class MyFirstClass
    {
        static void Staticmethod() => Console.WriteLine("[1] 정적메서드");

        void InstaceMethod() => Console.WriteLine("[2] 인스턴스 메서드");

        static void Main()
        {

            //1 정적메서드 호출
            MyFirstClass.Staticmethod(); //클래스 레벨
            //2 인스턴스 메서드 호출(new로 새로운 개체 생성)
            MyFirstClass my = new MyFirstClass();
            my.InstaceMethod();
        }
    }
}

내장 클래스

  • string : 프로그램을 만들 때 가장 많이 사용하는 문자열 처리와 관련한 속성과 메서드를 다양하게 제공
  • StringBuilder - 대용량 문자열 처리와 관련된 속성 및 메서드를 제공.
    • 보통은 string을 사용하여 문자열을 처리함.
    • 큰 규모의 문자열 저장은 위에 스트링 빌더 사용.
    • System.Text 네임 스페이스에 들어있음.
  • Array 클래스 : 배열과 관련한 주요 속성 및 메서드를 제공.

Enviroment 클래스

  • 0을 매개변수로 전달하면 현재 프로그램을 종료하는 클래스.
  • 이 코드 뒤로 아무리 많은 코드가 와도 실행 되지 않음.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class EnvironmentExit
    {
        static void Main()
        {
            Console.WriteLine("출력됩니다.");
            Environment.Exit(0);
            Console.WriteLine("출력될까요?"); //되겠냐 ㅋ
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class EnvironmentDemo
    {
        static void Main()
        {
            Console.WriteLine(Environment.SystemDirectory); // 시스템폴더
            Console.WriteLine(Environment.Version); // 닷넷기준버전
            Console.WriteLine(Environment.OSVersion); // 운영체제 버전
            Console.WriteLine(Environment.MachineName); // 컴퓨터명
            Console.WriteLine(Environment.UserName); // 사용자명
            Console.WriteLine(Environment.CurrentDirectory); // 현재 폴더
            string docs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            Console.WriteLine(docs); // 문서 폴더
        }
    }
}

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class EnvironmentDemo
    {
        static void Main()
        {
            // 메모장 실행
            Process.Start("Notepad.exe");

            // 웹 브라우저를 열고 매개 변수로 URL을 절달
            Process.Start("Explorer.exe", "<https://ck.ac.kr>");
        }

    }
}
  • 기존 파일 실행가능 및 Enviroment 클래스의 여러가지 속성을 사용해서 환경변수를 출력.

random 함수

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class RandomDemo
    {
        static void Main()
        {
            Random random = new Random();

            Console.WriteLine(random.Next()); //임의의 정수
            Console.WriteLine(random.Next(5)); //0~4까지
            Console.WriteLine(random.Next(1, 10)); //1~10까지
        }
    }
}

가위바위보 게임

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Diagnostics.Eventing.Reader;
using System.Globalization;
using System.Linq;
using System.Runtime.ConstrainedExecution;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp3
{
    class Program
    {
        static void Print_RockPaperScissors(string PlayerName, int InNumber)
        {
            if (InNumber == 1)
            {
                Console.WriteLine($"{PlayerName} : 가위");
            }
            else if (InNumber == 2)
            {
                Console.WriteLine($"{PlayerName} : 바위");
            }
            else if (InNumber == 3)
            {
                Console.WriteLine($"{PlayerName} : 보");
            }
        }

        static void Print_Result(int player, int CPU)
        {
            if(player == 1)
            {
                if(CPU == 1)
                    Console.WriteLine("비김");
                else if(CPU == 2)
                    Console.WriteLine("짐");
                else
                    Console.WriteLine("이김");
            }
            else if(player == 2)
            {
                if (CPU == 1)
                    Console.WriteLine("이김");
                else if (CPU == 2)
                    Console.WriteLine("비김");
                else
                    Console.WriteLine("짐");
            }
            else
            {
                if (CPU == 1)
                    Console.WriteLine("짐");
                else if (CPU == 2)
                    Console.WriteLine("이김");
                else
                    Console.WriteLine("비김");
            }
        }

        static void Main(string[] args)
        {
            int PlayerNum;
            Random random = new Random();
            int Cpu = random.Next(1, 3);

            Console.Write("1(가위), 2(바위), 3(보) 입력 : ");
            PlayerNum = int.Parse(Console.ReadLine());

            Program.Print_RockPaperScissors("사용자", PlayerNum);
            Program.Print_RockPaperScissors("컴퓨터", Cpu);

            Program.Print_Result(PlayerNum, Cpu);
        }
    }
}

Stopwatch 클래스

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            Stopwatch timer = new Stopwatch();
            timer.Start();
            Thread.Sleep(3000);
            timer.Stop();

            Console.WriteLine("경과시간 {0}밀리초", timer.Elapsed.TotalMilliseconds);
            Console.WriteLine("경과시간: {0}초", timer.Elapsed.Seconds);
            
        }
    }
}

패턴 매칭

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main()
        {
            PrintStarts(null);
            PrintStarts("하나");
            PrintStarts(5);
        }
        
        static void PrintStarts(object o)
        {
            if(o is null)
            {
                return; //null.제외
            }
            if(o is string)
            {
                return; //문자열 제외
            }
            if(!(o is int number))
            {
                return;//패턴 매칭 : 넘어온 값이 정수 형식이면 int number = o;
                //정수형 이외 값 제외
            }
            Console.WriteLine(new String('*', number));
        }
    }

}

개체 만들기

  • class 키워드로 작성 → 클래스
  • 클래스를 new 키워드를 생성 → 개체
  • 클래스로 만든 개체들은 서로 다른 인스턴스(instance)
  • 여러가지 용어 - 개체 객체, 오브젝트, 인스턴스

인스턴스 메서드

  • 인스턴스 메서드를 호출하려면 클래스의 인스턴스가 필요함.
class MyMath
{
    public void Sum(int x, int y) //인스턴스 메서드
    {
        int sum = x + y;
        Console.WriteLine($"합계 : {sum}");
    }
   
}

public class ClassMethod
{
    public static void Main()
    {
        MyMath myMath = new MyMath(); //MyMath 클래스의 인스턴스
        myMath.Sum(3, 5);//개체, 인스턴스메서드 이름 형태로 호출
    }
}

익명형식

  • 클래스를 선언하지 않고 개체를 만드는 방법
  • 특정 클래스 없이 이름 하나로 여러 속성을 모아서 관리.
  • 각 데이터 형식은 자동으로 유추해서 만들어짐.
  • (IsPrint ←true로 초기화, bool 형식이 됨.
  public class ObjectDemo
  {
      static void Main()
      {
          var hong = new { Name = "홍길동", Age = 21 };
          var park = new { Name = "박문수", Age = 30 };

          Console.WriteLine($"이름 : {hong.Name}, 나이 : {hong.Age}");
          Console.WriteLine($"이름 : {park.Name}, 나이 : {park.Age}");

      }
  }

ToString() 메서드 오버라이드

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class My { }
    class your 
    {
        public override string ToString()
        {
            return "새로운 반환 문자열 지정";
        }
    }

    class ToStringMethod
    {
        static void Main()
        {
            My my = new My();
            Console.WriteLine(my); 
            //My 개체를 출력하면 기본은 클래스 이름이 출력

            your your = new your();
            Console.WriteLine(your);
            //새로운 반환 문자열 지정
        }
    }

}

 

 

 

클래스 배열

  • 사용자 정의 클래스도 데이터 형식의 하나이므로 배열처럼 사용가능.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public class CategoryClass
    {
        public void Print(int i) => Console.WriteLine($"카테고리 {i}");
    }
    class ClassArray
    {
        static void Main()
        {
            CategoryClass[] categories = new CategoryClass[3]; // 클래스 배열 생성
                                                               // 각 인스턴스 생성
            categories[0] = new CategoryClass();
            categories[1] = new CategoryClass();
            categories[2] = new CategoryClass();

            for (int i = 0; i < categories.Length; i++)
            {
                categories[i].Print(i);
            }
        }
    }
}

 

 

Var 키워드로 개체 생성

  • 클래스 생성구문을 참고로 클래스를 유추해서 개체를 생성.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public class ExamClass { }
    class InstanceWithVar
    {
        static void Main()
        {
            //[1] 클래스를 사용하기 위해 인스턴스 생성
            ExamClass exam1 = new ExamClass(); // 기본 방식
            Console.WriteLine($"{exam1}"); 
            
            //[2] var 키워드를 사용하여 인스턴스 생성
            var exam2 = new ExamClass(); // 축약 방식
            Console.WriteLine($"{exam2}");
        }
    }
}

필드

  • 클래스 내에서 선언된 변수 도는 배열등
  • 클래스의 부품역할을 하며, 대부분 private 액세스 한정자(access modifier)가 붙고
  • 클래스 내에서 데이터를 담는 그릇 역할 을 함
  • 개체 상태 (state)를 보관.
  • 선언한 후 초기화 하지 않아도 자동으로 초기화 함
    • int 형 필드 : 0
    • string 형 필드 : String.Empty,(공백)
  • 변수 선언시 메서드 내부 또는 메서드 밖에(메서드와 동등한 레벨)선언할 수 있음.
  • 메서드 내에서 선언된 변수 또는 배열 - 지역 변수(local variable)
  • 메서드 밖에서 선언된 변수 - 전역 변수(global variable)
  • 다만 C#에서는 전역 변수라는 용어를 사용하지 않고 메서드와 동일하게 엑세스 한정자를 붙여 필드라고 함.
  • 지역 변수
    • 변수는 main() 메서드가 종료되면 자동으로 소멸.
    • 변수가 살아있는 영역은 Main() 메서드의 중괄호 시작과 끝 사이.
    • 특정 지역을 범위로 하기에 변수를 일반적으로 지역변수라고 함.
  • 전역별수 (필드)
    • 메서드가 아닌 클래스 내의 선언된 변수를 필드라고 함.
    • C#에서 필드는 변수와 마찬가지로 주로 소문자 또는 언더스코어(_)로 시작함.
    • 이러한 필드는 메서드 내에 선언된 지역 변수와 달리 전역 변수라고 함.

필드 예제

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public class ExamClass { }
    class VariableScope
    {
        static string globalVariable = "전역 변수"; // 필드 또는 멤버 변수
        static void Main()
        {
            string localVariable = "지역 변수";
            Console.WriteLine(localVariable); // "지역 변수:
            Console.WriteLine(globalVariable); // "전역 변수"
            Test();
        }

        static void Test() => Console.WriteLine(globalVariable); // "전역 변수
    }
}
  • 변수(variable) : 지역 변수와 마찬가지로 값을 대입하여 사용할수있음
  • 상수(constant) : 필드(변수)와 비슷하지만 한 번 값을 초기화한 후에는 다시 값을 재설정할수없음(선언할때초기화)
  • 읽기전용(readonly) : readonly 키워드 사용. 상수와 비슷. (생성자로 초기화)
  • 배열(array) : 값을 여러 개 보관
  • 기타, 개체(object) : 기타 필드에는 모든 데이터 형식이 올 수 있음

엑세스 한정자

  • public : 모든 곳에서 접근가능
  • private : 현재 클래스 내에서만 접근
  • protected : 현재 클래스 또는 자식클래스에서만 접근이 허가.
  • internal : 같은 어셈블리의 모든 클래스에 접근 허가(프로젝트 내부 전용)
  • protected inernal : 현재 어셈블리 또는 다른 어셈블리에서 파생된 클래스에 엑세스 허가.

참고로 defaul는 private이다.

  • 다른 클래스에서 필드에 접근하게 하려면 public
  • 같은 클래스 내에서만사 용하려면 private
  • 필드는 주로 클래스/개체의 부품 역할을 하며 임시적으로 데이터를 보관해놓음
  • 필드에는 public 키워드를 붙이지 않는것이 좋은 습관
  • 필드 내용을 외부에 공개할 때는 public 메서드 또는 뒤에서 배울 속성을 사용

생성자

  • 개체를 생성하면서 무엇인가를 하고자 할때 사용하는 메서드
  • 개체를 초기화(주로 클래스 내 필드를 초기화)하는데 사용됨.
  • 생성자 규칙 → 생성자 이름이 클래스 이름과 동일
  • 클래스 내에서 클래스 이름과 동일한 이름을 갖는 메서드는 모두 생성자
  • 매개변수가 없는 기본(default) 생성자와, 매개변수가 있는 생성자
  • static 생성자(정적 생성자)와 public 생성자(인스턴스 생성자)로 구분
  • 반환값은 가지지 않음.
  • 매개변수를 달리하여 생성자를 여러개 만들수도 있음(생성자 오버로딩)
  • this 키워드를 사용해서 다른 생성자 호출 가능.

this 생성자 사용 예제

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Player
    {
        private string _name = "홍길동";
        private int _level = 999;
        public Player() => Console.WriteLine($"name: {this._name}, level: {this._level}");
        public Player(string name, int level) : this()
        {
            this._name = name; // this.필드 = 매개변수
            this._level = level;
        }
        public void PrintPlayer()
        {
            Console.WriteLine($"name: {this._name}, level: {this._level}");
        }
    }
    class ConstructorParameter
    {
        static void Main()
        {
            Player player1 = new Player("이순신", 21);
            player1.PrintPlayer();
        }
    }
}

static 생성자 예제

using ConsoleApp1;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public class Player
    {
        private static readonly string _Name;
        private int _Level;
        static Player() { _Name = "홍길동"; }
        public Player() { _Level = 21; } //[2] 인스턴스 생성자
        public Player(int Level)
        { //[3] 인스턴스 생성자 (매개변수)
            this._Level = Level; // this.필드 = 매개변수;
        }

        public static void Show()
        { // 정적 메서드
            Console.WriteLine("name : {0}", _Name);
        }
        public void Print()
        { // 인스턴스 메서드
            Console.WriteLine("level : {0}", _Level);
        }
    }
    class ConstructorAll
    {
         static void Main()
        {
             // 정적 생성자 실행
             Player.Show(); // 정적인 멤버 호출//
             // 인스턴스 생성자 실행
            (new Player()).Print(); // 인스턴스 멤버 호출
            (new Player(22)).Print();
        }
    }
}

 

소멸자

  • 가급적 종료자를 사용하지 말것을 권장.
  • 가비지 컬렉터가 언제 동작할 지 예측 못함.
    • 객체의 사용이 끝난 직후가 될 수도, 10분 후가 될 수도 있다.
    • 중요한 자원을 종료자에서 해제하도록 하면 자원이 부족해질수도
  • 명시적으로 종료자를 구현하면, 가비지 컬렉터가 object로 부터 상속 받은 Finalize()
    • 메소드를 클래스으 족보를 타고 올라가며 호출
    • 대개의 경우 응용프로그램의 성능 저하만 가져올 확률 높음.
    • CLR의 가비지 컬렉터는 객체으 소멸을 스마트하게 처리함.
반응형

'Game DevTip > C#' 카테고리의 다른 글

4. C# 인터페이스 및 추상클래스 ,다형성  (0) 2025.04.21
2. C# 배열, 함수, 델리게이트  (0) 2025.04.21
1. C# 기초  (0) 2025.04.21

댓글