ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [12강] 상속
    프로그래밍/C# 2022. 8. 13. 00:13

    목차

    의미
    형식
    상속 관계에서 생성자와 소멸자 호출
    base, sealed
    override와 overload에 대해서
    추상 클래스
    다형성
    박싱과 언박싱

     

    상속

    객체 지향적 프로그래밍의 꽃

    많은 양의 코드를 줄이고, 다 구현하지 않아도 되는 효과를 얻을 수 있다.

     

    상속의 대상?

      클래스

    상속의 목적?

      클래스의 재사용 -> 코드 양 줄이기

    상속 클래스의 역할

      부모 클래스 : 상속을 하는 클래스(base class, parent class, 상위 클래스)

      자식 클래스 : 상속을 받는 클래스(child class, derived class, 파생 클래스)

     

    의미

    뒤를 잇다.(서로 상相 이을 속屬)

    -> 하나의 클래스가 있고, 또 다른 하나의 클래스를 만들어야 할 때, 이미 이 클래스에 만들어져 있는 것에 무엇인가를 추가하고 싶으나, 기존의 클래스를 훼손하고 싶지 않다.

    -> 기존 클래스를 부모로 두고 상속받아 필요한 것을 추가한다.

     

    형식

    상속 관계 표시 및 형식

    Parent class

            ↑

    Child class

     

    class A { ... }

    class B : A { ... }

     

    상속 접근 제한

    상위 클래스 접근 제한

    class A

    {

        private

        protected

        public

    }

    class B : A {}

     

      B에서 접근할 수 있는 것 : protected, public

      Main과 같은 외부에서 접근할 수 있는 것 : public

     

    상속 관계에서 생성자와 소멸자 호출

    생성자 호출 순서

    상위 클래스 생성자 호출 -> 하위 클래스 생성자 호출

    상위 클래스가 먼저 생성되고 하위 클래스가 생성된다.

     

    소멸자 호출 순서

    하위 클래스 소멸자 호출 -> 상위 클래스 소멸자 호출

     

    예시 코드

    public class Practice
    {
        static void Main(string[] args)
        {
            Test081204 test = new Test081204();
        }
    }
    
    class Test081203
    {
        public Test081203()
        {
            Console.WriteLine("Test081203 생성자");
        }
    
        ~Test081203()
        {
            Console.WriteLine("Test081203 소멸자");
        }
    }
    
    class Test081204 : Test081203
    {
        public Test081204()
        {
            Console.WriteLine("Test081204 생성자");
        }
    
        ~Test081204()
        {
            Console.WriteLine("Test081204 소멸자");
        }
    }

     

    예시 코드 실행시 Console 출력

    Test081203 생성자
    Test081204 생성자
    Test081204 소멸자
    Test081203 소멸자

     

    base, sealed

    상속과 관련된 base 키워드

    역할

      상위 클래스의 행성자 또는 멤버 변수 및 메서드 호출

    활용

      멤버 이름의 중복

      하위에서 상위 설정 등(생성자 위주)

     

    상속과 관련된 sealed 키워드

    sealed의 의미

      봉인을 한

    사용 의미

      상속 불가에 대한 명시(멤버 변수, 메서드)

    sealed 사용 형식

    type 1

    sealed class A { ... } 

    상속할 수 없는 클래스임을 명시

     

    type 2

    class A { sealed public void Print() }

    class B : A { }

     

    override와 overload

    override : 무시하다

    C#에서의 override의 의미

      상위 메서드에 이미 구현되어 있는 내용을 무시하고 하위에서 재정의 하는 것

    override의 대상

      클래스 메서드 > 속성, 인덱서, 이벤트

    override 사용 형식

      상위 클래스에서는 virtual 명시

      하위 클래스에는 override 명시

     

    overload : 과적하다. 과부하

    overload의 역할

      하나의 메서드명에 다양한 매개변수를 적용

    장점

      하나의 메서드로 다양한 값을 대입할 수 있다.

    형식

      메서드명만 동일하며, 매개변수는 임의로 적용할 수 있다

    호출

      메서드명과 매개변수로 호출

     

    추상 클래스

    상속의 개념, override의 개념이 있어야 한다.

    상위 클래스와 하위 클래스의 관계를 이야기 하며 어떤 식으로 구현할 것이고, 무시할 것인가?

    무시를 하기는 하되 어떤 형식으로 주어지도록 할 것인가와 같은 구조에 관련된 것.

     

    추상

    뽑을 추抽, 코끼리 상象

    abstract : 추상적인, 관념적인

    여러 가지 사물이나 개념에서 공통되는 특성이나 속성 따위를 추출하여 파악하는 작용.

     

    의미

      구현하려는 메서드의 형태만 존재하는 클래스

    역할

      추상 클래스는 구현 형태만 제공, 실제 구현은 하위에서 구현

    제한 사항

      추상 클래스는 상속으로만 사용

      new를 통해 생성할 수 없다

      abstract가 있는 상위 메서드만 하위에서 모두 구현

    용도

      제공되는 형식으로 메서들를 구성해야 하는 경우

      (팀을 이루어서 구현을 해야 할 경우. 구조가 단일화 되고 메서드가 동일해야 하는 경우)

     

    예시 코드

    public class Practice
    {
        static void Main(string[] args)
        {
            Test081210 test = new Test081210();
            test.Print();
            test.PrintNumber();
        }
    }
    
    abstract class Test081209
    {
        private int number = 3;
        public abstract void Print();
    
        public void PrintNumber()
        {
            Console.WriteLine(number);
        }
    }
    
    class Test081210 : Test081209
    {
        public override void Print()
        {
            Console.WriteLine("abstract class");
        }
    }

     

    다형성 Polymorphism

    의미 : 여러 형태(그리스어)

      같은 종의 생물이면서도 어떤 형태나 형질이 다양하게 나타나는 현상.

      상속 관계에서 일어남

     

    일반적 형태 : 상위에서 하위 호출

    class A { public virtual void Print()  { ... } }

    class B : A { public override void Print() { ... } }

     

    A test = new B();

    Test.Print();

    B의 객채가 생성되어 있는데 A 클래스의 참조 변수로 해당 객체에 접근하겠다는 의미.

    이 참조 객체로 Print 메서드를 호출하면 B 클래스의 Print를 호출한다

    -> override를 하여 상위 객체가 무시되었기 때문

     

    다른 형태 : 일반적 형태 + cast형을 이용한 하위 참조 호출

    예시 코드

    public class Practice
    {
        static void Main(string[] args)
        {
            Test081211 test1 = new Test081212();
            test1.Print();
            
            // cast형을 이용한 참조
            Test081212 test2 = new Test081212();
            Test081211 test3 = (Test081211) test2;
            test3.Print();
        }
    }
    
    class Test081211
    {
        public virtual void Print()
        {
            Console.WriteLine("Test081211");
        }
    }
    
    class Test081212 : Test081211
    {
        public override void Print()
        {
            Console.WriteLine("Test081212");
        }
    }

    console에는 둘 다 하위클래스의 Print가 호출된다.

     

    박싱과 언박싱

    박싱

      값 형식을 object형 변환

      (int, double, float, 구조체...)

     

    언박싱

      object형을 다시 값 형식으로 변환

      cast를 사용하여 형을 명시

     

    형식

      int a = 7;

      object obj = a;

      int result = (int)obj;

      * 구조체도 값 형식이므로 박싱과 언박싱이 됨

     

    예시 코드

    public class Practice
    {
        static void Main(string[] args)
        {
            int num = 3;
            object obj = num;
            int result = (int) obj;
            Console.WriteLine($"{num} {result}");
    
            TestData test = new TestData("test", 3);
            object obj1 = test;
            TestData test1 = (TestData) obj1;
            Console.WriteLine($"{test1.name} {test.number}");
        }
    }
    
    struct TestData
    {
        public string name;
        public int number;
    
        public TestData(string name, int number)
        {
            this.name = name;
            this.number = number;
        }
    }

     

    클래스는 상속 관계에 있으므로 참조 변환이 된다.(Upcasting, Downcasting)

    -> 박싱과 언박싱과 구별

    예시 코드

    public class Practice
    {
        static void Main(string[] args)
        {
            Test081214 test1 = new Test081214();
            //object obj = test1;
            //Test081213 test2 = (Test081213) obj;
            Test081213 test2 = test1;
            test1.PrintA();
            test1.PrintB();
            test2.PrintA();
        }
    }
    
    class Test081213
    {
        public void PrintA()
        {
            Console.WriteLine("Hello");
        }
    }
    
    class Test081214 : Test081213
    {
        public void PrintB()
        {
            Console.WriteLine("World");
        }
    }

     

     

    '프로그래밍 > C#' 카테고리의 다른 글

    [13강] 인터페이스  (0) 2022.08.13
    [11강] 델리게이트와 이벤트  (0) 2022.06.20
    [10강] 배열/객체배열, 속성/인덱서 비교  (0) 2022.06.20
    [09강] 속성과 인덱서  (0) 2022.06.13
    [08강] 클래스  (0) 2022.05.31
Designed by Tistory.