λ°˜μ‘ν˜•

🧱 ν΄λž˜μŠ€μ™€ 객체의 핡심 κ°œλ… 정리

πŸ“Œ 객체지ν–₯ ν”„λ‘œκ·Έλž˜λ°(OOP)의 4κ°€μ§€ 핡심 원칙

  • μΊ‘μŠν™”(Encapsulation)
    κ΄€λ ¨λœ 데이터와 κΈ°λŠ₯을 ν•˜λ‚˜μ˜ λ‹¨μœ„λ‘œ λ¬Άκ³  μ™ΈλΆ€λ‘œλΆ€ν„° μˆ¨κΈ΄λ‹€. ν•„λ“œμ™€ λ©”μ„œλ“œλ₯Ό 클래슀 내뢀에 감좰 μ•ˆμ •μ„±κ³Ό μœ μ§€λ³΄μˆ˜μ„±μ„ 높인닀.
  • 상속(Inheritance)
    κΈ°μ‘΄ 클래슀의 속성과 κΈ°λŠ₯을 λ¬Όλ €λ°›μ•„ μƒˆλ‘œμš΄ 클래슀λ₯Ό λ§Œλ“ λ‹€. μ½”λ“œμ˜ μž¬μ‚¬μš©μ„±μ„ 높이고 계측적인 섀계λ₯Ό κ°€λŠ₯ν•˜κ²Œ ν•œλ‹€.
  • λ‹€ν˜•μ„±(Polymorphism)
    같은 μ΄λ¦„μ˜ λ©”μ„œλ“œκ°€ λ‹€μ–‘ν•œ λ°©μ‹μœΌλ‘œ λ™μž‘ν•  수 μžˆλ„λ‘ ν•œλ‹€. μ˜€λ²„λΌμ΄λ”©κ³Ό μ˜€λ²„λ‘œλ”©μ„ 톡해 μœ μ—°ν•œ μ½”λ“œ κ΅¬ν˜„μ΄ κ°€λŠ₯ν•˜λ‹€.
  • 좔상화(Abstraction)
    λΆˆν•„μš”ν•œ μ„ΈλΆ€ 사항은 숨기고 핡심 κΈ°λŠ₯만 λ…ΈμΆœν•œλ‹€. μ‚¬μš©μž μž…μž₯μ—μ„œ ν•„μš”ν•œ μ •λ³΄λ§Œ μ œκ³΅ν•΄ μ½”λ“œμ˜ κ°„κ²°μ„±κ³Ό λͺ…확성을 높인닀.

🧩 ν΄λž˜μŠ€μ™€ 객체

  • 클래슀(Class)
    객체λ₯Ό λ§Œλ“€κΈ° μœ„ν•œ 섀계도이닀. ν•„λ“œ(속성)와 λ©”μ„œλ“œ(행동)둜 κ΅¬μ„±λœλ‹€. 예: λΆ•μ–΄λΉ΅ ν‹€
  • 객체(Object)
    ν΄λž˜μŠ€μ— κΈ°λ°˜ν•΄ λ§Œλ“€μ–΄μ§„ 싀체이닀. 각 κ°μ²΄λŠ” 독립적인 μƒνƒœλ₯Ό κ°€μ§„λ‹€. 예: λΆ•μ–΄λΉ΅

πŸ› οΈ 클래슀의 ꡬ성 μš”μ†Œ

  • ν•„λ“œ (Field): 객체의 데이터λ₯Ό μ €μž₯ν•˜λŠ” λ³€μˆ˜
  • λ©”μ„œλ“œ (Method): 객체가 μˆ˜ν–‰ν•˜λŠ” λ™μž‘
  • μƒμ„±μž (Constructor): 객체λ₯Ό μ΄ˆκΈ°ν™”ν•  λ•Œ μ‹€ν–‰λ˜λŠ” 특수 λ©”μ„œλ“œ
  • μ†Œλ©Έμž (Destructor): 객체가 μ†Œλ©Έλ  λ•Œ ν˜ΈμΆœλ˜λŠ” 특수 λ©”μ„œλ“œ

🧱 클래슀 μ„ μ–Έκ³Ό μΈμŠ€ν„΄μŠ€ 생성

class Person
{
    public string Name;
    public int Age;

