공부/C#

[C#] 상속과 virtual, abstract, interface / 오버로딩, 오버라이딩 코드

굴러다니다니 2023. 3. 23. 21:14
728x90

앞의 내용에서 상속을 다뤘는데, virtual / abstract / interface와는 무슨 연관이 있을가?

본래 상속은 단일 클래스만 가능한 일이지만, 다중 상속이 가능한 키워드가 있다.

 

부모클래스에서 protected / public으로 선언한 변수는 자식클래스에서도 참조가 가능하지만 private으로 선언한 변수는 안된다는 것은 모두 알고 있을것이다.

그렇다면 method, 즉 함수의 경우는 어떨까?

protected / public으로 선언된 메소드는 위와 동일하다.

하지만 메소드를 재정의 하는 경우는 또 다르다.

 

virtual(가상) abstract(추상) interface

virtual : 재정의가 가능하고 이는 필수가 아니다.

abstract: 재정의가 가능하지만 이는 필수이다.

(abstract로 부모클래스에서 선언을 할 수 있지만, 부모클래스에서 정의를 내릴 순 없다. 자식클래스에서 각각 정의를 해줘야한다.)

interface: 재정의 가능하며 이는 필수이다.

* 그렇다면 abstract와 interface의 차이점은 무엇일까?

인터페이스의 경우 조립의 개념에 더 가깝다.

또한 다중 상속이 가능해 기능에 많이 사용된다.

예를 들어 공격하는 기능은 같지만 안의 행동은 기본 공격 / 스킬 공격 등으로 같은 종류지만 형태가 다를 때 많이 사용된다.

(다형성 / 확장성 개념에 속한다)

 

그렇다면 상속은 왜 사용될까?

- 추상화 : 재사용이 용이하게 추상화를 시키기 위함이다.

- 유지보수 및 메모리 효율: 공격에서 오류가 났을때 이를 한번에 수정하는 등 유지보수적인 측면이 강하다.

 


인터페이스를 이용해 코드를 작성해보자.

    public interface IWalk
    {
        void Walk();
    }

클래스 선언 전, public interface로 걸어다니는 함수를 가진 인터페이스를 선언해주었다.

보통 인터페이스를 이용하면 함수 이름을 대문자 I를 붙여 사용한다.


    abstract class Animal
    {
        public virtual void Speak()
        {
            Console.WriteLine("Scream");
        }
        //abstract는 선언한 클래스에 추상(abstract) 키워드를 붙여 줘야 한다.
        public abstract void Sleep(); 
    }

Animal이라는 큰 부모클래스를 생성해주었다.

Animal은 짖을 수 있게 Speak라는 virtual 함수를 가지고 있다.

또한 잔다는 Sleep 메서드도 가지고 있지만, 이를 abstract로 선언하였기 때문에 이에 대한 정의는 자식 클래스에서만 할 수 있다.

또한 메서드를 abstract 형태로 선언한다면, 이를 포함한 class도 abstract 형태가 되어야한다.

 class Dog : Animal, IWalk
    {
        public override void Sleep()
        {
            Console.WriteLine("zzzzzzzzzzzZZZZZZZZ");
        }

        public override void Speak()
        {
            base.Speak(); //부모의 메서드 한번 실행하고 재정의된 메소드가 실행된다.
            Console.WriteLine("bark bark"); //재정의
        }

        public void Walk()
        {
            Console.WriteLine("강아지의 발발거림");
        }
    }

Animal의 클래스를 상속받으며, 인터페이스 IWalk를 받는 Dog 클래스를 선언했다.

위의 Sleep을 재정의 하기 위해 override를 붙였으며, Speak또한 오버라이딩하였다.

base.method를 실행하면 부모클래스의 메서드를 한번 실행한다. 

Iwalk에서 선언했던 Walk 메서드또한 선언해주었다.

class Program
    {
        static void Main(string[] args)
        {
            Dog cancho = new Dog();
            cancho.Speak();
            cancho.Walk();
            cancho.Sleep();
        }
    }
}

메인문에서 칸초라는 강아지가 말하고 뛰고 잘 수 있게 코드를 짰다.

위의 코드를 실행하면

Scream

Bark bark

강아지의 발발거림

zzzzzzzzzzzZZZZZZZZZZ

순서로 출력된다는 것을 확인할 수 있다.


위의 오버라이딩은 override라는 키워드를 사용한 반면, 같은 이름의 함수를 파라미터만 다르게 해서 사용하는 오버로딩은 별개의 키워드가 존재하지 않는다.

static int Sum(int a, int b)
        {
            int result = a + b;
            return result;
        }
        static int Sum(int a, int b, int c)
        {
            int result = a + b + c;
            return result;
        }

        static void Main(string[] args)
        {
            Console.WriteLine(Sum(1, 2));
            Console.WriteLine(Sum(1, 2, 3));
        }
728x90