C#

C# - Parent obj = new Child(); 메모리는 어떻게 될까? & 다형성

Dev_Jen 2025. 7. 3. 15:59
반응형

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();  // 각 몬스터의 고유 공격 실행됨!
}

✅ 한 줄 정리

다형성은 **“하나의 타입(부모)으로 여러 타입(자식)을 다루면서도,
각 객체에 맞는 동작을 실행하는 객체지향의 핵심 기능”**이야.

 

그렇다고한다! 아직도 와닿지는 않지만 이해는 됐다. 직접 개발해봐야 느낌이 올듯하다. 확실히 나중에 개발하면 코드에 대한 유지보수나 여러 기능들 만들고 사용할때 많이 사용하니 잘 알아둬야 할듯하다.

반응형