언어/C#

[C#] 객체지향 프로그래밍 핵심 개념

달시_Dalsi 2024. 12. 18. 03:39
728x90

1. 클래스(Class)와 객체(Object)

정의:

  • 클래스는 객체를 만들기 위한 설계도입니다.
  • 객체는 클래스의 인스턴스로, 실제 메모리 공간에 할당된 데이터입니다.

예시 코드:

public class Car
{
    public string Brand;
    public void Drive()
    {
        Debug.Log(Brand + " is driving.");
    }
}

public class Test
{
    void Start()
    {
        Car myCar = new Car(); // 객체 생성
        myCar.Brand = "Toyota";
        myCar.Drive(); // 출력: Toyota is driving.
    }
}
 

왜 필요한가?

  • 클래스를 사용하면 코드를 재사용하고 구조화할 수 있습니다.
  • 객체는 프로그램에서 실제 동작하는 데이터를 다룹니다.

 

2. 상속(Inheritance)

정의:

  • 상속은 기존 클래스의 기능을 물려받아 새로운 클래스를 만들 수 있게 해줍니다.
  • 코드 재사용성과 확장성을 높여줍니다.

예시 코드:

public class Vehicle
{
    public void StartEngine()
    {
        Debug.Log("Engine started.");
    }
}

public class Car : Vehicle
{
    public void Drive()
    {
        Debug.Log("The car is driving.");
    }
}

public class Test
{
    void Start()
    {
        Car myCar = new Car();
        myCar.StartEngine(); // 부모 클래스의 메서드 사용
        myCar.Drive(); // 자식 클래스의 메서드 사용
    }
}

왜 필요한가?

  • 기존 코드를 재사용하면서도, 필요한 부분만 추가하거나 수정할 수 있습니다.

 

3. Virtual과 Override

Virtual

virtual 키워드는 부모 클래스에서 메서드를 정의할 때 사용됩니다. 이 메서드는 자식 클래스에서 재정의(overriding)될 수 있습니다. 즉, 부모 클래스에서는 기본적인 구현을 제공하고, 자식 클래스에서는 그 구현을 바꿀 수 있습니다.

public class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("The animal makes a sound.");
    }
}

위 코드에서 Speak 메서드는 virtual로 정의되어 있습니다. 이를 통해 자식 클래스에서 Speak 메서드를 재정의할 수 있습니다.

 

 

Override

override 키워드는 자식 클래스에서 부모 클래스의 메서드를 재정의할 때 사용됩니다. 자식 클래스는 부모 클래스의 메서드를 자신에게 맞게 구현할 수 있습니다.

public class Dog : Animal
{
    public override void Speak()
    {
        Console.WriteLine("The dog barks.");
    }
}

이 코드에서 Dog 클래스는 Animal 클래스의 Speak 메서드를 재정의하고 있습니다. 이때 override 키워드를 사용하여 부모 클래스에서 정의한 메서드를 새로운 방식으로 변경합니다.

 

 

예시 코드:

public class Animal
{
    public virtual void Speak()
    {
        Debug.Log("Animal makes a sound");
    }
}

public class Dog : Animal
{
    public override void Speak()
    {
        Debug.Log("Dog barks");
    }
}

public class Test
{
    void Start()
    {
        Animal myDog = new Dog();
        myDog.Speak(); // 출력: Dog barks
    }
}

왜 필요한가?

virtual과 override를 활용한 다형성은 객체지향 프로그래밍에서 확장성과 유지보수성을 높이는 중요한 방법입니다. 특히 유니티 개발과 같은 게임 개발에서는 다양한 객체가 동일한 인터페이스를 공유하면서도 각기 다른 동작을 할 수 있도록 만들어, 코드의 유연성을 높이고 새로운 기능을 쉽게 추가할 수 있게 해줍니다.

 

4. 인터페이스(Interface)

정의:

  • 인터페이스는 클래스가 반드시 구현해야 하는 메서드의 청사진을 정의합니다.
  • 여러 클래스를 연결하고 의존성을 줄이는 역할을 합니다.

예시 코드:

public interface IMovable
{
    void Move();
}

public class Car : IMovable
{
    public void Move()
    {
        Debug.Log("Car is moving");
    }
}

public class Character : IMovable
{
    public void Move()
    {
        Debug.Log("Character is walking");
    }
}

public class Test
{
    void Start()
    {
        IMovable movable = new Car();
        movable.Move(); // 출력: Car is moving

        movable = new Character();
        movable.Move(); // 출력: Character is walking
    }
}

왜 필요한가?

  • 여러 클래스에서 동일한 기능을 구현해야 할 때 유연하게 설계할 수 있습니다.

 

5. 추상 클래스(Abstract Class)

정의:

  • 추상 클래스는 객체를 생성할 수 없고, 반드시 상속을 통해서만 사용됩니다.
  • 공통 기능을 구현하고, 일부 기능은 자식 클래스가 구현하도록 강제합니다.

예시 코드:

public abstract class Animal
{
    public void Sleep()
    {
        Debug.Log("Animal is sleeping");
    }
    public abstract void Speak(); // 자식 클래스가 구현해야 함
}

public class Dog : Animal
{
    public override void Speak()
    {
        Debug.Log("Dog barks");
    }
}

public class Test
{
    void Start()
    {
        Animal myDog = new Dog();
        myDog.Sleep(); // 출력: Animal is sleeping
        myDog.Speak(); // 출력: Dog barks
    }
}

왜 필요한가?

  • 공통된 로직은 재사용하고, 각 자식 클래스에 따라 다른 로직은 유연하게 강제할 수 있습니다.
728x90

'언어 > C#' 카테고리의 다른 글

[C#] 랜덤 배열(리스트) 셔플하기 (Fisher-Yates 알고리즘)  (1) 2025.01.09