Skip to content

Latest commit

 

History

History
61 lines (52 loc) · 3.46 KB

Item34.md

File metadata and controls

61 lines (52 loc) · 3.46 KB

항목 34. 인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구별하자

public 상속의 두 가지 개념

  1. 함수 인터페이스 상속
  2. 함수 구현 상속
class Shape{
public:
    virtual void draw() const = 0; // 순수 가상 함수
    virtual void error(const std::string& msg); // 단순 가상 함수
    int objectID() const; // 비가상 함수
};

class Rectangle: public Shape{};
class Ellipse: public Shape{};

Shape a; // 에러. 인스턴스를 만들 수 없음
  • Shape는 순수 가상 함수인 draw 함수 때문에 인스턴스를 만들 수 없는 추상 클래스이다.
    • Shape의 파생 클래스(Rectangle, Ellipse)만 인스턴스를 만들 수 있다.
  • Shape가 클래스로부터 파생된 클래스에 미치는 영향은 절대적이다.
    • 멤버 함수 인터페이스는 항상 상속되기 때문이다.

각 함수에 대한 설명

draw 함수(순수 가상 함수)

  • 순수 가상 함수를 선언하는 목적은 파생 클래스에게 함수의 인터페이스만을 물려주려는 것이다.
  • 순수 가상 함수를 물려받은 클래스는 해당 클래스에서 재선언해야 한다.
  • 순수 가상 함수는 추상 클래스 안에서 정의를 갖지 않는다.
  • 순수 가상 함수에도 정의를 제공할 수 있다.
  • 클래스 이름을 한정자로 붙여주어야만 동작한다.
virtual void draw() const = 0
{
    std::cout<<"Shape Draw"<<std::endl;
}
Shape::draw();

error 함수(단순 가상 함수)

  • 단순 가상 함수를 선언하는 목적은 파생 클래스에게 함수의 인터페이스뿐만 아니라 그 함수의 기본 구현도 물려받게 하자는 것이다.
  • 단순 가상 함수는 프로그래머가 지원해야 하지만 새로 만들 필요가 없다면 기본 클래스에 있는 버전을 사용할 수 있다.
  • 특별하게 처리해야 한다면 오버라이드를 통해 제공한다.

objectID 함수(비가상 함수)

  • 비가상 함수를 선언하는 목적은 파생 클래스가 함수 인터페이스와 더불어 그 함수의 필수적인 구현을 물려받게 하는 것이다.
  • ShapeShape에서 파생된 모든 객체는 objectId 함수를 갖게 될것이다."라고 생각하면 된다.
  • 비가상 함수는 클래스 파생에 상관없는 불변동작과 같기 때문에, 파생 클래스에서 재정의할 수 있는 것이 아니다.

클래스 설계시 주의할 점

  • 순수 가상 함수, 단순 가상 함수, 비가상 함수의 선언문이 가진 차이점 덕분에 파생 클래스가 물려받았으면 하는 것들을 정밀하게 지정할 수 있다.
    • 인터페이스만 상속시켜도 되고, 인터페이스와 기본 구현을 함께 상속시킬 수도 있고, 인터페이스와 필수 구현을 상속 시킬 수 있다.

멤버 함수 작성시 하는 실수

모든 멤버를 비가상 함수로 선언하는 것

  • 파생 클래스를 만들더라도 기본 클래스의 동작을 특별하게 만들만한 여지가 없어지게 된다.
  • 비가상 소멸자가 문제가 될 수 있다.

모든 멤버를 가상 함수로 선언하는 것

  • 파생 클래스에서 재정의가 안 되어야 하는 함수도 있을것이다.
  • 이런 함수는 반드시 비가상 함수로 만들어서 입장을 밝혀야 한다.
  • 인터페이스 클래스처럼 맞는 경우도 존재한다.