    public void PrintInfo()
    {
        Console.WriteLine("Name: " + Name);
        Console.WriteLine("Age: " + Age);
    }
}

// μΈμŠ€ν„΄μŠ€ 생성
Person p = new Person();
p.Name = "John";
p.Age = 30;
p.PrintInfo();

🧾 클래슀 vs ꡬ쑰체

ν•­λͺ© 클래슀 ꡬ쑰체
νƒ€μž… μ°Έμ‘°ν˜•(Reference Type) κ°’ν˜•(Value Type)
μ €μž₯ μœ„μΉ˜ νž™(Heap) μŠ€νƒ(Stack)
상속 지원함 μ§€μ›ν•˜μ§€ μ•ŠμŒ
생성 방식 new ν‚€μ›Œλ“œ ν•„μš” new 없이도 μ‚¬μš© κ°€λŠ₯
μš©λ„ λ³΅μž‘ν•œ 데이터 ꡬ쑰 κ°„λ‹¨ν•œ 데이터 μ €μž₯
 

πŸ”’ μ ‘κ·Ό μ œν•œμž

  • public: μ–΄λ””μ„œλ“  μ ‘κ·Ό κ°€λŠ₯
  • private: 클래슀 λ‚΄λΆ€μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯
  • protected: ν΄λž˜μŠ€μ™€ κ·Έ μžμ‹ ν΄λž˜μŠ€μ—μ„œλ§Œ μ ‘κ·Ό κ°€λŠ₯

🧭 ν”„λ‘œνΌν‹°(Property)

ν•„λ“œμ— λŒ€ν•œ 접근을 μ œμ–΄ν•˜κ³  μœ νš¨μ„± 검사λ₯Ό μΆ”κ°€ν•  수 μžˆλŠ” λ©”μ»€λ‹ˆμ¦˜.

 

    1. ν”„λ‘œνΌν‹°λž€?
    • ν”„λ‘œνΌν‹°λŠ” 클래슀 λ©€λ²„λ‘œμ„œ, 객체의 ν•„λ“œ 값을 μ½κ±°λ‚˜ μ„€μ •ν•˜λŠ”λ° μ‚¬μš©λ˜λŠ” μ ‘κ·Όμž(Accessor) λ©”μ„œλ“œμ˜ μ‘°ν•©μž…λ‹ˆλ‹€.
    • 객체의 ν•„λ“œμ— 직접 μ ‘κ·Όν•˜μ§€ μ•Šκ³ , κ°„μ ‘μ μœΌλ‘œ 값을 μ„€μ •ν•˜κ±°λ‚˜ 읽을 수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.
    • ν•„λ“œμ— λŒ€ν•œ μ ‘κ·Ό μ œμ–΄μ™€ 데이터 μœ νš¨μ„± 검사 등을 μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • ν”„λ‘œνΌν‹°λŠ” ν•„λ“œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ 객체의 μƒνƒœλ₯Ό λ‚˜νƒ€λ‚΄λŠ” 데이터 역할을 ν•˜μ§€λ§Œ, μ™ΈλΆ€μ—μ„œ μ ‘κ·Όν•  λ•Œ 좔가적인 λ‘œμ§μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    1. ν”„λ‘œνΌν‹° ꡬ문
    • ν”„λ‘œνΌν‹°λŠ” getκ³Ό set μ ‘κ·Όμžλ₯Ό μ‚¬μš©ν•˜μ—¬ 값을 읽고 μ„€μ •ν•˜λŠ” λ™μž‘μ„ μ •μ˜ν•©λ‹ˆλ‹€.
    • get μ ‘κ·ΌμžλŠ” ν”„λ‘œνΌν‹°μ˜ 값을 λ°˜ν™˜ν•˜κ³ , set μ ‘κ·ΌμžλŠ” ν”„λ‘œνΌν‹°μ˜ 값을 μ„€μ •ν•©λ‹ˆλ‹€.
    • ν•„μš”μ— 따라 get λ˜λŠ” set μ ‘κ·Όμž 쀑 ν•˜λ‚˜λ₯Ό μƒλž΅ν•˜μ—¬ 읽기 μ „μš© λ˜λŠ” μ“°κΈ° μ „μš© ν”„λ‘œνΌν‹°λ₯Ό μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
