Virtual 및 Override 키워드
Coddy C# 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 70개 중 21번째.
파생 클래스가 메서드를 상속받을 때, 때로는 해당 메서드의 동작 방식을 완전히 바꾸고 싶을 수 있습니다. virtual 및 override 키워드를 함께 사용하면 이를 제어된 방식으로 구현할 수 있습니다.
파생 클래스가 해당 메서드의 구현을 대체할 수 있음을 나타내려면 기본 클래스에서 메서드를 virtual로 표시하세요:
public class Animal
{
public virtual void Speak()
{
Console.WriteLine("Some sound");
}
}
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("Woof!");
}
}파생 클래스의 override 키워드는 기본 메서드를 의도적으로 대체한다는 것을 컴파일러에 알립니다. 기본 메서드에 virtual이 없으면 override를 사용할 수 없습니다.
기본 클래스 참조를 사용해 파생 클래스 객체를 담을 때 진정한 힘이 드러납니다:
Animal myPet = new Dog();
myPet.Speak(); // 출력: Woof!myPet이 Animal로 선언되어 있어도 C#은 Speak()의 Dog 버전을 호출합니다. 이를 런타임 다형성이라고 합니다. 실제로 호출되는 메서드는 변수의 선언된 형식이 아니라 객체의 실제 형식에 따라 달라집니다.
동작을 완전히 대체하는 대신 확장하고 싶다면 재정의한 메서드 안에서 base.Speak()를 사용해 기본 구현에 계속 접근할 수 있습니다.
챌린지
쉬움virtual 및 override 키워드를 사용해 파생 클래스가 기본 클래스의 동작을 완전히 재정의하는 방법을 보여 주고, 런타임 다형성의 강력함도 살펴보는 알림 시스템을 만들어 봅시다.
코드를 정리하기 위해 파일 세 개를 만들겠습니다:
Notification.cs:Alerts네임스페이스에Notification클래스를 정의합니다. 이 기본 클래스는Message속성(string)과 해당 속성을 설정하는 생성자를 가진 일반 알림을 나타냅니다."Sending notification: {Message}"를 반환하는virtual메서드Send()를 포함합니다.EmailNotification.cs:Alerts네임스페이스에Notification을 상속하는EmailNotification클래스를 정의합니다.Recipient속성(string)과 메시지 및 수신자를 모두 받는 생성자를 추가합니다(메시지를 전달할 때base를 사용합니다).Send()메서드를 재정의하여"Emailing {Recipient}: {Message}"를 반환합니다.SmsNotification.cs:Alerts네임스페이스에Notification을 상속하는SmsNotification클래스도 정의합니다.PhoneNumber속성(string)과 메시지 및 전화번호를 모두 받는 생성자를 추가합니다.Send()를 재정의하여"SMS to {PhoneNumber}: {Message}"를 반환합니다.Program.cs: 메인 파일에서 입력값을 사용해 세 가지 알림 유형의 인스턴스를 만듭니다. 그런 다음 세 인스턴스를 모두Notification변수에 저장하고 각각에Send()를 호출하여 런타임 다형성을 보여 줍니다.
입력은 네 개가 주어집니다:
- 알림 메시지
- 이메일 수신자 주소
- SMS에 사용할 전화번호
기본 클래스 참조로 저장된 각 알림에 Send()를 호출한 결과를 출력합니다:
{base notification Send() result}
{email notification Send() result}
{sms notification Send() result}예를 들어 입력이 Meeting at 3pm, alice@email.com, 555-1234라면 출력은 다음과 같아야 합니다:
Sending notification: Meeting at 3pm
Emailing alice@email.com: Meeting at 3pm
SMS to 555-1234: Meeting at 3pm세 인스턴스 모두 Notification 변수에 저장되어 있는데도 각 인스턴스가 자신만의 재정의된 Send() 버전을 호출한다는 점에 주목하세요. 이것이 바로 런타임 다형성입니다!
직접 해보기
using System;
using Alerts;
class Program
{
public static void Main(string[] args)
{
// 입력값 읽기
string message = Console.ReadLine();
string email = Console.ReadLine();
string phone = Console.ReadLine();
// TODO: 세 가지 알림 유형의 인스턴스를 모두 생성하기
// 다형성을 보여주기 위해 인스턴스들을 Notification 변수에 저장하기
// TODO: 기본 Notification 생성하기
Notification baseNotification;
// TODO: EmailNotification 생성하기(Notification 타입으로 저장)
Notification emailNotification;
// TODO: SmsNotification 생성하기(Notification 타입으로 저장)
Notification smsNotification;
// TODO: 각각에 대해 Send()를 호출하고 결과 출력하기
// 런타임 다형성에 따라 재정의된 메서드가 호출됩니다
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C# 컴파일러