Qaupot Blog
Software Engineering, Trip

401. 상속

🕐 Sat, 08 Mar 2014 09:00:00 GMT 🕓 Sun, 05 Sep 2021 12:30:00 GMT

상속 (Inheritance)

상속은 재사용성을 높이고 다형성을 확보할 수 있는 방법입니다. 기존에 잘 디자인 된 클래스를 확장하여 새로운 목적의 클래스를 만들어 낼 수 있습니다.

어떠한 클래스가 다른 클래스를 멤버로써 포함될 때, 이를 has a 상속 이라고 합니다.

  • 예 : PC는 CPU 와 RAM 을 포함한다

어떠한 클래스가 다른 클래스로 부터 파생될 때, 이를 is a 상속 이라고 합니다.

  • 예 : Laptop 은 PC다

흔히 상속이라는 표현을 쓰면 is a 상속을 이야기 합니다.

"돈을 지불하다" 라는 메소드가 있습니다.
학생이 "돈을 지불하다" 라는 것과 회사원이 "돈을 지불하다"라는 것은 본질적으로 동일합니다.
전통적인 C 프로그래밍에서는 이러한 중복되는 기능은 "함수"로써 분리하기를 권장합니다.

  • 코드가 여러 벌이 생기면 각각의 파트별로 유지보수가 복잡해지기 때문입니다.

C++에서도 마찬가지입니다. 그러나, C 에서는 전역에 함수를 선언하므로 어디에서나 호출할 수 있지만, C++ 에서는 "객체지향"이라는 관점에서 자료형과 관련된 메소드들은 클래스 내에 디자인하기를 권장합니다.

학생과 회사원의 공통점이면서, "돈을 지불하다"라는 메소드를 가질 수 있는 "사람"입니다.
그렇다면, Person 클래스를 부모로 Student 와 Employee 라는 파생 클래스를 디자인 할 수 있습니다.

#include <iostream>

class Person
{
private:
    int money;
protected:
    Person(int val)
        : money(val) {}
public:
    void payTo(Person& payTo,int val)
    { 
        this->money -= val;
        payTo.money += val;
    }
    int getMoney()
    {
        return money;
    }
};

class Student : public Person
{
public:
    Student(int val) : Person(val) {};
};

class Employee : public Person
{
public:
    Employee(int val) : Person(val) {};
};

int main(int argc, char** argv)
{
    Student student(100);
    Employee employee(100);

    std::cout << student.getMoney() << " " << employee.getMoney() << std::endl;

    student.payTo(employee, 10);

    std::cout << student.getMoney() << " " << employee.getMoney() << std::endl;
}

상속은 클래스를 선언할때 클래스 이름 뒤에 : 를 붙이고 상속하려는 클래스 이름을 기입합니다.
이때 private, protected, public 권한을 지정할 수 있으며, 아무것도 지정하지 않을 경우, 기본값은 private 입니다.

상속시 접근권한

  1. private 로 지정할 경우, 부모 클래스의 모든 멤버는 파생 클래스에서 private 로 지정됩니다.
  2. protected 로 지정할 경우, 부모 클래스의 public 은 protected 로 지정되며, 나머지는 부모클래스의 권한과 동일하게 지정됩니다.
  3. public 으로 지정할 경우, 부모 클래스의 권한지정은 파생 클래스의 멤버들에 똑같이 지정됩니다.

또한 부모 클래스의 권한은 파생 클래스안에서의 호출에도 영향을 줍니다.

  1. 부모 클래스에서 private 로 지정된 멤버는 파생 클래스에서도 호출할 수 없습니다.

  2. protected 로 지정된 멤버는 파생 클래스 내부에서는 호출할 수 있지만,

protected 혹은 private 로 상속되기 때문에 파생 클래스 외부에서는 호출할 수 없습니다.

  1. public 으로 지정된 멤버는 상속시에 public 으로 상속했다면

파생 클래스 내부 혹은 외부에서 호출할 수 있으며, protected 나 private 로 상속했다면 내부에서만 호출할 수 있습니다.

만약, 위의 예제 코드에서 상속을 각각 protected 이나 private 로 지정하면, 부모 클래스에서의 지정이 public 이므로, Student 와 Employee 의 내부 메소드에서는 payTo와 getMoney 를 호출할 수 있지만, 외부에서는 호출할 수 없습니다.

권한지정 활용

Person 은 private 멤버로 int money 를, protected 멤버로 생성자를 가지고 있습니다.
생성자가 protected 이기에 외부 호출이 불가능하며, Person 은 직접 선언으로 생성할 수 없도록 제한됩니다.

  • protected 는 외부에는 private, 상속 자식에게는 public 으로 지정되는 접근 제어입니다.

Student 와 Employee 는 public 으로 Person 을 상속합니다.

  • private 속성이었던 money 값에 접근할 수는 없지만 protected 였던 생성자에는 접근할 수 있습니다.
  • Student 와 Employee 의 생성자는 public 으로 지정되었기 때문에, Student 와 Employee 는 직접 선언이 가능해집니다.

Student(int val) : Person(val) {}; 와 같이 부모의 생성자에 매개변수를 전달했습니다.

  • 부모 클래스가 기본 생성자가 없을 경우, 반드시 부모의 생성자에 매개변수를 전달해 주어야 합니다.
이 블로그는 개인 블로그입니다. 게시글은 오류를 포함하고 있을 수 있지만, 저자는 오류를 해결하기 위해 노력하고 있습니다.
게시글에 별도의 고지가 없는 경우, 크리에이티브 커먼즈 저작자표시-비영리-변경금지 4.0 라이선스를 따릅니다.

This blog is personal blog. published posts may contain some errors, but author doing efforts to clear errors.
If post have not notice of license, it under creative commons Attribution-NonCommercial-NoDerivatives 4.0.