24.01.13 TIL - [C#] 기초 (9) : 상속과 다형성

JJwoo·2024년 1월 3일
0

C#

목록 보기
9/20
post-thumbnail

🧬 상속

1. 상속의 개념

  • 상속은 기존 클래스(부모 클래스)를 확장하거나 재사용하여 새로운 클래스(자식 클래스)를 생성하는 과정

  • 자식 클래스는 부모 클래스의 멤버(필드, 메서드, 프로퍼티 등)를 상속받아 사용할 수 있다.

  • 상속을 통해 부모 클래스의 기능을 확장하거나 수정하여 새로운 클래스를 정의할 수 있다.


2. 상속의 장점

  • 코드의 재사용성
    : 상속을 통해 기존 클래스의 코드를 재사용할 수 있으므로, 반복적인 코드 작성을 줄일 수 있습니다.

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

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


3. 상속의 종류

  • 단일 상속
    : 하나의 자식 클래스가 하나의 부모 클래스만 상속받습니다. 예를 들어, C#에서는 단일 상속만을 지원합니다.

  • 다중 상속
    : 하나의 자식 클래스가 여러 개의 부모 클래스를 동시에 상속받습니다. 하지만 C#은 다중 상속을 지원하지 않습니다.

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

4. 상속의 특징:

  • 부모 클래스의 멤버 접근
    : 자식 클래스는 상속받은 부모 클래스의 멤버에 접근할 수 있으며, 이를 통해 부모 클래스의 기능을 재사용할 수 있습니다.

  • 메서드 재정의
    : 자식 클래스는 부모 클래스의 메서드를 재정의하여 자신에게 맞게 수정할 수 있습니다.
    이를 통해 다형성(Polymorphism)을 구현할 수 있습니다.

  • 상속의 깊이
    : 클래스는 여러 계층의 상속 구조를 가질 수 있습니다. 상속의 깊이가 깊어질수록 클래스 간의 관계가 복잡해질 수 있으므로, 적절한 상속의 깊이를 유지하는 것이 중요합니다.


5. 접근 제한자와 상속

  • 상속 관계에서 멤버의 접근 제한자는 중요한 역할을 합니다. 부모 클래스의 멤버의 접근 제한자에 따라 자식 클래스에서 해당 멤버에 접근할 수 있는 범위가 결정됩니다.

  • 접근 제한자를 통해 상속된 멤버의 가시성을 조절하여 캡슐화와 정보 은닉을 구현할 수 있습니다.


// 부모 클래스
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 bark.");
    }
}

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

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

// 사용 예시
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();
cat.Sleep();
cat.Meow();


🔄 다형성

✔️ 같은 타입이지만 다양한 동작을 수행할 수 있는 능력

1) 가상(Virtual) 메서드

  • 기본 개념
    : 가상 메서드는 부모 클래스에서 정의되고, 자식 클래스에서 재정의할 수 있는 메서드.

virtual 키워드를 사용해서 선언하고, 자식 클래스에서는 override 키워드를 사용해서 재정의할 수 있습니다.

  • 역할
    : 가상 메서드를 사용하면, 자식 클래스가 부모 클래스의 메서드를 자기 방식대로 변경하거나 확장할 수 한다.
    이는 다형성을 구현하는 데 중요한 역할을 한다.

        public class Unit
        {
            public virtual void Move()  // virtual : 자식이 재정의를 했을 수 있다.
            {
                Console.WriteLine("두발로 걷기");
            }
            // virtual 이면 실형태가 다를 수 있으니 실형태에 재정의가 되어있는지 확인

            public void Attack()
            {
                Console.WriteLine("Unit 공격");
            }
        }

        public class Marine : Unit
        {
	       // Marine 클래스에서는 Move 메서드를 재정의하지 않음.
        }

        public class Zergling : Unit
        {
            public override void Move() // override : 재정의
            {
                Console.WriteLine("네발로 걷기");
            }
        }
        static void Main(string[] args)
        {
            //Marine marine = new Marine();
            //marine.Move();
            //marine.Attack();

            //Zergling zergling = new Zergling();
            //zergling.Move();
            //zergling.Attack();

            // unit 참조의 형태, marine과 zergling은 실형태
            List<Unit> list = new List<Unit>();

            list.Add(new Marine());
            list.Add(new Zergling());

            foreach (Unit unit in units)
            {
                unit.Move();  // Marine은 "두발로 걷기", Zergling은 "네발로 걷기"
            }
        }

추상(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 Circle");
               }
           }
    
           class Triangle : Shape
           {
               public override void Draw()
               {
                   Console.WriteLine("Drawing a Circle");
               }
           }
           static void Main(string[] args)
           {
               List<Shape> list = new List<Shape>();
               list.Add(new Circle());
               list.Add(new Square());
               list.Add(new Triangle());
    
               foreach (Shape shape in list)
               {
                   shape.Draw();
               }
           }

3) 오버라이딩 - 오버로딩

  • 오버라이딩
    : 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것. 상속 관계에서 발생하며, 메서드의 시그니처(이름, 매개변수, 반환타입)가 동일해야 한다.
  • 오버로딩
    : 같은 이름의 메서드를 매개변수의 개수나 타입이 다르게 여러 개 정의하는 것. 메서드의 시그니처가 다르면, 같은 이름의 메서드도 여러 개 만들 수 있다.
    이는 클래스 내에서 발생하고, 다형성을 구현하는 또 다른 방법이다.
기준오버라이딩(Overriding)오버로딩(Overloading)
정의부모 클래스에서 정의된 메서드를 자식 클래스에서 재정의하는 것같은 이름의 메서드를 매개변수의 개수, 타입, 순서가 다르게 여러 번 정의하는 것
목적부모 클래스의 메서드 동작을 자식 클래스에서 변경하거나 확장하기 위함같은 이름의 메서드를 다양한 매개변수로 사용하기 위함
메서드 시그니처메서드 이름, 매개변수의 수와 타입, 반환 타입이 부모 클래스의 메서드와 동일해야 함메서드 이름은 같지만 매개변수의 수, 타입, 순서가 달라야 함
키워드override (C# 등 일부 언어에서 사용)overload라는 특별한 키워드는 없음 (매개변수의 차이로 구분)
사용 예시부모 클래스 AnimalMakeSound 메서드가 있고, 자식 클래스 Dog에서 MakeSoundBark로 재정의할 수 있음Add(int, int) 메서드와 Add(int, int, int) 메서드가 동일한 클래스 내에서 공존할 수 있음

다형성의 개념과 사용 방법은 객체 지향 프로그래밍에서 매우 중요하다. 다형성을 이해하고 잘 사용하면, 유연하고 확장성 있는 코드를 작성할 수 있다.



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 shape1 = new Circle();
Shape shape2 = new Rectangle();

shape1.Draw();  // Drawing a circle.
shape2.Draw();  // Drawing a rectangle.


오버로딩(Overloading)
동일한 메서드 이름을 가지고 있지만, 매개변수의 개수, 타입 또는 순서가 다른 여러 개의 메서드를 정의하는 것을 의미합니다. 
오버로딩을 통해 동일한 이름을 가진 메서드를 다양한 매개변수 조합으로 호출할 수 있습니다.

C#
복사
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 calc = new Calculator();
int result1 = calc.Add(2, 3);         // 5
int result2 = calc.Add(2, 3, 4);      // 9


 
 
 
 
profile
개발 모코코

0개의 댓글