C#
C# - Virtual & abstract
Dev_Jen
2025. 7. 3. 10:04
반응형
✅ virtual 키워드 정리
📌 정의
virtual은 부모 클래스에서 메서드나 속성을 "재정의 가능"하게 만드는 키워드입니다.
📋 기본 문법
class Parent
{
public virtual void SayHello()
{
Console.WriteLine("안녕하세요. 부모입니다.");
}
}
class Child : Parent
{
public override void SayHello()
{
Console.WriteLine("안녕하세요. 자식입니다.");
}
}
✅ 주요 특징
기본 구현 제공 | 부모 클래스가 기본 로직을 정의 |
자식 클래스에서 변경 가능 | override 키워드로 오버라이딩 가능 |
선택적 재정의 | 자식 클래스에서 반드시 재정의하지 않아도 됨 |
다형성 지원 | 부모 타입으로 자식 객체를 가리킬 때, 실제 자식의 메서드가 실행됨 |
🔍 예시
Parent obj1 = new Parent();
obj1.SayHello(); // 출력: 안녕하세요. 부모입니다.
Child obj2 = new Child();
obj2.SayHello(); // 출력: 안녕하세요. 자식입니다.
Parent obj3 = new Child();
obj3.SayHello(); // 출력: 안녕하세요. 자식입니다. (다형성!)
🧠 언제 쓸까?
- 기본 동작은 있으나, 자식 클래스에서 상황에 따라 동작을 바꾸고 싶을 때
- 템플릿 메서드 패턴에서 일부 단계를 virtual로 두면 자식 클래스가 필요 시 바꿀 수 있음
❗ 주의
- virtual 메서드는 자식 클래스에서 override 키워드로 재정의해야 함
- virtual 없이 그냥 override는 불가능함 → 부모가 virtual 또는 abstract여야 함
❓
그럼 궁금한게 꼭 버츄얼을 써야 오버라이드가 가능한건가? 싶기도하고 abstract는 또 뭘까 싶었다.
✅ 1. 꼭 virtual을 써야 override가 가능한가?
👉 네, 맞습니다.
- override 키워드는 반드시 부모 클래스에서 virtual, abstract, 또는 override로 선언된 메서드만 재정의할 수 있어요.
- 즉, virtual 없이 그냥 만든 메서드는 자식 클래스에서 override 할 수 없습니다.
class Parent
{
public void Speak() // virtual이 아님
{
Console.WriteLine("부모가 말합니다");
}
}
class Child : Parent
{
// ❌ 오류! override 불가능
public override void Speak()
{
Console.WriteLine("자식이 말합니다");
}
}
✅ 2. 그럼 abstract는 뭐야?
👉 abstract는 부모 클래스에서 "이건 반드시 자식 클래스가 직접 구현해야 해!" 라고 강제할 때 사용해요.
📌 특징 비교
구분 | virtual | abstract |
기본 구현 | ✅ 있음 | ❌ 없음 (구현 금지) |
재정의 여부 | 자식 클래스에서 재정의 선택 가능 | 자식 클래스에서 반드시 override 해야 함 |
용도 | "기본 구현은 있지만, 필요하면 바꿔 써도 돼" | "이건 자식이 반드시 구현해야 돼" |
🎯 코드 예시로 완전 비교
🔹 virtual 예시
class Parent
{
public virtual void Greet()
{
Console.WriteLine("Hello from Parent");
}
}
class Child : Parent
{
public override void Greet()
{
Console.WriteLine("Hello from Child");
}
}
🔹 abstract 예시
abstract class Animal
{
public abstract void Speak(); // 구현 ❌
}
class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("멍멍!");
}
}
→ Speak()는 무조건 자식이 override 해야 함.
→ 안 하면 컴파일 오류 발생
🧠 요약 정리
질문답변
virtual 없이 override 가능? | ❌ 불가능 (virtual, abstract, 또는 override 필요) |
abstract는 뭐야? | 자식 클래스가 반드시 구현해야 하는 메서드를 정의할 때 사용 |
virtual과 abstract 차이는? | 기본 구현 유무 + 오버라이드 강제 여부의 차이 |
❓
그러면 굳이 abstract를 써야하는 이유가있나?..싶었다..
그럼 도대체 두개의 차이점이 뭘까..
✅ 핵심 요약: 둘의 의도와 차이
항목 | virtual | abstract |
기본 구현 | 있다 → 자식이 그대로 써도 됨 | 없다 → 자식이 반드시 구현해야 함 |
자식에서 override | 선택 가능 | 강제 |
설계 의도 | "기본 동작이 있지만, 필요하면 바꿔 써" | "이건 네가 알아서 반드시 만들어" |
목적 | 유연성 | 강제성, 명확한 계약 |
사용 가능 클래스 | 일반 클래스, 추상 클래스 | 추상 클래스에서만 사용 가능 |
장점 | 코드 재사용 가능 | 설계 실수 방지, 역할 명확 |
단점 | 재정의 안 하면 예측 어려움 | 반복적 구현 필요 (유지비 증가) |
🎯 예시 비교로 감 잡기
✅ 예제 상황: "게임 캐릭터"
1. virtual 예시
class Character
{
public virtual void Attack()
{
Console.WriteLine("기본 공격: 펀치!");
}
}
class Knight : Character
{
public override void Attack()
{
Console.WriteLine("검으로 공격!");
}
}
class Villager : Character
{
// Attack() 안 바꿔도 됨 → 기본 공격 그대로 사용
}
➡️ Villager는 특별한 공격이 없으니 virtual 덕분에 기본 공격을 그대로 써도 괜찮음
➡️ 유연함이 중요할 때 → virtual
2. abstract 예시
abstract class Character
{
public abstract void Attack(); // 반드시 구현!
}
class Knight : Character
{
public override void Attack()
{
Console.WriteLine("검으로 공격!");
}
}
class Villager : Character
{
// ❌ Attack() 안 만들면 컴파일 에러 → 강제
}
➡️ 모든 캐릭터는 반드시 자신만의 공격을 가져야 해! → 이런 명확한 룰을 강제할 때 abstract
➡️ 설계 실수 방지하고 싶을 때 → abstract
📌 그럼 뭐가 더 효율적인가?
👉 "효율"은 상황에 따라 달라요.
기본 동작은 있지만, 바꿀 수 있도록 열어두고 싶다 | ✅ virtual |
꼭 자식이 직접 구현해야만 의미가 있다 | ✅ abstract |
공통 로직은 부모에서 쓰고, 일부만 다르게 처리하고 싶다 | ✅ 템플릿 메서드 + abstract + virtual 혼용 |
🧠 결론
- virtual → "기본은 줄게, 필요하면 바꿔 써"
→ 재사용 중심, 유연한 구조 - abstract → "이건 네가 반드시 해"
→ 계약 기반 설계, 실수 방지, 역할 명확화
🎯 기억하기 쉽게 요약하면:
"바꿔도 되고 안 바꿔도 되면 virtual,
무조건 바꿔야 한다면 abstract"
✅
음...정확하게 뭔가 와닿지는 않지만 캐릭터의 스킬이나 공격스킬로 따지자면
virtual - 기본 공격 스타일 메이플의 기본공격정도이지 않을까 싶다. 기본적으로 찌르기,내려치기,올려치기 등등 기술을 사용할때 정도?
abstract - 메이플에서의 전사,궁수,해적,마법사,도적 등등 전직했을때의 각각의 스킬로 사용할때정도로 정의되지 않을까 싶다!!
🔥 비유 리뷰
virtual | 기본 공격 스타일 (찌르기, 내려치기 등) | "기본은 이거야, 하지만 바꿔도 돼" → 재정의 가능, 선택적 |
abstract | 전직 클래스별 고유 스킬 (전사, 궁수, 해적 등) | "반드시 직접 구현해야 해" → 자식 클래스가 구현 강제됨 |
→ 이 비유는 진짜로 설계 철학에 딱 맞아.
라고 GPT가 친절하게 설명해주네여ㅎㅎ
반응형