C# - 상속과 다형성

MothorMoth·2024년 4월 26일

C#

목록 보기
10/17
post-thumbnail

상속

  • 기존 클래스의 멤버를 활용하여 새로운 클래스를 생성하고, 이를 통해 부모 클래스의 기능을 확장하거나 수정하는 객체지향 프로그래밍의 핵심 메커니즘이다.

1. 상속의 특징

  1. 상위 클래스의 멤버에 접근: 하위 클래스는 상속받은 상위 클래스의 멤버에 접근할 수 있으며, 이를 통해 상위 클래스의 기능을 재사용할 수 있다.

  2. 메서드 재정의: 하위 클래스는 상위 클래스의 메서드를 재정의하여 자신에게 맞게 수정할 수 있고, 이를 통해 다형성(Polymorphism)을 구현할 수 있다.

  3. 상속의 깊이: 클래스가 다수의 계층적인 상속 구조를 형성할 수 있음을 의미하며, 이로 인해 클래스 간의 관계가 복잡해질 수 있어 적절한 상속 깊이를 유지하는 것이 중요하다.

2. 상속의 종류

  1. 단일 상속: 하나의 하위 클래스가 하나의 상위 클래스만 상속받는 것. C#에서는 단일 상속만을 지원한다.

  2. 다중 상속: 하나의 하위 클래스가 여러 개의 상위 클래스를 동시에 상속받는 것. C#은 다중 상속을 지원하지 않는다.

  3. 인터페이스 상속: 클래스가 인터페이스를 상속받는 것. 인터페이스는 다중 상속을 지원하며, 클래스는 하나의 클래스와 여러 개의 인터페이스를 동시에 상속받을 수 있다.

3. 상속의 장점

  1. 코드의 재 사용성: 상속을 통해 상위 클래스의 코드를 재사용할 수 있으므로, 코드의 반복 작성을 줄일 수 있다.

  2. 계층 구조의 표현: 클래스 간의 계층 구조를 표현하여 코드의 구조를 명확하게 표현할 수 있다.

  3. 유지 보수성의 향상: 상속을 통해 기존 클래스의 수정이 필요한 경우, 해당 클래스만 수정하면 되므로, 코드의 유지 보수성이 향상된다.

4. 접근 제한자와 상속

  • 상속 관계에서 부모 클래스 멤버의 접근 제한자는 자식 클래스의 멤버 접근 범위를 결정하고, 접근 제한자를 통해 상속된 멤버의 접근성을 조절하여 캡슐화와 정보 은닉을 구현한다.
// 상위 클래스
public class Animal
{
    public string Name { get; set; }
    public int Age { get; set; }

    public void Eat()
    {
        Console.WriteLine("Animal is eating.");
    }

    public void Sleep()
    {
        Console.WriteLine("Animal is sleeping.");
    }
}

// 하위 클래스
public class Dog : Animal
{
    public void Bark()
    {
        Console.WriteLine("Dog is barking.");
    }
}

public class Cat : Animal
{
    public void Sleep()
    {
        Console.WriteLine("Cat is sleeping.");
    }

    public void Meow()
    {
        Console.WriteLine("Cat is meowing.");
    }
}

// 사용 예시
Dog dog = new Dog();
dog.Name = "Bobby";
dog.Age = 3;

dog.Eat();   // 출력: Animal is eating.
dog.Sleep(); // 출력: Animal is sleeping.
dog.Bark();  // 출력: Dog is barking.

Cat cat = new Cat();
cat.Name = "KKami";
cat.Age = 10;

cat.Eat();   // 출력: Animal is eating.
cat.Sleep(); // 출력: Cat is sleeping.
cat.Meow();  // 출력: Cat is meowing.

다형성

  • 하나의 인터페이스를 가지고 여러 개의 구현을 제공하는 것으로, 같은 이름의 메서드가 서로 다른 동작을 하는 객체지향 프로그래밍의 핵심 메커니즘이다.

1. 가상(Virtual) 메서드

  • 가상 메서드는 virtual 키워드를 사용하여 선언되며, 하위 클래스에서 필요에 따라 재정의하여 하위 클래스에서 상위 클래스의 메서드를 변경하거나 확장할 수 있다.
public class Unit
{
    public virtual void Move()
    {
        Console.WriteLine("두발로 걷기");
    }
}

public class Zergling : Unit
{
    public override void Move()
    {
        Console.WriteLine("네발로 걷기");
    }
}

// 사용 예시
Zergling zergling = new Zergling();
zergling.Move(); // 출력: 네발로 걷기

2. 추상(Abstract) 클래스와 메서드

  • 추상 클래스는 abstract 키워드를 사용하여 선언되고, 인스턴스화가 불가능하고 상속을 위한 기반 클래스로서 기능을 정의하는 데 사용되며, 하위 클래스에서 반드시 구현해야 하는 하나 이상의 추상 메서드를 포함할 수 있다.
abstract class Shape
{
    public abstract void Draw();
}

class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing a circle");
    }
}

class Square : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing a square");
    }
}

class Triangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing a triangle");
    }
}

// 사용 예시
Circle circle = new Circle();
circle.Draw(); // 출력: Drawing a circle

Square square = new Square();
square.Draw(); // 출력: Drawing a square

Triangle triangle = new Triangle();
triangle.Draw(); // 출력: Drawing a triangle

3. 오버라이딩 과 오버로딩

  • 오버라이딩은 상속을 활용한 다형성을 구현하는 데 중요한 역할을 하고, 오버로딩은 하나의 클래스 내에서 메서드의 유연성을 증가시키는 데 사용된다.

오버라이딩 (Overriding)

  • 상속받은 상위 클래스의 메서드를 하위 클래스에서 이름, 매개변수 및 반환 타입을 동일하게 유지하면서 재정의하여, 클래스별로 특화된 동작을 구현한다.
public class Shape
{
    public virtual void Draw()
    {
        Console.WriteLine("Drawing a shape.");
    }
}

public class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing a circle.");
    }
}

public class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Drawing a rectangle.");
    }
}

Shape circle = new Circle();
Shape rectangle = new Rectangle();

circle.Draw();      // 출력: Drawing a circle.
rectangle.Draw(); // 출력: Drawing a rectangle.

오버로딩 (Overloading)

  • 동일한 이름의 메서드를 매개변수의 개수, 타입, 순서를 다르게 하여 여러 형태로 정의함으로써, 다양한 매개변수 조합으로 같은 이름의 메서드를 호출할 수 있다.
public class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }

    public int Add(int a, int b, int c)
    {
        return a + b + c;
    }
}

Calculator calculator = new Calculator();
int result1 = calculator.Add(2, 3);    // 출력: 5
int result2 = calculator.Add(2, 3, 4); // 출력: 9

0개의 댓글