[C#] 클래스의 상속(inheritance)

정영훈·2022년 10월 10일
0

C#프로그래밍

목록 보기
19/29

👉 상속

객체 지향 프로그래밍에선 부모 클래스와 자식 클래스가 있는데, 부모 클래스는 자식 클래스의 기반이 된다 하여 기반 클래스라고 부르기도 하고, 자식 클래스는 부모 클래스로부터 파생되었다고 해서 파생 클래스라고도 부르기도 한다.

상속 방법


class 부모 클래스
{
 // 부모 클래스 필드 값
 // 부모 클래스 메소드
}

class 자식 클래스 : 부모 클래스
{
  // 부모 클래스의 모든 상태와 행동이 전달
}
  • 부모 클래스는 자식 클래스에게 부모 클래스의 모든 필드와 메소드를 물려주게 되며, 자식 클래스는 부모의 모든 멤버를 사용할 수 있다.

😁예제

class Hero
{
    private int hp;
    private int attack;

    public void Attack()
    {
        Console.WriteLine("공격하라");
    }
}

class Knight : Hero
{
    private int defense;
    public void Defense()
    {
        Console.WriteLine("방어하라");
    }
}

class Mage : Hero
{
    private int mana;
    public void Magic()
    {
        Console.WriteLine("마법 공격 시전!!");
    }
}

Knight 클래스와 Mage 클래스는 Hero클래스를 상속받아 클래스를 정의하였다.

상속을 사용하는 이유

  • 위 예제에서 hero클래스를 부모 클래스로 정의하고 상속하여 자식 클래스를 선언하지 않고 별도의 클래스로 Knight클래스와 Mage클래스를 선언할 경우 중복되는 필드값과 메서드를 반복하여 작성 해야 된다.
  • 만약 rpg게임에서 선택할 수 있는 직업군이 기사, 마법사, 바바리안, 성직자 등등 여러 종류가 있다면 중복되는 필드값과 메서드를 각각의 직업마다 정의해야 되고, 수정 과정에서 실수를 할 수 있다.

✌ Protected 접근제한자

  • 접근제한자는 이전에 Public과 Private을 설명했다.
  • Public은 내외부 클래스에서 접근가능하며, Private은 내부 클래스에서만 접근 가능한 접근제한자이다.
  • Protected는 외부에서는 접근이 불가능하지만 상속한 클래스에서는 접근할 수 있는 접근제한자이다.

    즉 Private 접근제한자에 파생 클래스로부터의 접근을 허용하는 역할이
    추가되었다.

😁예제

class Hero
{
    protected int hp;
    private int attack;
    public void Attack()
    {
        Console.WriteLine("공격하라");
    }
}
class Knight : Hero
{
    private int defense;
    public void Defense()
    {
        hp -= 10; //protected는 자식클래스에서 접근 가능하지만
        attack += 10; //private는 자식클래스에서 접근할 수 없다.
        Console.WriteLine("방어하라");
    }
}

👌 this와 base 키워드

this키워드

  • this키워드는 클래스 내부에서 멤버에 접근할 때 멤버의 이름으로 바로 멤버에 접근할 수 있다. 이는 현재 객체를 가르키는 키워드 this가 생략된 것이다.
class Hero
{
    protected int hp;
    private int attack;

    public Hero(int attack)
    {
        this.attack = attack; 
        //매개변수와 내부 멤버 변수의 이름이 같은 상황
        //this키워드를 통해 내부 멤버 변수에 접근할 수 있다.
    }
}

base키워드

  • this키워드는 클래스의 현재 객체를 가리키지만, base키워드는 부모 클래스를 가르킨다. 다음과 같은 예제를 살펴보자
class Hero
{
    protected int hp;
    protected int attack;

}
class Knight : Hero
{
    int hp;
    private int defense;
    public Knight(int hp)
    {
        base.hp = hp;
        this.hp = 100;
    }
    public int Hp
    {
        get { return hp; }
    }
    public int Php //부모의 hp를 확인
    {
        get { return base.hp; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Knight knight = new Knight(200);
        Console.WriteLine(knight.Hp); //현재 hp를 출력
        Console.WriteLine(knight.Php); //부모의 hp를 출력
    }
}
//출력결과
//100
//200

부모생성자 호출 :base()

  • 자식의 생성자에서 부모의 생성자를 명시적으로 호출할 수 있다.
  • :(콜론)과 함께 base()를 통해 부모 클래스의 생성자를 호출한다.
  • 아래 예제의 Knight생성자에서 :base(name)을 통해 입력받은 name 매개변수를 Hero 부모 클래스의 생성자를 호출한다.
  • 이때 부모 클래스의 생성자는 두개가 있으며, 두개 중 매개변수를 string name으로 가지는 생성자를 호출한다.
class Hero
{
    protected int hp;
    protected int attack;
    protected string name;
    public Hero() { }
    public Hero(string name)
    {
        this.name = name;
    }
}
class Knight : Hero
{
    public Knight(int attack, string name) : base(name) 
    {
        this.attack = attack;
        this.hp = 100;
    }
    public int Attack 
    { 
        get { return attack; }
    }
    public string Name
    {
        get { return name;}
    }
}
class Program
{
    static void Main(string[] args)
    {
        Knight knight = new Knight(200,"james");
        Console.WriteLine($"{knight.Name}의 공격력은 {knight.Attack}입니다.");
    }
}

🖖 상속의 상속

  • 상속받은 클래스는 자식 클래스에게 상속할 수 있다.
  • Creature 클래스는 Hero 클래스에게 상속하고, Hero클래스는 Knight클래스에게 상속하였다.

활용 예제

class Creature
{
    protected int hp;
    protected int attack;

    public int Hp
    {
        get { return hp; } 
        set { hp = value; }
    }
    public int Attack
    {
        get { return attack; }
        set { attack = value; }
    }
    public bool IsDead()
    {
        if (hp < 0) return true;
        else return false;
    }
}
class Hero : Creature
{
    protected string name;
    protected int defense;

    public Hero(string name)
    {
        this.name = name;
        Console.WriteLine("생성자 발동");
    }

    public string Name
    {
        get { return name; }
    }
}

class Knight : Hero
{
    public Knight(string name) : base(name)
    { 
        this.hp = 100;
        this.attack = 100;
        Console.WriteLine("생성자 발동2");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Knight knight = new Knight("kim");
        Console.WriteLine(knight.Name);
        Console.WriteLine(knight.Hp);
        Console.WriteLine(knight.Attack);
    }
}
profile
경북소프트웨어고등학교 정보교사

0개의 댓글