C#/클래스와 객체지향

C# 클래스와 객체지향 - 17. 상속과 오버라이딩 제한

tita 2024. 5. 29. 16:29

C#에는 클래스에서 상속을 불가하게 하거나 반드시 상속하게 하는 정보를 입력할 수 있습니다.

이것은 메서드에도 동일하게 적용되며, 다양한 방법을 알아보겠습니다.

 

 

[sealed 메서드]

sealed 키워드는 클래스와 메서드 앞에 적용하는 키워드입니다. 클래스에 적용하면 절대 상속하지 말라는 의미가 되고, 메서드에 적용하면 더 이상 오버라이딩 하지 말라는 의미가 됩니다.

 

 

 

<상속 제한>

부모의 클래스에 sealed를 붙이고 자식의 클래스에서 상속을 받으면 에러가 발생합니다. 

다음 코드를 통해 확인할 수 있습니다.

 

class Program
{
    sealed class Parent
    {
    	public void Test() { }
    }
    
    class Child : Parent // 여기서 에러가 발생합니다
    {
        public void Test() { }
    }
    
    static void Main(string[] args)
    {
        Parent parent = new Parent();
        Child child = new Child();
        
        parent.Test();
        child.Test();
    }
}

 

 

<메서드 오버라이딩 제한>

sealed 키워드를 메서드 앞에 붙일 때는 앞에서 언급한 것처럼 더 이상 오버라이딩하지 말라는 의미입니다. 더 이상이라는 말이 있는 것처럼 원래 virtual  키워드가 붙어 오버라이딩할 수 있는 메서드를 어느 지점 이후로 못하게 하는 것입니다.

 

상속을 여러번 받는 경우에 사용하기도 합니다.

class Program
{
    sealed class Parent
    {
    	public virtual void Test() { }
    }
    
    class Child : Parent 
    {
        //sealed 메서드로 변경했습니다.
        sealed public override void Test() { }
    }
    
    class GrandChild : Child
    {
        public override void Test() { } // 여기서 오류가 발생합니다.
    }
}

 

 

 

[abstract 키워드]

abstract 키워드는 sealed 키워드와 반대로 무조건 상속해서 쓰라는 의미 또는 이 메서드는 반드시 오버라이딩해달라는 의미로 사용됩니다.

 

 

<상속>

일단 abstract 키워드를 클래스에 적용하는 경우를 살펴보겠습니다. abstract 키워드를 클래스에 적용하면 반드시 상속해서 쓰라는 의미가 됩니다. 해당 클래스 자체는 인스턴스를 만들 수 없습니다.

class Program
{
    // abstract 클래스를 선언했습니다.
    abstract class Parent
    {
    	public void Test() { }
    }
    
    class Child : Parent 
    {
        public void Test() { }
    }
    
    static void Main(string[] args)
    {
        Parent parent = new Parent(); // 여기서 오류가 발생합니다.
        Child child = new Child();
        
        parent.Test();
        child.Test();
    }
}

 

 

 

 

<메서드 오버라이딩>

메서드에 abstract 를 적용하면 이 메서드를 반드시 오버라이딩 해달라는 의미가 됩니다.

abstract 키워드를 메서드에 적용할 때는 반드시 클래스에도 abstract 키워드를 적용해야 합니다.

abstract 메서드가 되면 중괄호 { } 를 사용하지 않고 곧바로 세미콜론을 찍습니다. 

어차피 상속해서 사용할 것이므로 내용을 적지  않습니다.

 

abstract class Parent     // 메서드에 abstract 선언하려면 반드시 클래스도 abstract 로 선언되어야 합니다.
{
    public abstract void Test(); // abstract 메서드로 선언되었습니다.
}

class Child : Parent // 여기서 오류가 발생합니다.
{

}

 

해결하는 방법은 다음과 같습니다.

abstract class Parent    
{
    public abstract void Test(); 
}

class Child : Parent 
{
    public override void Test();  // override 키워드를 이용해 오버라이딩해야 합니다.
}

 

조금 이상합니다.  원래 override 키워드를 사용하려면 부모의 메서드에 virtual 키워드가 있어야 하는데 abstract 키워드만 있습니다.

abstract 키워드 자체가 이 메서드는 반드시 오버라이딩해달라는 의미이기 때문에 따로 virtual 키워드를 적지 않아도 되기 떄문입니다.