virtual method (가상 메서드) 는 abstract method (추상 메서드) 와 달리, 자식 클래스에서 재정의 여부는 선택입니다. 

추상 메서드에서는 재정의는 필수입니다.

 

가상 메서드가 포함된 클래스를 상속할때, 자식 클래스에서 재정의 할 때에는 override, new 두 가지 한정자로 정의할 수 있습니다.

추상 메서드가 포함된 클래스를 상속할때에는 override 만 가능합니다.

 

언제 override 키워드를 사용할지, new 키워드를 사용할지 헷갈려서 정리해봅니다.

 

그전에 알아야할 내용이 많습니다. 업캐스팅(Up Casting), 다운캐스팅(Down Casting)을 알아야 합니다.

서로 상속관계에 있는 클래스들 사이에서 타입 변환이 가능합니다.

 

업캐스팅 (Up Casting)

  • 자식 클래스 타입에서 부모 클래스 타입으로 변경됩니다.
  • 자동적으로 형변환이 됩니다.

 

다운캐스팅 (Down Casting)

  • 부모 클래스 타입에서 자식 클래스 타입으로 형변환됩니다.
  • 명시적으로 형변환이 됩니다.

 

 

업캐스팅 / 다운캐스팅 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Program {
    static void Main(string[] args) {
        // Up Casting
        Animal animal = new Lion();
 
        // Down Casing
        Lion lion = (Lion)animal;
    }
}
 
// 부모 클래스
public class Animal {
}
// 자식 클래스
public class Lion : Animal {
}
cs
  • 프로그래밍 언어의 다형성을 말할때 가장 많이 사용되는 Animal 클래스 (부모 클래스)
  • Animal 클래스를 상속받는 Lion 클래스 (자식클래스)
  • 4번째 라인, animal 객체는 new Lion 으로 객체 생성되었지만 부모 클래스인 Animal 클래스로 바로 캐스팅되었습니다. (Up Casting)
  • 7번째 라인, lion 객체는 animal을 명시적 캐스팅으로 자식 클래스인 Lion 클래스로 다운 캐스팅 되는 것을 볼 수 있습니다. (Down Casting)
  • 업/다운 캐스팅 예제를 기반으로, override/new 한정자를 사용했을 때 호출되는 메서드의 차이를 설명해보겠습니다.

 

override 를 사용할 경우

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Program {
    static void Main(string[] args) {
        // Up Casting
        Animal animal = new Lion();
        animal.Sound();
    }
}
 
 
public class Animal {
    public virtual void Sound() {
        Console.WriteLine("부모");
    }
}
public class Lion : Animal {
    public virtual void Sound() {
        Console.WriteLine("어흥");
    }
}
cs
  • override 는 자신이 상속받은 부모 클래스의 메소드를 재정의 하는 것을 의미합니다.
  • Animal.Sound 부모 클래스 메서드를 숨기고, 자식 클래스인 Lion.Sound 메서드를 재 정의하였습니다.
  • Up Casting 된 animal 객체에서 Sound를 호출하면, 재정의된 Lion.Sound 가 호출이 되고 콘솔에는 어흥이 찍히게 됩니다.

 

new 를 사용했을 경우

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Program {
    static void Main(string[] args) {
        // Up Casting
        Animal animal = new Lion();
        animal.Sound();
    }
}
 
 
public class Animal {
    public virtual void Sound() {
        Console.WriteLine("부모");
    }
}
public class Lion : Animal {
    public new void Sound() {
        Console.WriteLine("어흥");
    }
}
cs
  • override 와 달리, new 키워드는 부모 클래스의 메서드를 완전히 무시하고 동일한 이름의 새로운 메서드를 만드는 것을 의미합니다.
  • Lion.Sound 메서드는 Animal.Sound 메서드와 완전히 다른 메서드라고 생각하시면 됩니다.
  • Up Casting 된 animal 객체에서 Sound를 호출하면, animal 객체의 타입은 Animal 이기 때문에 Animal.Sound 가 호출이 되고 콘솔에는 부모가 찍히게 됩니다.

 

결론

new, override 둘다 메소드를 재정의하는 것이지만, 키워드 하나로 인해서 결과가 다르게 나오기 때문에 쓰임새를 정확하게 이해하고 사용해야겠다는 생각이 들었습니다. 

 

 

+ Recent posts