프로그래밍/C#

[C#] 클래스(Class) 두번째 시간

gameObject 2023. 6. 13. 02:23
728x90

클래스 특징

1. 캡슐화

- 캡슐화는 클래스 안의 필드를 private 또는 protected로 외부에서 접근하지 못하도록 처리하는것을 말한다.

 

2. 상속

- 부모 클래스와 자식 클래스를 만들어서 부모 클래스에 정의된 필드와 메서드를 자식 클래스에서 사용할 수 있도록 처리하는것을 의미한다.

 

* 부모 클래스 = 슈퍼클래스, 부모클래스, 베이스 클래스 라고도 불린다.

* 자식 클래스 = 서브클래스, 자식 클래스, 파생 클래스 라고도 불린다.

 

3. 다형성

- 메서드가 동일한 이름으로 다양한 기능을 수행할 수 있도록 처리하는것을 의미한다.

 

4. 추상화

- 클래스를 정의할 때, 공통된 필드와 메서드를 부모 클래스로 정의해서 중복사용을 줄이는 것을 의미한다.

 

사용예시

가장 아래쪽 예제에 몬스터를 3가지 종류로 준비해 보았다.

 

고블린, 슬라임, 드래곤

각각을 클래스로 정의했으며 아래 내용들이 중복된다.

private string name;
private int hp;
private int mp;
private int damage;
private int defence;
private string monsterType;

public Goblin(string name_, int hp_, int mp_, int damage_, int defence_, string monsterType_)
{
name = name_;
hp = hp_;
mp = mp_;
damage = damage_;
defence = defence_;
monsterType = monsterType_;
}

public void print_MonsterInfo()
{
Console.WriteLine("몬스터 이름: {0}, Hp: {1}, Mp: {2}, Damage: {3}, Defence: {4}, Type: {5}", name,hp,mp,damage,defence,monsterType);
}

여기서 private 키워드를 볼 수 있는데, 이것이 캡슐화이다.

클래스 내에서는 해당 변수들을 이용가능하지만 Main함수에서는 해당변수 호출이 안된다.

 

세가지 몬스터 중에 드래곤만 상속을 시켜보았다. 상속은 아래 내용이다.

먼저 드래곤 보다 더 위에 몬스터들의 공통 베이스 클래스를 만들어준다.

(즉, 고블린이나 슬라임도 이 클래스를 부모클래스로 받을 수 있음_ 이번 경우에는 차이점을 알기 위해 부모클래스를 받지않았다.)

using System;
namespace csharp_practice
{
	public class MonsterBase
	{
        protected string name;
        protected int hp;
        protected int mp;
        protected int damage;
        protected int defence;
        protected string monsterType;

        public virtual void Initilize(string name_, int hp_, int mp_, int damage_, int defence_, string monsterType_)
        {
            name = name_;
            hp = hp_;
            mp = mp_;
            damage = damage_;
            defence = defence_;
            monsterType = monsterType_;
        }

        public virtual void print_MonsterInfo()
        {
            Console.WriteLine("몬스터 이름: {0}, Hp: {1}, Mp: {2}, Damage: {3}, Defence: {4}, Type: {5}", name, hp, mp, damage, defence, monsterType);
        }

    }
}

아까 보이던 Private와 다르게 이번에는 Protected가 눈에 보인다.

Protected는 상속된 개체에서는 변수를 Call할 수 있도록 만들어주고, 그 이외에는 캡슐화되어 접근이 불가하다.

 

그 다음 포인트는 바로 클래스 명이다.

 public class Dragon : MonsterBase

이렇게 클래스 명 뒤에 : MonsterBase를 써주면 MonsterBase를 부모클래스로써 상속받겠다는 의미가 된다.

 

상속을 받게되면 부모클래스가 갖고있는 변수, 함수까지 전부 받을 수 있게 되는데 이때 오버라이딩을 쓸 수 있다.

 

// 부모클래스에서 virtual키워드를 통해 일반 함수를 적어준다.

public virtual void Initilize(string name_, int hp_, int mp_, int damage_, int defence_, string monsterType_){}

// 자식클래스에서는 override 키워드를 통해 상속을 받아 준다.

public override void Initilize(string name_, int hp_, int mp_, int damage_, int defence_, string monsterType_)
        {
            base.Initilize(name_, hp_, mp_, damage_, defence_, monsterType_);
        }

위와 같은 방식을 이용하면 공통된 사항들에 대해서는 다시 정의해줄 필요가 없어지게 된다.(이것이 추상화이다.)

다시 정의해 줄 필요가 없으니, 많은 사람들이 작성해도 균일하게 수정이 가능하게되므로 유지보수성이 높아진다.

 

 

전체예제

 

// 클래스 작성 실습
// 본인이 만들고 싶은 몬스터 클래스 3개 만들 것.
// 몬스터 이름 , HP, Mp, damage, defence, monster type
// 위에 정의된 값을 출력하는 함수를 클래스 내부에 구현할 것

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

namespace csharp_practice
{
    public class Program
    {
        static void Main(string[] args) // static함수와 static함수가 아닌 함수를 부르는 순서가 달라서 static함수 내에서는 static함수만 써야한다.
        {
           
            
            Goblin babyGoblin = new Goblin("애기고블린",10,10,1,5,"고블린");
            Slim babySlim = new Slim("애기슬라임", 5, 5, 1, 1, "슬라임");

            //Dragon babyDragon = new Dragon("애기드래곤",50,50,10,50,"드래곤"); // 상속 적용전
            Dragon babyDragon = new Dragon(); // 상속 적용시
            babyDragon.Initilize("애기드래곤", 50, 50, 10, 50, "드래곤"); //상속 적용시

            babyGoblin.print_MonsterInfo();
            babyDragon.print_MonsterInfo();
            babySlim.print_MonsterInfo();

        }//Main()
    }// class Program
}
using System;
using static System.Net.Mime.MediaTypeNames;
using System.Xml.Linq;

namespace csharp_practice
{
	public class Goblin
	{
		private string name;
		private int hp;
		private int mp;
		private int damage;
		private int defence;
		private string monsterType;

		public Goblin(string name_, int hp_, int mp_, int damage_, int defence_, string monsterType_)
		{
			name = name_;
			hp = hp_;
			mp = mp_;
			damage = damage_;
			defence = defence_;
			monsterType = monsterType_;
		}

		public void print_MonsterInfo()
		{
			Console.WriteLine("몬스터 이름: {0}, Hp: {1}, Mp: {2}, Damage: {3}, Defence: {4}, Type: {5}", name,hp,mp,damage,defence,monsterType);
		}
	}

	public class Slim
	{

		private string name = "애기슬라임";
		private int hp = 10;
		private int mp = 10;
		private int damage = 10;
		private int defence = 10 ;
		private string monsterType = "슬라임1";
		
		public Slim(string name_, int hp_, int mp_, int damage_, int defence_, string monsterType_)
		{
			name = name_;
			hp = hp_;
			mp = mp_;
			damage = damage_;
			defence = defence_;
			monsterType = monsterType_;
		}
		
		public void print_MonsterInfo()
		{
			Console.WriteLine("몬스터 이름: {0}, Hp: {1}, Mp: {2}, Damage: {3}, Defence: {4}, Type: {5}", name, hp, mp, damage, defence, monsterType);
		}
	}

    public class Dragon : MonsterBase
    {
        /* 상속받지 않을때 사용하는 변수 단 부모의 변수가 propected가 되어있어야함
        private string name;
        private int hp;
        private int mp;
        private int damage;
        private int defence;
        private string monsterType;
		*/

        /* 오버라이딩 사용하지 않을 때 사용하는 함수
        public void Initilize(string name_, int hp_, int mp_, int damage_, int defence_, string monsterType_)
        {
            name = name_;
            hp = hp_;
            mp = mp_;
            damage = damage_;
            defence = defence_;
            monsterType = monsterType_;
        }*/
        public override void Initilize(string name_, int hp_, int mp_, int damage_, int defence_, string monsterType_)
        {
            base.Initilize(name_, hp_, mp_, damage_, defence_, monsterType_);
        }

        /* 상속받지 않을때 사용하는 생성자
        public Dragon(string name_, int hp_, int mp_, int damage_, int defence_, string monsterType_)
        {
            name = name_;
            hp = hp_;
            mp = mp_;
            damage = damage_;
            defence = defence_;
            monsterType = monsterType_;
        }
		*/

        /* //상속받지 않을때 사용하는 함수
        public void print_MonsterInfo()
        {
            Console.WriteLine("몬스터 이름: {0}, Hp: {1}, Mp: {2}, Damage: {3}, Defence: {4}, Type: {5}", name, hp, mp, damage, defence, monsterType);
        }
		*/

        public override void print_MonsterInfo()
        {
            base.print_MonsterInfo();
        }
    }

}
using System;
namespace csharp_practice
{
	public class MonsterBase
	{
        // 캡슐화 -> 필드로 private 로 처리해서 외부에서 접근 불가능하도록 하겠다는 의미.
        // protected 는 상속받은 자식 클래스에서는 쓸 수 있도록 하겠다는 뜻 
        protected string name;
        protected int hp;
        protected int mp;
        protected int damage;
        protected int defence;
        protected string monsterType;

        /* 오버라이딩을 사용하지 않을 때 사용하는 함수
        public void Initilize(string name_, int hp_, int mp_, int damage_, int defence_, string monsterType_)
        {
            name = name_;
            hp = hp_;
            mp = mp_;
            damage = damage_;
            defence = defence_;
            monsterType = monsterType_;
        }
        */

        // 오버라이드 사용방법 _ 부모에서는 virtual 이용
        public virtual void Initilize(string name_, int hp_, int mp_, int damage_, int defence_, string monsterType_)
        {
            name = name_;
            hp = hp_;
            mp = mp_;
            damage = damage_;
            defence = defence_;
            monsterType = monsterType_;
        }

        /* 오버라이딩을 사용하지 않을 때 사용하는 함수
        public void print_MonsterInfo()
        {
            Console.WriteLine("몬스터 이름: {0}, Hp: {1}, Mp: {2}, Damage: {3}, Defence: {4}, Type: {5}", name, hp, mp, damage, defence, monsterType);
        }
        */
        public virtual void print_MonsterInfo()
        {
            Console.WriteLine("몬스터 이름: {0}, Hp: {1}, Mp: {2}, Damage: {3}, Defence: {4}, Type: {5}", name, hp, mp, damage, defence, monsterType);
        }

    }
}

 

728x90