C# 클래스와 객체지향 - 17. 상속과 오버라이딩 제한
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 키워드를 적지 않아도 되기 떄문입니다.