[μ ‘κ·Ό μ œν•œμž] [데이터 νƒ€μž…] ν”„λ‘œνΌν‹°λͺ…
{
    get
    {
        // ν•„λ“œλ₯Ό λ°˜ν™˜ν•˜κ±°λ‚˜ λ‹€λ₯Έ 둜직 μˆ˜ν–‰
    }
    set
    {
        // ν•„λ“œμ— 값을 μ„€μ •ν•˜κ±°λ‚˜ λ‹€λ₯Έ 둜직 μˆ˜ν–‰
    }
}

 

  • ν”„λ‘œνΌν‹° μ‚¬μš© μ˜ˆμ‹œ
  • λ‹€μŒμ€ Player 클래슀의 이름과 λ ˆλ²¨μ„ λ‚˜νƒ€λ‚΄λŠ” nameκ³Ό level ν•„λ“œλ₯Ό μΊ‘μŠν™”ν•œ ν”„λ‘œνΌν‹°μ˜ μ˜ˆμ‹œ.
class Person
{
    private string name;
    private int age;

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public int Age
    {
        get { return age; }
        set { age = value; }
    }
}
Person person = new Person();
person.Name = "John";   // Name ν”„λ‘œνΌν‹°μ— κ°’ μ„€μ •
person.Age = 25;        // Age ν”„λ‘œνΌν‹°μ— κ°’ μ„€μ •

Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");  // Nameκ³Ό Age

 

ν”„λ‘œνΌν‹° μ ‘κ·Ό μ œν•œμž 적용 & μœ νš¨μ„± 검사 예제

class Person
{
    private string name;
    private int age;

    public string Name
    {
        get { return name; }
        private set { name = value; }
    }

    public int Age
    {
        get { return age; }
        set
        {
            if (value >= 0)
                age = value;
        }
    }
}
Person person = new Person();
person.Name = "John";     // 컴파일 였λ₯˜: Name ν”„λ‘œνΌν‹°μ˜ set μ ‘κ·ΌμžλŠ” privateμž…λ‹ˆλ‹€.
person.Age = -10;         // μœ νš¨μ„± 검사에 μ˜ν•΄ λ‚˜μ΄ 값이 μ„€μ •λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");  // Nameκ³Ό Age ν”„λ‘œνΌν‹°μ— μ ‘κ·Όν•˜μ—¬ 값을 좜λ ₯ν•©λ‹ˆλ‹€.

 

  • μžλ™ ν”„λ‘œνΌν‹° (Auto Property)
    • μžλ™ ν”„λ‘œνΌν‹°λŠ” ν”„λ‘œνΌν‹°λ₯Ό κ°„λ‹¨ν•˜κ²Œ μ •μ˜ν•˜κ³  μ‚¬μš©ν•  수 μžˆλŠ” νŽΈλ¦¬ν•œ κΈ°λŠ₯μž…λ‹ˆλ‹€.
    • ν•„λ“œμ˜ μ„ μ–Έκ³Ό μ ‘κ·Όμž λ©”μ„œλ“œμ˜ κ΅¬ν˜„μ„ μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ μ²˜λ¦¬ν•˜μ—¬ κ°œλ°œμžκ°€ κ°„λ‹¨ν•œ ꡬ문으둜 ν”„λ‘œνΌν‹°λ₯Ό μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
[μ ‘κ·Ό μ œν•œμž] [데이터 νƒ€μž…] ν”„λ‘œνΌν‹°λͺ… { get; set; }

 

μ•„λž˜λŠ” μžλ™ ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•œ μ˜ˆμ‹œ.

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
Person person = new Person();
person.Name = "John";     // 값을 μ„€μ •
person.Age = 25;          // 값을 μ„€μ •

Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");  // 값을 읽어 좜λ ₯

 

