전체 코드
using System.ComponentModel;
using System.Numerics;
using System.Threading;
using System.Collections.Generic;
namespace CSharp
{
internal class Program
{
abstract class Monster
{
public abstract void Shout();
}
interface IFlyable
{
void Fly();
}
class Orc : Monster
{
public override void Shout()
{
Console.WriteLine("록타르 오가르!");
}
}
class Skeleton : Monster
{
public override void Shout()
{
Console.WriteLine("꾸에에엑");
}
}
class FlyableOrc : Orc, IFlyable
{
public void Fly()
{
Console.WriteLine("오크가 난다");
}
}
static void DoFly(IFlyable flyable)
{
flyable.Fly();
}
static void Main(string args)
{
IFlyable flyable = new FlyableOrc();
FlyableOrc orc = new FlyableOrc();
DoFly(flyable);
DoFly(orc);
}
}
}
1️⃣ 추상 클래스(abstract class) 개념 정리
| 구분 | 설명 | 비유 |
|---|
| 목적 | 상속받는 자식 클래스들에게 공통된 틀 제공 | 템플릿 |
| 특징1 | 추상 메서드(몸통 없는 메서드) 가질 수 있음 | 강제 약속 |
| 특징2 | 구현된 메서드나 필드도 포함 가능 | 부분 완성된 템플릿 |
| 특징3 | 객체 생성 불가 (인스턴스화 불가) | 자체 사용 불가 |
| 특징4 | 단일 상속만 가능 | 부모는 한 명 |
✔️ 추상 클래스 예제 및 해설
abstract class Monster
{
public abstract void Shout();
}
abstract 키워드: 추상 클래스임을 명시
- 추상 메서드:
{} 없이 선언, 자식이 반드시 구현해야 함
- 인스턴스화 불가:
new Monster()는 에러
2️⃣ 인터페이스(interface) 개념 정리
| 구분 | 설명 | 비유 |
|---|
| 목적 | 구현해야 할 기능의 목록 제공 | 체크리스트 |
| 특징1 | 모든 메서드는 기본적으로 추상 메서드 | 몸통 없음 |
| 특징2 | 다중 상속 가능 | 여러 체크리스트 |
| 특징3 | 필드, 구현 메서드 없음 (C# 최신버전 일부 가능하나 일반적으론 없음) | 데이터 없음 |
| 특징4 | 인터페이스 자체 객체 생성 불가 | new 불가 |
✔️ 인터페이스 예제 및 해설
interface IFlyable
{
void Fly();
}
interface: 인터페이스 선언 키워드
- 접근 지정자 안 붙임
- 몸통 없는 메서드만 정의 (구현은 자식 클래스가)
4️⃣ 다중 상속 문제 (C#이 막는 이유)
❌ 아래 코드는 불가능 (다중 상속 금지)
class SkeletonOrc : Orc, Skeleton
{
}
💥 문제점: "죽음의 다이아몬드 문제"
- Orc와 Skeleton 모두 Monster 상속
- 각자 Shout()를 다르게 구현
- SkeletonOrc는 어떤 Shout()를 상속받아야 할지 모호
- 이런 구조적 혼란 때문에 C#은 다중 상속 금지
5️⃣ 인터페이스 다중 상속 예시 (가능)
interface IFlyable { void Fly(); }
interface ISwimmable { void Swim(); }
class Duck : IFlyable, ISwimmable
{
public void Fly() { Console.WriteLine("날다"); }
public void Swim() { Console.WriteLine("수영하다"); }
}
- 인터페이스는 다중 상속 가능
- 실제 구현은 Duck이 각각 알아서 처리