본문 바로가기
Programming Language/C#

[C#] 오버라이딩

by dbxxrud 2019. 5. 18.

오버 라이딩 - 클래스의 상속 관계에서 사용하는 개념으로 다른 의미로 재정의 하는 것을 의미한다. 메서드를 오버 라이딩하기 위해서는 조건이 필요한데, 오버 라이딩을 할 메서드가 virtual 키워드로 한정되어 있어야 한다는 것이다. 

 

 

예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using System;
using static System.Console;
using System.Collections;
 
 
namespace AS
{
    class ArmorSuite
    {
        public virtual void Initialize() // 오버로딩할 메소드를 virtual 키워드로 정의 
        {
            WriteLine("Armored");
        }
    }
    class IronMan : ArmorSuite
    {
        public override void Initialize()
        {
            base.Initialize();
            WriteLine("Repulsor Ray Armed");
        }
    }
    class WarMachine : ArmorSuite
    {
        public override void Initialize()
        {
            base.Initialize();
            WriteLine("Double-Barrel Cannons Armed");
            WriteLine("Micro-Roket Launcher Armed");
        }
    }
    class MainApp
    {
        public static void Main(string[] args)
        {
            WriteLine("Creating ArmorSuite...");
 
            ArmorSuite armorSuite = new ArmorSuite();
            armorSuite.Initialize();
 
            WriteLine("\nCreating IronMan...");
            ArmorSuite ironman = new IronMan();
            ironman.Initialize();
 
            WriteLine("\nCreating WarMachine...");
            ArmorSuite warmachine = new WarMachine();
            warmachine.Initialize();
        }
    }
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

 

 

결과

 

아이언맨의 ArmorSuite 클래스를 만들고 업그레이드를 위해 ArmorSuite 자체를 고치기보다는 상속하는 클래스를 만들어서 Initialize 메서드를 오버 라이딩한 코드이다. 

 

※ private로 선언된 메서드는 오버 라이딩할 수 없다

    private로 선언된 멤버는 어차피 파생 클래스에서도 보이지 않으며, 같은 이름, 같은 형식, 같은 매개 변수를 이용하여 선언했다 하더라     도 컴파일러는 기반 클래스의 메서드를 재정의한다고 생각하지 않고 전혀 없었던 메서드를 선언한다고 간주한다.

 

 

 

메서드 숨기기

 

CLR에게 기반 클래스에서 구현된 버전의 메서드를 감추고 파생 클래스에서 구현된 버전만을 보여주는 것이다. 메서드 숨기기는 파생 클래스 버전의 메서드를 new 한정자로 수식함으로써 할 수 있다(생성자를 호출할 때 사용하는 new 연산자와는 완전히 다른 녀석임.)

 

 

예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using static System.Console;
using System.Collections;
 
 
namespace AS
{
    class Base
    {
        public void MyMethod()
        {
            WriteLine("Base.MyMethod");
        }
    }
    class Derived : Base
    {
        public new void MyMethod()
        {
            WriteLine("Derived.MyMethod()");
        }
    }
    class MainApp
    {
        public static void Main(string[] args)
        {
            Base baseObj = new Base();
            baseObj.MyMethod();
 
            Derived derivedObj = new Derived();
            derivedObj.MyMethod();
 
            Base baseOrDerived = new Derived();
            baseOrDerived.MyMethod();
        }
    }
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

 

 

기반 클래스에는 아무 생각없이 메서드를 구현해도 메서드 숨기기를 하면 오버 라이딩과 같은 효과를 얻을 수 있다. 하지만 메서드 숨기기는 오버 라이딩과 다르다. 이름 그대로 메서드를 숨기고 있을 뿐 객체를 선언하면 CLR에게 Base 버전의 MyMethod()가 노출되어 이를 실행하게 된다.

 

 

그래서 메소드 숨기기는 완전한 다형성을 표현하지 못하는 한계를 가지고 있다. 따라서 기반 클래스를 설계할 때 파생 클래스의 모습까지 고려해야 한다.

 

 

오버 라이딩 봉인

 

메서드도 오버 라이딩되지 않도록 봉인할 수 있다. virtual로 선언된 가상 메서드를 오버 라이딩한 버전의 메서드만이 가능하다.

Derived의 SealMe() 만 봉인할 수 있다.

 

 

 

위 코드는 실행할 수 없다. 

봉인메소드는 혹시라도 파생 클래스의 작성자가 기반 클래스로부터 상속받은 메서드 하나를 오버 라이딩했는데 이 때문에 다른 부분들이 오작동을 하게 된다면 동작하지 않는 원인을 알 수도 없다. 그래서 오작동을 할 위험이 있거나 잘못 오버 라이딩함으로써 발생할 수 있는 문제가 있다면 봉인 메서드를 이용해서 상속을 사전에 막는 것이 낫다.

 

 

 

※ 혼자서 공부하며 정리하는 블로그 입니다.

참고서적 : 이것이 c#이다

'Programming Language > C#' 카테고리의 다른 글

[C#] 구조체  (0) 2019.05.18
[C#] 중첩 클래스  (0) 2019.05.18
[C#] 상속  (0) 2019.05.18
[C#] 접근 한정자  (0) 2019.05.18
[C#] 정적 필드와 메소드  (0) 2019.05.18