C# - Parent obj = new Child(); 메모리는 어떻게 될까? & 다형성
Parent obj = new Child(); 메모리는 어떻게 될까?
🤔 질문
클래스 상속을 사용할 때,
Parent obj = new Child();
이렇게 부모 타입으로 자식 객체를 참조하면,
메모리는 부모 클래스만큼만 잡히는 걸까? 아니면 자식 클래스 전체가 메모리에 올라갈까?
✅ 결론 먼저!
👉 메모리에는 자식 클래스 전체가 생성된다.
즉, **new Child()**를 하면
자식 클래스가 부모를 포함한 상태로 메모리에 만들어지고,
참조 변수(obj)가 그 전체 객체를 가리키게 된다.
🧠 왜 그렇게 되는 걸까?
1. new Child()는 "Child 인스턴스를 생성"하는 코드다
- 여기서 생성되는 객체는 무조건 Child 전체 클래스
- Child는 내부적으로 Parent의 멤버도 다 포함하고 있음
(상속이란 게 그런 것!)
💡 즉, 메모리에는 Parent + Child 모든 멤버가 존재
2. Parent obj는 “부모 타입의 변수”일 뿐이다
- 이 변수는 Child 객체 전체를 가리키지만,
사용할 수 있는 기능(메서드, 필드)은 Parent에 선언된 것만이다.
obj.SomeChildOnlyMethod(); // ❌ 오류 — Parent에 없기 때문
((Child)obj).SomeChildOnlyMethod(); // ✅ 캐스팅하면 가능
❓
여기에서 바로 위에 코드가 이해가 안되는데
Parent obj = new Child(); | 자식 객체를 부모 타입 변수에 담음 |
obj.SomeChildOnlyMethod(); | ❌ 불가 — 부모 타입엔 없음 |
((Child)obj).SomeChildOnlyMethod(); | ✅ 가능 — 형변환해서 자식 메서드 호출 |
✅
이렇게 설명해주니 이해가 되는듯합니다! 부모타입에는 없는 메서드를 호출하려고하니
형변환을해서 자식 메서드를 호출한다고 하는거같아요!
3. 그럼 왜 이렇게 쓰는 걸까?
이런 식으로 부모 타입으로 자식 객체를 참조하는 이유는 다형성(polymorphism) 때문이다!
- 공통된 부모 타입을 이용하면 여러 자식 객체를 하나의 타입으로 다룰 수 있음
- 예를 들어:
List<Parent> characters = new List<Parent>();
characters.Add(new Warrior());
characters.Add(new Magician());
foreach (var c in characters)
{
c.Move(); // 각 클래스의 오버라이딩된 Move가 실행됨
c.Attack(); // 다형성 발동!
}
🧠 이게 바로 다형성: 하나의 타입(Parent)으로 여러 타입(Warrior, Magician)을 다루는 방식
💡 정리: 메모리와 동작 구조
Parent obj = new Child();
메모리 구조:
[ Parent의 멤버 | Child의 멤버 ]
obj 참조:
↑
Parent 타입의 참조라서 Parent 멤버까지만 직접 접근 가능
(단, override된 메서드는 실제 Child의 것이 실행됨!)
🔍 실습 예제
class Parent
{
public virtual void SayHello()
{
Console.WriteLine("안녕하세요. 부모입니다.");
}
}
class Child : Parent
{
public override void SayHello()
{
Console.WriteLine("안녕하세요. 자식입니다.");
}
public void OnlyChildMethod()
{
Console.WriteLine("자식만의 기능!");
}
}
Parent obj1 = new Parent();
obj1.SayHello(); // → 안녕하세요. 부모입니다.
Child obj2 = new Child();
obj2.SayHello(); // → 안녕하세요. 자식입니다.
Parent obj3 = new Child();
obj3.SayHello(); // → 안녕하세요. 자식입니다. (다형성 발동)
((Child)obj3).OnlyChildMethod(); // → 자식만의 기능!
✅ 마무리 요약
코드 | 메모리 생성 | 사용할 수 있는 멤버 |
new Parent() | Parent만 | Parent 멤버만 |
new Child() | Parent + Child | Child 멤버 전부 |
Parent obj = new Child() | Parent + Child | Parent 멤버만 직접 사용 (다형성 O) |
📝 한 줄 요약
부모 타입으로 자식 객체를 참조해도,
메모리는 자식 전체가 생성되며,
실행 시 다형성에 따라 자식 메서드가 호출된다.
❓
다형성이 제대로 이해되지 않는다 흠.. 다시 한번 물어보자.
좋아, 이제 진짜 핵심 중의 핵심으로 왔어.
많은 사람이 객체지향에서 **“다형성(polymorphism)”**이라는 단어를 듣고
**“뭔가 중요한 것 같긴 한데… 솔직히 감이 안 잡혀”**라고 느끼거든.
지금 딱 그런 시점에 온 거야 —
지금부터 진짜 이해되는 방식으로 다형성을 설명해줄게 👇
✅ 다형성이란?
"같은 타입(부모 타입)으로 여러 객체(자식 객체)를 같은 방식으로 다루지만,
실제로는 각 객체에 맞는 동작이 실행되는 것"
🔥 핵심 포인트
- "부모 타입 하나로 다양한 자식 객체를 처리한다." → 다형성
- 다형성은 “형태는 같지만 행동은 다르게” 동작함
🎯 예제로 설명해볼게
class Animal
{
public virtual void Speak()
{
Console.WriteLine("동물이 소리를 냅니다.");
}
}
class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("멍멍!");
}
}
class Cat : Animal
{
public override void Speak()
{
Console.WriteLine("야옹!");
}
}
List<Animal> animals = new List<Animal>();
animals.Add(new Dog());
animals.Add(new Cat());
foreach (Animal a in animals)
{
a.Speak(); // ??? 어떤 소리가 나올까?
}
👉 출력 결과:
멍멍!
야옹!
🔍 여기서 중요한 건 → a.Speak()는 전부 Animal 타입인데,
실제로는 Dog, Cat 각각의 메서드가 실행된다!
➡️ 이게 바로 다형성(polymorphism)
➡️ 같은 코드(a.Speak()) → 다양한 동작
🧠 비유로 이해해보기
부모 타입 = 콘센트
자식 객체 = 다양한 기기 (선풍기, 에어컨, 충전기 등)
- 콘센트 하나(Animal 변수)로 어떤 기기(Dog, Cat)를 꽂든,
- 각각의 기기는 자기 기능대로 작동
콘센트.작동() →
→ 선풍기면 바람 나옴
→ 충전기면 충전됨
→ 에어컨이면 냉풍 나옴
➡️ 인터페이스는 같고, 동작은 다름
➡️ 다형성!
✅ 왜 중요한가?
이유 | 설명 |
유지보수가 쉬워짐 | 부모 타입 기준으로 다룰 수 있어서 코드가 유연해짐 |
코드 중복 줄임 | 동일한 인터페이스/부모 클래스로 묶을 수 있음 |
확장성 좋아짐 | 새로운 자식 클래스가 생겨도 부모 타입만 알면 됨 |
🎮 게임 예제
abstract class Enemy
{
public abstract void Attack();
}
class Slime : Enemy
{
public override void Attack() => Debug.Log("슬라임 점프 공격!");
}
class Dragon : Enemy
{
public override void Attack() => Debug.Log("드래곤 불뿜기!");
}
List<Enemy> enemies = new List<Enemy>() {
new Slime(), new Dragon()
};
foreach (Enemy e in enemies)
{
e.Attack(); // 각 몬스터의 고유 공격 실행됨!
}
✅ 한 줄 정리
다형성은 **“하나의 타입(부모)으로 여러 타입(자식)을 다루면서도,
각 객체에 맞는 동작을 실행하는 객체지향의 핵심 기능”**이야.
✅
그렇다고한다! 아직도 와닿지는 않지만 이해는 됐다. 직접 개발해봐야 느낌이 올듯하다. 확실히 나중에 개발하면 코드에 대한 유지보수나 여러 기능들 만들고 사용할때 많이 사용하니 잘 알아둬야 할듯하다.