Tip

  • ν΄λž˜μŠ€μ™€ 객체λ₯Ό μ‚¬μš©ν•˜μ—¬ ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•  λ•Œ, 객체 μ§€ν–₯ ν”„λ‘œκ·Έλž˜λ°(OOP)의 원칙을 지킀도둝 λ…Έλ ₯ν•΄μ•Ό ν•©λ‹ˆλ‹€. μΊ‘μŠν™”, 상속관계, λ‹€ν˜•μ„± λ“± OOP κ°œλ…μ„ μ΄ν•΄ν•˜κ³  ν™œμš©ν•˜μ—¬ μœ μ§€λ³΄μˆ˜μ„±μ΄ λ†’κ³  μž¬μ‚¬μš© κ°€λŠ₯ν•œ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • Propertiesλ₯Ό μ‚¬μš©ν•˜μ—¬ ν•„λ“œ 접근을 μ œμ–΄ν•˜λ©΄, μ½”λ“œμ˜ μ•ˆμ •μ„±κ³Ό 가독성을 높일 수 μžˆμŠ΅λ‹ˆλ‹€.
  • 클래슀의 μ ‘κ·Ό μ œν•œμžλ₯Ό 적절히 μ‚¬μš©ν•˜μ—¬ ν•„μš”ν•œ λΆ€λΆ„λ§Œ μ™ΈλΆ€μ—μ„œ μ ‘κ·Ό κ°€λŠ₯ν•˜λ„λ‘ μ„€μ •ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

πŸ’‘ μƒμ„±μžμ™€ μ†Œλ©Έμž

  • μƒμ„±μž: 객체 생성 μ‹œ μžλ™ μ‹€ν–‰. μ΄ˆκΈ°ν™” μž‘μ—… μˆ˜ν–‰.
    μ˜€λ²„λ‘œλ”©μ„ 톡해 λ‹€μ–‘ν•œ λ°©μ‹μœΌλ‘œ 객체 μ΄ˆκΈ°ν™” κ°€λŠ₯.
  • μ†Œλ©Έμž: 객체가 μ†Œλ©Έλ  λ•Œ μžλ™ 호좜. λ¦¬μ†ŒμŠ€ ν•΄μ œ λ“±μ˜ μž‘μ—… μˆ˜ν–‰.

 

🧬 상속과 λ‹€ν˜•μ„±μ˜ 핡심 이해

🧾 상속(Inheritance)

  • μ •μ˜
    κΈ°μ‘΄ 클래슀(λΆ€λͺ¨ 클래슀)의 속성과 κΈ°λŠ₯을 μƒˆλ‘œμš΄ 클래슀(μžμ‹ 클래슀)κ°€ λ¬Όλ €λ°›λŠ” κ°œλ…μ΄λ‹€.
  • μž₯점
    • μ½”λ“œ μž¬μ‚¬μš©μ„± ν–₯상
    • 계측적 ꡬ쑰 ν˜•μ„±
    • μœ μ§€λ³΄μˆ˜ 용이
  • νŠΉμ§•
    • C#은 단일 μƒμ†λ§Œ 지원
    • μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 닀쀑 상속 효과 κ΅¬ν˜„ κ°€λŠ₯
    • λΆ€λͺ¨ 클래슀의 public 및 protected λ©€λ²„λŠ” μžμ‹ ν΄λž˜μŠ€μ—μ„œ μ ‘κ·Ό κ°€λŠ₯
    • λ©”μ„œλ“œλŠ” μž¬μ •μ˜(Override)ν•˜μ—¬ μƒˆλ‘œμš΄ λ™μž‘ κ΅¬ν˜„ κ°€λŠ₯
  • κΈ°λ³Έ μ˜ˆμ‹œ
class Animal
{
    public void Eat() => Console.WriteLine("λ¨ΉλŠ”λ‹€");
}

class Dog : Animal
{
    public void Bark() => Console.WriteLine("μ§–λŠ”λ‹€");
}

Dog dog = new Dog();
dog.Eat();  // μƒμ†λœ λ©”μ„œλ“œ
dog.Bark(); // μžμ‹ 클래슀 고유 λ©”μ„œλ“œ

πŸŒ€ λ‹€ν˜•μ„±(Polymorphism)

  • μ •μ˜
    λ™μΌν•œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 μ—¬λŸ¬ ν΄λž˜μŠ€κ°€ λ‹€μ–‘ν•œ λ°©μ‹μœΌλ‘œ λ™μž‘ν•˜λ„λ‘ λ§Œλ“œλŠ” 객체지ν–₯ 원칙이닀.
  • μ’…λ₯˜
    • μ˜€λ²„λ‘œλ”©(Overloading): 같은 이름, λ‹€λ₯Έ λ§€κ°œλ³€μˆ˜μ˜ λ©”μ„œλ“œλ₯Ό μ—¬λŸ¬ 개 μ •μ˜
    • μ˜€λ²„λΌμ΄λ”©(Overriding): λΆ€λͺ¨ 클래슀의 λ©”μ„œλ“œλ₯Ό μžμ‹ ν΄λž˜μŠ€κ°€ μž¬μ •μ˜ν•˜μ—¬ μ‹€ν–‰ λ‚΄μš© λ³€κ²½

