언어 자료구조 알고리즘/Escort C#

[C#] 6. 상속과 다형성 - 6.1 상속

언제나휴일 2016. 5. 2. 14:08
반응형


상속


6. 상속과 다형성

 

 C#에서는 다른 형식을 기반으로 파생된 형식을 정의할 수 있습니다. 이러한 OOP 언어의 특징을 상속이라고 합니다. C#에서 상속은 클래스와 인터페이스가 기반 형식이 될 수 있고 구조체는 기반 형식으로 인터페이스만 가능합니다.

 

 이처럼 상속으로 표현된 기반 클래스와 파생 클래스의 관계를 일반화 관계라고 합니다. C#에서는 기반 형식의 변수로 파생된 형식의 개체를 참조할 수 있어 사용하는 곳에 편의를 제공합니다. 그리고 기반 형식에 정의한 멤버 메서드를 파생 형식에서 재정의할 수 있습니다. 이처럼 기반 형식의 멤버 메서드를 재정의하여 사용하는 변수의 형식의 멤버 메서드가 아닌 실제 참조하고 있는 개체의 멤버 메서드가 수행되게 할 수 있습니다. 이 같은 특징을 다형성이라고 합니다. 이번 장에서는 C#에서 제공하는 상속과 다형성에 대해 살펴봅시다.


6.1 상속

 

 C#에서 파생된 형식을 정의할 때 기반 형식을 명시하여 상속을 표현합니다. 구조체는 기반 형식으로 인터페이스만 사용할 수 있지만, 클래스는 기반 형식으로 클래스와 인터페이스 모두 사용 가능합니다. 기반 형식에서 파생 형식을 정의할 때는 파생 형식 명 뒤에 콜론을 추가하고 기반 형식의 이름을 지정합니다.

 

class Base

{

}

class Derived: Base

{

}


인터페이스 목록에 있는 형식이 인터페이스가 아닙니다.

[그림 21] 클래스 기반의 구조체를 정의할 때 오류 화면


  파생 형식의 개체는 생성 과정에서 기반 형식의 개체 부분을 포함하여 생성됩니다.

 

 다음의 예는 Walk 메서드가 있는 Man 클래스를 기반으로 파생된 Student 클래스를 정의한 예입니다. 예를 보시면 파생된 Student 개체를 참조하는 변수를 통해 기반 형식인 Man의 멤버 메서드인 Walk를 사용하는 것을 보실 수 있습니다.

 

Man 클래스 기반의 파생 클래스 Student 정의

class Man

{

    internal void Walk()

    {

        Console.WriteLine("걷다.");

    }

}

class Student:Man //Man 클래스를 기반으로 파생

{

    internal void Study()

    {

        Console.WriteLine("공부하다.");

    }

}

class Program

{

    static void Main(string[] args)

    {

        Student student = new Student();

        student.Walk(); //기반 클래스 Man의 멤버를 사용

        student.Study();

    }

}

▶ 실행 결과

걷다.

공부하다.

 

 

 이처럼 파생된 형식의 개체에서는 기반 형식의 멤버를 포함하게 되는데 프로그램에서 파생된 형식을 정의할 때는 "파생된 형식은 기반 형식이다."라는 논리가 성립될 때 사용하십시오.

 

6.1.1 protected

 

 파생된 형식에서도 기반 형식에서 private으로 접근 지정된 멤버는 보이지 않으므로 자신에게 포함된 멤버지만 접근할 수 없습니다.


보호 수준 때문에 액세스할 수 없습니다.

[그림 22] 기반 형식의 private으로 접근 지정된 멤버에 파생된 형식에서 접근 불가

  

 형식 외부에서는 접근을 막고 파생된 형식에서는 접근할 수 있게 하려면 protected로 접근 지정하면 됩니다. 하지만 멤버 필드는 접근 지정을 private으로 하시고 파생된 형식에서 접근할 수 있게 하려면 멤버 속성을 통해 접근할 수 있게 하는 것이 바람직합니다.

 

▶ 멤버 속성을 통해 멤버 필드에 접근

class Man

{

    int hp = 100; //prviate으로 접근 지정(디폴트 접근 지정)

 

    protected int Hp //파생 형식에서 접근 가능

    {

        get

        {

            return hp;

        }

        set

        {

            hp = value;

        }

   }

   internal void Walk()

   {

        Console.WriteLine("걷다.");

        Hp += 2;

    }

}

 

6.1.2 생성

 

 파생 형식의 개체가 생성될 때는 기반 형식의 생성자 수행 후에 파생 형식의 생성자가 수행됩니다.

 

▶ 파생 형식의 개체 생성 과정

class Man

{

    internal Man()

    {

        Console.WriteLine("Man 생성자");

    }

}

class Student : Man //Man 클래스 기반으로 파생

{

    internal Student()

    {

        Console.WriteLine("Student 생성자");

    }

}

class Program

{

    static void Main(string[] args)

    {

        Student student = new Student();

    }

}

▶ 실행 결과

Man 생성자

Student 생성자

 

 

 만약, 기반 형식의 기본 생성자가 없고 매개 변수가 있는 생성자만 있으면 어떻게 해야 할까요? 이때는 다음의 예처럼 파생 형식의 생성자를 캡슐화할 때 base 키워드와 기반 형식 생성에 필요한 인자를 이용하여 초기화해야 합니다.

 

▶ 기반 형식에 기본 생성자가 없을 때 파생 형식 생성자에서 초기화

class Man

{

    string name;

    internal Man(string name)

    {

        this.name = name;

    }

}

class Student:Man

{

    internal Student(string name):base(name) //기반 클래스 생성 초기화

    {

    }

}

class Program

{

    static void Main(string[] args)

    {

        Student student = new Student("홍길동");

    }

}

  

6.1.3 봉인(sealed) 클래스

 

 C#에서는 클래스를 정의할 때 다른 클래스의 기반 형식으로 사용할 수 없게 정의할 수 있습니다. 이와 같은 클래스를 봉인 클래스라 부르며 class 앞에 sealed 키워드를 명시하면 됩니다. 값 형식은 기반 형식이 될 수 없으므로 묵시적으로 봉인된 형식입니다.


봉인 클래스를 기반 형식으로 사용하려고 할 때 오류 화면

[그림 23] 봉인 클래스를 기반 형식으로 사용하려고 할 때 오류 화면

 

 좀 더 자세한 사항은 6.2 다형성에서 다시 다루기로 하겠습니다. 그리고 인터페이스 기반으로 파생하는 부분은 8장 인터페이스와 컬렉션에서 설명할게요.

 

[C#] 6. 상속과 다형성 - 6.1 상속

[C#] 6.2 다형성 - 기반 형식의 변수로 파생한 개체를 참조

[C#] 6.2.2 is 연산자와 as 연산자

[C#] 무효화 - new 키워드, base 키워드

[C#] 6.2.4 가상화 virtual, 재정의 override

[C#] 6.2.5 abstract 키워드를 이용한 추상화

[C#] 6.2.5 sealed 키워드를 이용한 봉인

반응형