본문 바로가기
언어/C++

[C++ 기본 공부정리] 16-1. OOP 상속성 - 파생 클래스(derived class)

by 민-Zero 2020. 1. 5.

공부 내용을 정리하는 목적 이므로 참고용으로만 읽어 주시기 바랍니다.

틀린 부분에 대한 지적은 감사합니다.

파생 클래스(derived class)는 클래스를 상속을 이용해 새롭게 작성되는 클래스를 뜻한다. 따라서 먼저 상속(inheritance)에 대해 정리하자.

 

1. 상속(inheritance)

일상적으로 쓰이는 상속이란 뜻은 재산, 지위 등을 물려받는 것을 뜻한다. 클래스에서의 상속도 이와 비슷한 의미로 쓰인다. 상속이란 기존에 존재하는 클래스를 이용하여 해당 클래스의 속성이나 기능 즉 멤버 변수와 함수를 물려받아 그대로 사용하거나 기능을 개선 또는 확장하여 사용하는 것을 뜻한다. 만약 새로운 클래스B를 만드는대 클래스A와 기본적인 부분은 유사하나 다른 기능 몇 개가 추가되고 기존 기능보다 좀 더 확장된 기능을 가진 클래스라면 A에서 기능을 물려받아 사용할 수 있게 하는 것이다.

이때 기존에 존재하는 클래스를 상위 클래스(super class)또는 부모 클래스(parent class)라고 하며 상속을 통해 작성되는 클래스를 파생 클래스(derived class)또는 자식 클래스(child class)라고 한다. 쉽게 이해하기 위해 부모 클래스, 자식 클래스 라고 정리하자.

간단히 예를 들어 사람이라는 클래스를 만들고 추가로 운동선수라는 클래스를 만들면 사람이 가진 팔, 다리, 걷기, 숨쉬기 등의 공통적인 특징을 물려받아 그대로 사용하고 운동능력이라는 특징을 좀 더 확장시켜 제작하면 운동선수라는 클래스를 쉽게 생성할 수 있다.

 

문법)

class 자식클래스명 : 접근제어자  부모클래스명[, 접근제어자 부모클래스명2,...]{

    자식클래스 멤버;

}

 

접근 제어자는 부모 클래스의 멤버를 사용할 수 있는 자식 클래스의 접근 제어 권한을 설정한다. 즉, 상속시 어떤 접근제어자를 설정하냐에 따라 자식 클래스에서 부모 클래스 멤버에 대한 접근 여부가 결정된다. 생략할 경우 디폴트값인 private로 설정된다.


private - 부모 클래스의 모든 멤버는 자식 클래스에서 private로 지정
protected - 부모클래스의 public으로 지정된 멤버는 protected로 지정되며 나머지는 부모클래스의 접근 권한과 동일하게 지정 
public - 부모 클래스에서 지정한 권한은 자식 클래스의 멤버들에게도 똑같이 지정

private는 어떤 제어자를 설정하더라도 private로 유지되어 자식 클래스가 접근이 불가능 하므로 주의하자.

부모 클래스 멤버 상속 자식 클래스
public public public, 접근 가능
protected   protected, 접근 가능
private   private, 접근 불가
public protected protected, 접근 가능
protected   protected, 접근 가능
private   private, 접근 불가
public private private, 접근 불가
protected   private, 접근 불가
private   private, 접근 불가

 

만약 상속받을 클래스가 여러개라면 대괄호([])안의 문법처럼 쉼표(,)를 이용해 여러 클래스에서 상속받을 수 있다. 이때 여러 클래스에게 상속받는것을 다중 상속(multiple inheritance)라고 한다. 이는 뒤에 정리하자. 

 

앞에서 이야기한 사람 클래스와 운동선수 클래스를 간단히 구현해 상속을 이해해 보면.

Person 클래스와 Athlete 클래스를 생성 public을 통해 상속받았다. 그렇다면 부모 클래스의 멤버에 동일한 접근제어 권한을 가지고 자식 클래스에서 접근할 수 있다. 자식 클래스에서 새로운 멤버 변수는 생성하지 않았으므로 부모 클래스에서 물려받은 멤버 변수만 가지고 있게 되고 private로 물려받아서 부모의 멤버변수에 직접 접근이 불가능 하므로 public으로 물려받은 부모 클래스의 생성자를 그대로 이용한다. 자식 클래스가 멤버 변수를 가지고 있다면 일반적인 생성자처럼 Person()뒤에 멤버 변수의 이니셜라이저를 추가해 주면 된다.

Athlete 클래스를 이용하여 a 객체를 생성하게되면 Person 클래스의 속성이나 기능을 그대로 물려받아 사용가능 하므로 Athlete클래스에서 정의하지 않은 PrintInfo 함수를 사용하여 부모 클래스의 멤버 변수와 함수를 사용하여 출력할 수 있다. 또한 멤버 함수 오버라이딩을 이용하여 부모클래스와 같은 함수지만 기능을 변경하여 "보통" 대신 "뛰어남"을 출력하도록 기능을 개선할 수 있다. 오버라이딩에 대해선 뒤에 정리하자.

 

이처럼 상속을 통하면 공통적인 속성이나 기능을 다시 작성하지않고 물려받아 사용할 수 있어 코드의 재사용성을 제공하며 클래스를 계층적으로 관리할수 있게 해준다.

 

2. 파생 클래스(derived class) 특징

앞의 예시에서 확인한 자식 클래스의 특징을 한번에 정리해보면

 

① 부모 클래스가 생성자를 가지고 있더라도 자식 클래스에서 새로운 멤버 변수가 추가될 수 있으므로 새로운 멤버 변수가 없더라도 자식 클래스만의 생성자를 생성 해야 한다. 

② 자식 클래스에는 부모 클래스의 접근 가능한 멤버 변수들이 저장되어 있다.

자식 클래스로 부모 클래스의 접근 가능한 멤버 함수를 사용할 수 있다.

④ 자식 킄래스는 부모 클래스의 속성과 기능을 기초로 하여 필요시 멤버 변수나 함수를 추가할 수 있고 함수의 기능을 변경할 수 있다.

 

자식 클래스의 특징을 확인하기 위해 앞선 예시의 부모 클래스와 자식클래스에 몇가지를 추가하였다.

자식 클래스에서 자신만의 매개 변수와 함수를 추가하고 출력하도록 하였다. 이니셜라이저에서 부모 클래스의 생성자와 자신의 멤버 변수를 사용하여 초기화를 진행한다. 

public을 통해 상속받아 부모 클래스가 가진 접근 제어자 그대로 부모 클래스의 멤버에 접근할 수 있어 멤버 변수확인을 위해 public 함수를 이용하여 출력한다. 자식클래스는 자신만의 멤버 변수나 함수를 추가할 수 있고 부모 클래스의 멤버를 그대로 이용하거나 기능을 변경하여 사용할 수 있음을 확인할 수 있다.

 

또한 이 예시를 이용하여 자식 클래스 객체 생성과정을 확인 할 수 있다.

제일 먼저 생성자가 호출되는 것은 같으나 우선 부모 클래스에게 물려받은 멤버 변수의 초기화를 위해 부모 클래스 생성자가 초기화 되고 그다음 자신의 생성자가 호출된다. 객체가 할일이 끝나고 객체의 수명이 다하면 반대로 자식 클래스의 소멸자가 호출된 다음 부모 클래스의 소멸자가 호출된다. 

댓글