프로그래밍 언어/C#

상속(Inheritance)

gcreators 2024. 9. 5. 18:00

상속(Inheritance)이란

객체 지향 프로그래밍에서 가장 중요한 개념이다.

클래스는 기능들을 묶어놓은 모듈이라고 했다.

그리고 이 클래스를 이용해 생산성을 높이는 것이 객체 지향 프로그래밍 인데

클래스에 기능을 추가 해야하는데 이 추가된 기능이 한정된 상황에서 필요 할 경우

클래스에 기능을 추가하는 것은 생산성을 떨어뜨리는 일이 된다.

 

그런 상황에 대처하기 위해 나오게 된 것이 바로 상속 이다

상속은 하나의 클래스(자식)가 하나의 클래스(부모)의 기능을 모두 이어 받은 뒤

별도로 그 자식이 해야 할 일을 추가해주는 것 이라고 생각하면 된다.

자식 A와 자식 B는 별도의 존재이지만

자식 A가 할 수 있는 일이 있고 자식 B가 할 수 있는 일이 있다.

부모가 자식A와 B가 하는 일을 모두 다 할 수 있어서 이를 상속 받는다면 편리 할 수는 있겠지만

사실 그러면 A,B가 있을 필요가 없다.

부모가 할 수 있는 일을 하면서도 자식A가 해야 할 일

부모가 할 수 있는 일을 하면서도 자식B가 해야 할 일

이 있기에 상속은 의미가 있게 된다.

 

예를 들어

무기(Weapon) 라는 부모가 있다면

그 자식은 근거리 무기와 원거리 무기로 나뉠 수도 있다.

부모에 근거리 무기 라는 기능을 추가한다면 원거리 무기는 자식이 되서는 안될 것 이다.  

 

상속에 대해 알아보기 위해

생성자와 소멸자를 부모 자식으로 만들어 주겠다.

//Inheritance.cs

//부모 - 자식
//Parent - Child(부모 클래스 - 자식 클래스)
//Base - Derived(기본 클래스 - 파생 클래스)
//Super - Sub

/*sealed*/ class Parent // 키워드 sealed : 해당 클래스는 상속이 안되게함
{
    protected int parentA; //Protected : 내부 및 상속된 클래스에서는 접근이 가능하게 함, 그 외는 접근 불가
    public int parentB;//public 어디서든 접근 가능

    public Parent()
    {
        Console.WriteLine("Parent Consturctor Call!"); //부모 생성자
    }

    ~Parent()
    {
        Console.WriteLine("Parent Destructor Call!"); //부모 소멸자
    }

    public void ParentFunc()
    {
        Console.WriteLine("Parent Function Call!"); //부모 함수
    }
}



class Child : Parent
{
    public int childC;

    public Child()
    {
        Console.WriteLine("Child Consturctor Call!"); //자식 생성자
    }

    ~Child()
    {
        Console.WriteLine("Child Destructor Call!");//자식 소멸자
    }

    public void childFunc() //자식 함수
    {
        base.parentA = 10; //base는 부모를 지정함
        parentB = 20;
        //Console.WriteLine("자식 parentA : {0}, parentB : {1}", parentA, parentB); 
        //parentA : 10, parentB: 20 확인하고 싶은 사람은 해볼것
        base.ParentFunc();

    }
}

 

//Program.cs

class Program
{
    static void InheritanceExample()
    {
        //Parent parent = new Parent();

        Child child = new Child();

        child.ParentFunc();
        //child.childFunc(); //자식 함수 확인
    }
    static void Main()
    {
        //상속(Inheriatance)
        InheritanceExample();

        GC.Collect();
        Console.Read();//가비지 콜렉터 동작시간을 벌어줄 잠깐의 대기를 위한 코드
    }
}

메인 함수를 통해

자식 클래스가 호출이 된다.

 

하지만 자식 클래스는 부모 클래스를 상속 받고 있으므로

부모 클래스의 생성자부터 호출이 된 후 자식 클래스의 생성자가 호출이 된다.

 

그리고 자식 클래스에는 부모 함수가 선언 되어있지 않지만

상속을 받았기에 그 기능을 활용 할 수 있다는 것을 확인 할 수 있다.

이후 자식 클래스의 소멸자가 호출 된 후 부모 클래스의 소멸자가 호출이 되는 것을 확인 할 수 있다.

 

데이터를 읽을 때 상속되는 부모부터 읽은 후 자식 클래스를 읽게 된다.

 

위의 예시를 통해

가비지 컬렉션이 어떻게 작동 되는지 체크하고

부모 클래스에는 꼭 꼭 필요한 기능만 추가해서 메모리를 효율적으로 활용 하는 프로그램을 짤 수 있도록 해야한다.