[C#] 5. OOP 상속(inheritance) & base 키워드

반응형
반응형

#5 OOP 상속(inheritance) & base

 

[목차]

  • 1. 상속 이란?
  • 2. base() 로 부모의 생성자 특정하기
  • 3. base 로 부모의 요소 가져다 쓰기

* 개인적인 공부 기록용으로 작성한 글이기에 잘못된 내용이 있을 수 있습니다.


#1 상속 이란?

상속객체지향(OOP)의 3대 요소중 하나로, 매우 중요한 개념입니다. 상속에 대하여 예시를 통해 알아 보도록 하겠습니다.

RPG 게임에서 아래와 같은 Knight(기사) 클래스가 존재한다고 가정해 봅시다. 

    class Knight
    {
        public int hp;
        public int mp;
        public int atk;
        public int def;

        public void Attack()
        {
            Console.WriteLine("Attack!");
        }

        public void Move()
        {
            Console.WriteLine("Move!");
        }
    }

그런데 만약 Mage(마법사), Archor(궁수) 클래스를 업데이트 해야 한다면 각각 hp, mp, atk(공격력), def(방어력), Attack(), Move() 등을 아래 처럼 하나하나 다 재정의 해주어야 할 것입니다.

    class Mage
    {
        public int hp;
        public int mp;
        public int atk;
        public int def;

        public void Attack()
        {
            Console.WriteLine("Attack!");
        }

        public void Move()
        {
            Console.WriteLine("Move!");
        }
    }

    class Archor
    {
        public int hp;
        public int mp;
        public int atk;
        public int def;

        public void Attack()
        {
            Console.WriteLine("Attack!");
        }

        public void Move()
        {
            Console.WriteLine("Move!");
        }
    }

직업이 겨우 3개이기에 망정이지 넥슨에서 운영하는 메이플스토리(Maplestory) 게임은 직업의 개수만 40여개가 넘어갑니다. 더하여 몬스터 클래스를 제작할 경우에는 몇백가지의 속성들을 타이핑 해야만 합니다.

이러한 비효율적인 작업을 해결하기 위해 객체지향(OOP) 프로그래밍에서는 상속이라는 기능을 제공합니다.

상속은 부모클래스와 자식 클래스로 나뉘며, 자식 클래스는 부모 클래스의 모든 기능(함수,변수 등등)을 상속 받아서 사용이 가능합니다.

저는 Player라는 부모 클래스에 모든 기능을 넣은 뒤 , 자식 클래스 (Knight , Mage , Archor) 들에게 부모의 기능을 상속 시켰습니다. 상속을 받는 방법자식 클래스 이름 오른쪽에 콜론(:)과 함께 부모 클래스의 이름을 적어 주면 됩니다.

    class Player 
    {
        public int hp;
        public int mp;
        public int atk;
        public int def;

        public void Attack()
        {
            Console.WriteLine("Attack!");
        }

        public void Move()
        {
            Console.WriteLine("Move!");
        }
    }
    class Knight : Player
    {

    }

    class Mage : Player
    {

    }

    class Archor : Player
    {

    }

한 눈에 보기에도 코드가 매우 간결해 졌습니다. 그리고 만약 자식클래스 만의 필드를 정의하고 싶다면, 자식클래스 안에 기능들을 정의해 주면 됩니다. (단, 부모 클래스는 자식 클래스의 기능을 상속받지 못합니다.)


#2 base()로 부모의 생성자 특정하기

생성자의 호출 순서부모 -> 자식 순서입니다. 예시로 아래처럼 Knight(기사) 자식 클래스 객체를 생성해 보도록 하겠습니다.

namespace TextRpg
{

    class Player 
    {
        public int hp;
        public int mp;
        public int atk;
        public int def;

        public void Attack()
        {
            Console.WriteLine("Attack!");
        }

        public void Move()
        {
            Console.WriteLine("Move!");
        }

        public Player()
        {
            hp = 100;
            mp = 10;
            atk = 10;
            def = 10;
            Console.WriteLine("Player(부모) 생성자 호출");
        }
    }
    class Knight : Player
    {
       public Knight()
       {
            Console.WriteLine("Knight(자식) 생성자 호출");
       }
    }

    class Mage : Player
    {

    }

    class Archor : Player
    {

    }

    class Program
    {
        static void Main(string[] args)
        {
            Knight knight = new Knight();
        }
    }
}
[실행결과]
Player(부모) 생성자 호출
Knight(자식) 생성자 호출

 

보시다 싶이, 부모(Player)의 생성자가 먼저 호출되고, 자식(Knight)의 생성자가 호출 되었습니다.

 

또한, 부모의 생성자가 여러 개라면 base() 키워드를 이용해서 부모의 생성자를 특정하는 것이 가능합니다. 

사용 방법자식클래스 이름 오른쪽콜론(:) 과 함께 base()를 붙여 주면 됩니다. 괄호 안에 아무것도 넣지 않으면 기본 생성자가 호출되고, 괄호 안에 파라미터를 넣어주면 그에 맞는 생성자가 호출됩니다.

namespace TextRpg
{

    class Player 
    {
        public int hp;
        public int mp;
        public int atk;
        public int def;

        public void Attack()
        {
            Console.WriteLine("Attack!");
        }

        public void Move()
        {
            Console.WriteLine("Move!");
        }

        public Player()
        {
            hp = 100;
            mp = 10;
            atk = 10;
            def = 10;
            Console.WriteLine("Player(부모) 생성자 호출");
        }

        public Player(int hp)
        {
            this.hp = hp;
            mp = 10;
            atk = 10;
            def = 10;
            Console.WriteLine("int형 Player(부모) 생성자 호출");
        }
    }
    class Knight : Player
    {
       public Knight() : base(50)
       {
            Console.WriteLine("Knight(자식) 생성자 호출");
       }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Knight knight = new Knight();
        }
    }
}
[출력결과]
int형 Player(부모) 생성자 호출
Knight(자식) 생성자 호출

#3 base 로 부모의 요소 가져다 쓰기

base 키워드를 이용해 부모의 필드를 가져다 쓰는 것 도 가능합니다. 다음은 자식(knight)의 생성자에서 부모(player) 필드의 요소를 가져다가 재 정의한 예제입니다.사용 방법"base.부모필드 요소이름" 처럼 작성하면 됩니다.

    class Player 
    {
        public int hp;
        public int mp;
        public int atk;
        public int def;

        public void Attack()
        {
            Console.WriteLine("Attack!");
        }

        public void Move()
        {
            Console.WriteLine("Move!");
        }

        public Player()
        {
            hp = 100;
            mp = 10;
            atk = 10;
            def = 10;
            Console.WriteLine("Player(부모) 생성자 호출");
        }
    }
    class Knight : Player
    {
       public Knight() : base()
       {
            base.hp = 100;
            base.mp = 5;
            base.atk = 20;
            base.def = 30;
            Console.WriteLine("Knight(자식) 생성자 호출");
       }
    }

반응형

댓글

Designed by JB FACTORY