inheritance c
예를 들어 C ++에서 상속의 중요성 :
상속은 객체 지향 프로그래밍의 가장 중요한 기능 중 하나입니다.
상속은 한 클래스가 다른 클래스의 속성과 메서드를 획득하는 기술입니다. 이렇게하면 이미 작성되고 확인 된 코드를 재사용 할 수 있습니다. 다른 클래스의 속성을 획득하는 클래스를 하위 클래스 또는 파생 클래스 또는 자식 클래스라고합니다.
속성을 획득 한 클래스를 기본 클래스 또는 부모 클래스 또는 수퍼 클래스라고합니다. 한 클래스가 다른 클래스를 획득하거나 상속하면 파생 클래스에 대해 기본 클래스의 모든 속성과 메서드를 사용할 수 있으므로이 코드를 다시 사용할 수 있습니다.
=> 처음부터 C ++를 배우려면 여기를 방문하십시오.
0과 1 사이의 난수 생성기
학습 내용 :
상속이 필요한 이유는 무엇입니까?
자동차, 버스, 지프 등과 같은 차량 그룹을 고려하십시오. 이러한 각 차량에는 아래 다이어그램에 표시된 속성과 방법이 있습니다.
위의 차량에 대해 개별 클래스를 구현해야하는 경우 세 가지 클래스 모두에서 세 가지 유형의 차량이 거의 동일한 속성을 나타내므로 동일한 코드를 작성해야한다는 것을 알 수 있습니다. 중복 코드가 많기 때문에 프로그램이 비효율적이고 번거로울 것입니다.
위와 같이 중복 코드를 작성하는 대신 상속 기능을 구현하여 코드 중복을 방지하고 단일 코드를 작성하여 세 클래스 모두에서 사용할 수 있습니다. 이것은 아래와 같이 그림으로 표현됩니다.
위의 그림에서 기본 클래스 'Vehicles'를 정의하고이 클래스에서 Car, Bus 및 Jeep 클래스를 파생 시켰습니다. 일반적인 메서드와 속성은 이제 Vehicles 클래스의 일부입니다. 다른 클래스가 Vehicles 클래스에서 파생되므로 모든 클래스가 이러한 메서드와 속성을 얻습니다.
따라서 공통 코드를 한 번만 작성하고 세 클래스 모두를 작성하면됩니다. 자동차, 버스 및 지프가이를 획득합니다.
따라서 기존 클래스를 상속하거나 상속 메커니즘을 설계함으로써 얻을 수있는 주요 이점은 코드의 재사용 가능성입니다.
추가 읽기 = >> Java 상속 자습서
클래스 상속의 일반적인 형식은 다음과 같습니다.
class derived_classname: access_specifier base_classname { };
여기 ' 파생 _ 클래스 이름 '는 파생 클래스의 이름입니다.' 액세스 _ 지정자 ”는 액세스 모드 즉, 파생 클래스가 기본 클래스를 상속해야하는 공용, 보호 또는 개인 및“ 파생 _ 클래스 이름 ”는 파생 클래스가 상속하는 기본 클래스의 이름입니다.
상속 모드
위의 상속 선언에 표시된 'access_specifier'는 아래와 같은 값을 가질 수 있습니다.
클래스를 상속 할 때 지정된 access_specifier에 따라 다음과 같은 다양한 상속 모드가 있습니다.
공개 상속
일반 구문
class sub_class : public parent_class
공용 액세스 지정자가 지정되면 보호 된 멤버가 보호되는 동안 기본 클래스의 공용 멤버가 공용으로 상속됩니다. 비공개 회원은 비공개로 유지됩니다. 이것은 가장 널리 사용되는 상속 모드입니다.
개인 상속
일반 구문
class sub_class : parent_class
개인 상속은 아무것도 상속하지 않습니다. 개인 액세스 지정자를 사용하면 기본 클래스의 공용 및 보호 된 멤버도 개인용이됩니다.
보호 된 상속
일반 구문
class sub_class:protected parent_class
보호 된 액세스 지정자를 사용하면 기본 클래스의 공용 및 보호 된 멤버가 파생 클래스에서 보호 된 멤버가됩니다.
기본 클래스에 대해 개인 액세스 지정자를 사용하면 기본 클래스 멤버가 상속되지 않습니다. 이들은 모두 파생 클래스에서 전용이됩니다.
컴퓨터를 청소하는 최고의 소프트웨어
다음은 모든 액세스 모드의 표 형식 표현과 상속에 대한 해석입니다.
파생 클래스-> 기본 클래스 | 은밀한 | 공공의 | 보호 |
---|---|---|---|
은밀한 | 상속되지 않음 | 상속되지 않음 | 상속되지 않음 |
공공의 | 은밀한 | 공공의 | 보호 |
보호 | 은밀한 | 보호 | 보호 |
상속 된 생성자 / 소멸자의 순서
클래스가 상속 될 때 생성자는 클래스가 상속되는 순서와 동일한 순서로 호출됩니다. 기본 클래스와이 기본 클래스를 상속하는 하나의 파생 클래스가있는 경우 기본 클래스 생성자 (기본 또는 매개 변수화 여부)가 먼저 호출 된 다음 파생 클래스 생성자가 호출됩니다.
다음 프로그램은 상속에서 생성자의 순서를 보여줍니다. 기본 생성자와 매개 변수화 된 생성자를 가진 Base 클래스“Base”가 있습니다. 하나의 기본값과 다른 매개 변수화 된 생성자가있는 'Derived'라는 클래스에서 파생됩니다.
이 프로그램의 출력은 생성자가 호출되는 순서를 보여줍니다.
#include using namespace std; //order of execution of constructors in inheritance class Base { int x; public: // default constructor Base() { cout 산출:
기본 클래스 기본 생성자
기본 클래스 기본 생성자
파생 클래스 기본 생성자
기본 클래스 매개 변수화 된 생성자
파생 클래스 매개 변수화 된 생성자
기본 클래스 개체를 만든 후 기본 생성자를 사용하여 파생 클래스 개체를 만드는 것을 볼 수 있습니다. 이 객체가 생성되면 먼저 기본 클래스 기본 생성자가 호출 된 다음 파생 된 클래스 생성자가 실행됩니다.
마찬가지로 매개 변수가있는 생성자를 사용하여 파생 클래스 개체를 만들면 기본 클래스 매개 변수가있는 생성자가 먼저 호출 된 다음 파생 클래스 생성자가 호출됩니다.
기본 클래스에 매개 변수가있는 생성자가 없으면 매개 변수가있는 파생 클래스 개체를 생성하는 경우에도 기본 생성자가 호출되었을 것입니다.
그러나 파생 클래스 개체를 생성하는 동안 기본 클래스 생성자가 호출되는 이유에 대한 질문이 남아 있습니다.
생성자가 클래스의 객체를 생성하고 클래스의 멤버를 초기화하는 데 사용된다는 것을 알고 있습니다. 파생 클래스 개체를 만들 때 생성자는 파생 클래스 멤버에 대한 제어 만 갖습니다.
그러나 파생 클래스는 기본 클래스의 멤버도 상속합니다. 파생 클래스 생성자 만 호출 된 경우 파생 클래스에서 상속 된 기본 클래스 멤버가 제대로 초기화되지 않습니다.
결과적으로 전체 개체가 효율적으로 생성되지 않습니다. 이것이 파생 클래스 개체를 만들 때 모든 기본 클래스 생성자가 먼저 호출되는 이유입니다.
상속 유형
클래스가 파생되는 방식이나 클래스가 상속하는 기본 클래스 수에 따라 아래 그림과 같이 다음과 같은 상속 유형이 있습니다.
'상속 유형'에 대한 다음 자습서에서 이러한 유형을 각각 살펴 보겠습니다.
템플릿 상속
구현에 템플릿이 포함 된 경우 템플릿 클래스에서 상속하거나 파생해야하며 여기에서 템플릿 상속을 사용합니다.
템플릿을 사용하여 상속을 더 잘 이해하기 위해 프로그래밍 예제로 직접 이동하겠습니다.
#include using namespace std; //template inhertance templateclass basecls_Template { public: T value; basecls_Template(T value) { this->value = value; } void displayVal() { cout << value << endl; } }; //derived class inherits basecls_Template class derivedcls_Child : public basecls_Template { public: derivedcls_Child(/* no parameters */): basecls_Template( 0 ){ // default char is NULL; } derivedcls_Child(char c): basecls_Template( c ) { ; } void displayVal_drvd() { displayVal(); } }; int main() { basecls_Template obj( 100 ); derivedcls_Child obj1( 'A' ); cout<<'basecls_Template obj = '; obj.displayVal(); // should print '100' cout< 산출:
basecls_Template obj = 100
파생 된 cls_Child obj1 (basecls_Template = A에서 상 속됨
위의 프로그램에는 기본 클래스에 대한 클래스 템플릿을 정의하는 basecls_Template이라는 템플릿이 있습니다. 다음으로 템플릿 클래스에서 파생하려는 클래스 파생 cls_Child를 정의합니다.
그러나 basecls_Template 클래스는 클래스가 아닌 유형일뿐입니다. 따라서이 템플릿에서 파생 된 cls_Child 클래스를 파생시킬 수 없습니다.
따라서 자식 클래스를 다음과 같이 선언하면
class derivedcls_Child : public basecls_Template
이로 인해 오류가 발생합니다. basecls_Template 인 이유는 클래스가 아니라 데이터 유형입니다. 따라서 basecls_Template의 멤버를 상속하려면 먼저 파생하기 전에 먼저 인스턴스화해야합니다.
따라서 위의 진술은 파생 된 cls_Child 클래스 : 공용 basecls_Template 잘 작동합니다.
이 문장에서 우리는 basecls_Template 템플릿을 문자 클래스 템플릿으로 인스턴스화했습니다. 이 인스턴스화 된 템플릿 클래스를 사용하면 객체 생성 및 사용과 같은 다른 작업이 일반적인 상속 작업과 일치합니다.
구성
지금까지 상속 관계에 대한 모든 것을 보았습니다. 상속은 기본적으로 관계가 부분을 나타내는 관계의 종류를 나타냅니다. 예를 들어 뱀은 일종의 파충류입니다. Reptile이 Animal 클래스의 일부라고 말할 수도 있습니다.
결론적으로 상속은 'IS-A' 파생 클래스가 기본 클래스의 일부라고 말할 수있는 일종의 관계입니다.
관계를 전체적으로 나타낼 수도 있습니다. 예를 들어 Salary 클래스가 Employee 클래스의 일부라고 말하면 제대로 표현되지 않습니다. 직원에게는 급여가 있다는 것을 알고 있습니다. 따라서“직원에게는 급여가 있습니다”라고 말하는 것이 더 편리합니다.
마찬가지로 Vehicles 클래스를 예로 들면 Vehicle에는 Engine이 있거나 Vehicle에는 섀시가 있다고 말할 수 있습니다. 따라서 이러한 모든 관계는 “HAS-A” 다른 클래스에 포함 된 전체 개체를 나타내는 관계. 이것은 다음과 같이 정의됩니다. 구성 .
구성으로 묘사되는 관계는 서로 의존적입니다. 예를 들어 섀시는 차량없이 존재할 수 없습니다. 마찬가지로 급여는 직원없이 존재할 수 없습니다.
다음과 같이 구성을 다이어그램으로 나타낼 수 있습니다.
이 구성은 Containment라고도합니다. 위의 표현에서 우리는 부모 클래스를 보여주었습니다. 상속과 달리 부모 클래스 내에 자식 클래스 개체를 포함합니다. 이것은 봉쇄 또는 구성입니다.
인터뷰 질문과 답변을 지원합니다.
이를 이해하기 위해 프로그래밍 예제를 살펴 보겠습니다.
#include using namespace std; //Composition example //Child class - address class Address { public: string houseNo, building, street, city, state; //Initialise the address object Address(string houseNo,string building,string street, string city, string state) { this->houseNo = houseNo; this->building = building; this->street = street; this->city = city; this->state = state; } }; //Parent class - Employee class Employee { private: Address* address; //composition->Employee has an address public: int empId; string empName; Employee(int empId, string empName, Address* address) { this->empId = empId; this->empName = empName; this->address = address; } void display() { cout< 산출:
10001 Ved
A-101 실버 스프링스 Aundh Pune Maharashtra
이 예제에는 부모 클래스 Employee와 자식 클래스 Address가 있습니다. 부모 클래스 Employee 내에서 Address 클래스에 대한 포인터를 선언하고 Employee 생성자에서이 개체를 초기화했습니다. 따라서 우리는 직원이 구성 인 주소를 갖는 관계를 묘사합니다.
구성과 상속 사이에서 어떻게 결정해야합니까?
구성과 상속은 모두 클래스 간의 관계를 나타냅니다. 상속은 'IS-A'관계를 나타내지 만 구성은 'HAS-A'관계를 나타냅니다.
이제 질문은 언제 상속을 사용해야하고 언제 컴포지션을 사용해야 하는가하는 것입니다. 사실 우리는 둘 중 하나를 사용해야하는 정확한 상황을 결정할 수 없습니다. 각각의 장점과 단점이 있기 때문입니다.
둘 다 코드 재사용을 촉진합니다. 상속은 솔루션이 복잡 해짐에 따라 코드를 대량으로 만들 수 있지만 동시에 기존 코드를 확장 할 수도 있습니다. 따라서 새 클래스 내에서 다른 클래스의 속성과 메서드를 수정하고 사용해야하는 경우 상속을 사용해야합니다.
즉, 더 많은 속성을 추가하고 기존 클래스를 확장하려는 경우입니다. 반면에 다른 클래스의 속성과 동작을 수정하고 싶지 않고 단순히 클래스 내에서 사용하는 경우에는 구성을 수행합니다.
따라서 가장 좋은 결정은 특정 상황에 대한 두 기술의 장단점을 비교하여 구성 또는 상속을 사용할 것인지 여부입니다.
= >> Java로 작성도 읽으십시오.
결론
따라서 우리는 상속에 관한 주제를 끝 맺었습니다. 우리는 다양한 상속 방식을 보았습니다. 다음 튜토리얼에서 살펴볼 상속 유형도 살펴 보았습니다. 상속의 경우 실행되는 생성자의 순서에 대해 배웠습니다.
우리는 또한 템플릿과 상속에 대해서도 공부했습니다. 템플릿 자체는 데이터 유형이고 데이터 유형에서 상속 할 수 없기 때문에 상속에서 사용하기 전에 템플릿을 인스턴스화해야합니다.
컴포지션은 클래스 관계의 또 다른 유형이며 먼저 정확한 상황을 알아야만 컴포지션을 사용할지 상속을 사용할지 결정할 수 있습니다.
다음 자습서에서는 상속 유형에 대해 자세히 알아볼 것입니다.
추천 도서