[C#] Sealed 키워드

PIAZZI·2024년 5월 1일

C#

목록 보기
6/9
post-thumbnail

sealed 키워드

  • 메소드나 클래스를 봉인하는 키워드.
  • 메소드에 사용 시, 해당 메소드를 더 이상 재정의 할 수 없게 된다.
  • 클래스에 사용 시, 해당 클래스를 상속 할 수 없게 된다.

보통 추상클래스인터페이스를 통해 상속의 관계를 맺게 된다.
상속을 받은 자식클래스는 가지고 있는 추상 메소드를 반드시 재정의해야 한다.
이때 더 이상 해당 메소드를 재정의 못 하게 봉인하고 싶다면 sealed 키워드를 사용하면 된다.

예시를 간단하게 들자면

public sealed override void ItemGrade(){	//아이템의 최고 등급을 정하는 메소드라고 하자.
	Console.WriteLine("아이템의 최고 등급은 에픽입니다.");
} 

위의 코드 내용은 간단하다.

아이템의 최고 등급을 정하는 메소드를 상속받아서 최고 등급을 에픽으로 재정의한 것이다.

그리고 sealed 키워드를 사용했는데, 여기서의 의미는 다음과 같다.

아이템의 최고 등급은 에픽으로 고정할 생각이니, 재정의 못하도록 막아두겠다는 의미이다.

그럼 해당 메소드는 이후의 자식 클래스에서는 재정의할 수 없다.

예시를 간단하게 보면 다음과 같다.

class Game_Version_01
{
	public virtual void ItemGrade() //	최상위 클래스
    {
    	Console.WriteLine("아이템의 최고 등급은 에픽입니다.");
    }
}

class Game_Version_05 : Game_Version_01 // 최상위 클래스를 상속 받은 중간 단계 클래스
{
    public sealed override void ItemGrade() 	//ItemGrade 재정의 후, sealed 선언으로 ItemGrade 메소드 재정의 봉인
    {
    	Console.WriteLine("아이템의 최고 등급은 전설입니다.");
    }
}

class Game_Version_10 : Game_Version_05 // 중간 단계 클래스를 상속받은, 현재 최하위 클래스
{
    public override void ItemGrade() // 상속받는 Game_Version_05 클래스에서 sealed 키워드로 막아놨기에 재정의할 수 없다. - 오류 발생
    {
    	Console.WriteLine("아이템의 최고 등급은 신화입니다.");
    }
}

static void main(stirng[] args){
	
    Game_Version_01 v1 = new Game_Version_01;
	Game_Version_05 v5 = new Game_Version_05;
	Game_Version_10 v10 = new Game_Version_10;
	
    v1.ItemGrade(); // "아이템의 최고 등급은 에픽입니다." 출력됨
    v5.ItemGrade(); // "아이템의 최고 등급은 전설입니다." 출력됨
    v10.ItemGrade(); // 오류 발생
}

게임이 Version_01 일 때는 아이템 최고 등급에픽으로 정했지만, 이후 Version_01 을 상속받은 Version_05 에서는 전설로 수정했다.
이후 아이템 등급을 더 올릴 생각이 없었기에, Version_05 에서 이를 sealed 키워드로 재정의를 막아두었고,
Version_05 를 상속받은 Version_10 에서는 아이템 등급을 재정의할 수 없게 된 것이다.

그래서 오류 메세지를 보면 [상속된 'Game_Version_05.ItemGrade()' 멤버는 봉인되어 있으므로 재정의 할 수 없습니다] 라고 나온다.

위의 구조를 보고, sealde 키워드의 특징을 보면 느껴지는게 있다.

*sealed 지정하는 최상위 클래스나 최하위 클래스에서는 사용되지 않는다.

즉, sealed 키워드는 주로 중간 단계의 클래스에서 사용된다.

  • 최상위 클래스에서는 상속받으라고 가상 또는 추상 메소드를 선언했는데 sealed 키워드로 막는 것은 말이 되지 않는다.
  • 최하위 클래스에서는 어차피 더 이상 상속되지 않는데, sealed 키워드를 쓸 이유가 없다.

그래서 보통 sealed 키워드는 중간 단계 클래스에서만 사용된다.


그럼 만일 위의 예시에서 Game_Version_10 클래스ItemGrade() 메소드를 바꿔야 할 상황이 온다면 어떻게 될까?

class Game_Version_10 : Game_Version_05
{
    public override void ItemGrade()
    {
    	Console.WriteLine("아이템의 최고 등급은 신화입니다.");
    }
}

위의 기존 코드에서 아래와 같이 바꾸면 된다.

class Game_Version_10 : Game_Version_05
{
    public new void ItemGrade()
    {
    	Console.WriteLine("아이템의 최고 등급은 신화입니다.");
    }
}

예시를 보면 override 키워드가 사라지고, new 키워드가 추가되었다.
이는 사실상 ItemGrade()를 재정의 못해서 그냥 ItemGrade()라는 메소드를 새로 만든거라 보면 된다.

그럼 아래와 같은 코드는 결과가 어떻게 나올까.

static void main(stirng[] args){
	
	Game_Version_01 v10 = new Game_Version_10;
    v10.ItemGrade();
    
}

v10동적 타입게임의 초기 버전인 Game_Version_01 이고, 동적 타입Game_Version_10 상태에서
가상 메소드인 ItemGrade()를 호출한 코드이다.

결과는 다음과 같다.

아이템의 최고 등급은 전설입니다.

예상과 달리 Game_Version_10 클래스에서 new 키워드를 통해 아이템 등급신화로 올렸는데도 전설로 출력된다.
이 말은 Game_Version_10상속받은 Game_Version_05ItemGrade()이 출력된 것이다.

이는 사실 간단한데, ItemGraed()가 가상 메소드이기에 동적 타입을 따르게 되는데, Game_Version_10이 상속받은 ItemGraed()Game_Version_05로부터 상속받은 숨겨진 메소드이기 때문이다.

Game_Version_10 클래스에서 new 키워드로 생성한 ItemGraed()은 새로 만든 것이지,
상속받은 가상 메소드가 아니기에 출력이 되지 않은 것이다.

이런 상황 때문에 보통 봉인된 메소드는 그대로 상속받아서 사용하는 게 좋다.


필요하다면 클래스 전체를 봉인할 수도 있다.
클래스 선언문에 sealed 키워드를 붙이면, 그 클래스는 더 이상 상속을 할 수 없게 된다.
즉, 부모 클래스로서의 기능할 수 없게 되는 것이다.

public sealed void Game_Version_01{ // sealed 키워드로 클래스 전체를 막아놨기에, 이제 이 클래스를 상속받을 수 없다.
 . . .
}

보통은 클래스 그 자체로 기능이 완벽해서 더 이상 추가할 기능이 없거나, 상속할 경우 부작용이 생길 우려가 있을 경우 이렇게 봉인하기도 한다.


개인적인 공부를 위해 정리한 내용이며, 틀린 점이 있을 수 있습니다.
만일 틀린 내용이 있다면, 댓글로 알려주시면 감사하겠습니다.

profile
범부에오

0개의 댓글