πŸ” μ˜€λ²„λΌμ΄λ”©κ³Ό virtual / override ν‚€μ›Œλ“œ

  • virtual: λΆ€λͺ¨ ν΄λž˜μŠ€μ—μ„œ ν•΄λ‹Ή λ©”μ„œλ“œκ°€ μ˜€λ²„λΌμ΄λ”© κ°€λŠ₯ν•˜λ‹€κ³  λͺ…μ‹œ
  • override: μžμ‹ ν΄λž˜μŠ€μ—μ„œ λΆ€λͺ¨μ˜ virtual λ©”μ„œλ“œλ₯Ό μž¬μ •μ˜ν•  λ•Œ μ‚¬μš©
class Unit
{
    public virtual void Move() => Console.WriteLine("두 발둜 κ±·κΈ°");
}

class Zergling : Unit
{
    public override void Move() => Console.WriteLine("λ„€ 발둜 κ±·κΈ°");
}
  • μ‹€ν–‰ μ˜ˆμ‹œ
List<Unit> units = new List<Unit>();
units.Add(new Unit());
units.Add(new Zergling());

foreach (Unit unit in units)
{
    unit.Move();  // 각각 λ‹€λ₯΄κ²Œ 좜λ ₯됨
}

🧰 좔상 ν΄λž˜μŠ€μ™€ 좔상 λ©”μ„œλ“œ

  • 좔상 클래슀 (abstract class)
    직접 객체λ₯Ό λ§Œλ“€ 수 μ—†κ³ , λ°˜λ“œμ‹œ 상속받아 κ΅¬ν˜„ν•΄μ•Ό ν•˜λŠ” 클래슀
  • 좔상 λ©”μ„œλ“œ (abstract method)
    λ³Έλ¬Έ 없이 μ„ μ–Έλ§Œ μ‘΄μž¬ν•˜λ©°, μžμ‹ ν΄λž˜μŠ€κ°€ λ°˜λ“œμ‹œ μ˜€λ²„λΌμ΄λ”©ν•΄μ•Ό 함
abstract class Shape
{
    public abstract void Draw();
}

class Circle : Shape
{
    public override void Draw() => Console.WriteLine("원을 κ·Έλ¦°λ‹€");
}
  • μ‚¬μš© 예
List<Shape> shapes = new List<Shape> { new Circle(), new Square(), new Triangle() };

foreach (Shape shape in shapes)
{
    shape.Draw();  // 각각의 λ„ν˜•μ— 맞게 λ™μž‘
}

πŸ”„ μ˜€λ²„λ‘œλ”©κ³Ό μ˜€λ²„λΌμ΄λ”© 비ꡐ

ꡬ뢄 μ˜€λ²„λ‘œλ”©(Overloading) μ˜€λ²„λΌμ΄λ”©(Overriding)
μ •μ˜ 같은 이름, λ‹€λ₯Έ λ§€κ°œλ³€μˆ˜ λΆ€λͺ¨ λ©”μ„œλ“œ μž¬μ •μ˜
상속 ν•„μš” μ—†μŒ λ°˜λ“œμ‹œ 상속 관계 ν•„μš”
ν‚€μ›Œλ“œ μ—†μŒ virtual, override μ‚¬μš©
μ˜ˆμ‹œ    
// μ˜€λ²„λ‘œλ”©
int Add(int a, int b) => a + b;
int Add(int a, int b, int c) => a + b + c;

// μ˜€λ²„λΌμ΄λ”©
public class Shape
{
    public virtual void Draw() => Console.WriteLine("λ„ν˜• 그리기");
}

public class Circle : Shape
{
    public override void Draw() => Console.WriteLine("원 그리기");
}

 

λ°˜μ‘ν˜•