inheritance c
Importância da herança em C ++ com exemplos:
Herança é um dos recursos mais importantes da programação orientada a objetos.
Herança é a técnica pela qual uma classe adquire as propriedades e métodos de outra classe. Desta forma, podemos reutilizar o código que já está escrito e verificado. A classe que adquire as propriedades de outra classe é chamada de subclasse ou classe derivada ou classe filha.
A classe cujas propriedades são adquiridas é chamada de classe base ou classe pai ou superclasse. Quando uma classe adquire ou herda outra classe, todas as propriedades e métodos da classe base estão disponíveis para a classe derivada, para que possamos reutilizar esse código.
=> Visite aqui para aprender C ++ do zero.
o que a análise estática não pode encontrar
O que você aprenderá:
- Por que precisamos de herança?
- Modos de herança
- Ordem dos construtores / herança dos destruidores
- Tipos de herança
- Herança de modelo
- Composição
- Como devemos decidir entre composição e herança?
- Conclusão
- Leitura recomendada
Por que precisamos de herança?
Considere um grupo de veículos como carro, ônibus, jipe, etc. Cada um desses veículos terá propriedades e métodos conforme indicado no diagrama abaixo.
Se formos obrigados a implementar classes individuais para os veículos acima, podemos ver que em todas as três classes, teremos que escrever o mesmo código, pois todos os três tipos de veículos exibem mais ou menos as mesmas propriedades. Isso tornará nosso programa ineficiente e complicado, pois haverá muitos códigos duplicados.
Em vez de escrever um código duplicado como acima, podemos implementar o recurso de herança para evitar que o código se duplique e também escrever um único trecho de código e usá-lo em todas as três classes. Isso é representado pictoricamente conforme abaixo.
Na figura acima, definimos uma classe base “Veículos” e derivamos as classes Carro, Ônibus e Jeep desta classe. Os métodos e propriedades comuns agora fazem parte da classe Vehicles. Como outras classes são derivadas da classe Vehicles, todas as classes adquirem esses métodos e propriedades.
Portanto, precisamos escrever o código comum apenas uma vez e todas as três classes; Carro, ônibus e jipe irão adquiri-lo.
Portanto, a principal vantagem que obtemos ao herdar as classes existentes ou projetar um mecanismo de herança é a capacidade de reutilização do código.
Leitura Adicional = >> Tutorial de herança Java
O formato geral para herdar uma classe é:
class derived_classname: access_specifier base_classname { };
Aqui ' nome_de_classe derivado ”É o nome da classe derivada,“ access_specifier 'É o modo de acesso, ou seja, público, protegido ou privado em que a classe derivada deve herdar a classe base e' nome_de_classe derivado ”É o nome da classe base da qual a classe derivada herda.
Modos de herança
O “access_specifier” mostrado na declaração de herança acima, pode ter seus valores conforme mostrado abaixo.
Dependendo do access_specifier especificado quando herdamos a classe, temos vários modos de herança, conforme listado abaixo.
Herança Pública
Sintaxe geral
class sub_class : public parent_class
Quando o especificador de acesso público é especificado, os membros públicos da classe base são herdados como públicos, enquanto os membros protegidos são protegidos. Membros privados permanecem privados. Este é o modo de herança mais popular.
Herança Privada
Sintaxe Geral
class sub_class : parent_class
A herança privada não herda nada. Quando o especificador de acesso privado é usado, os membros públicos e protegidos da classe base também se tornam privados.
Herança protegida
Sintaxe Geral
class sub_class:protected parent_class
Quando o especificador de acesso protegido é usado, os membros públicos e protegidos da classe base tornam-se membros protegidos na classe derivada.
Observe que quando usamos o especificador de acesso privado para a classe base, nenhum dos membros da classe base é herdado. Todos eles se tornam privados na classe derivada.
A seguir está a representação tabularizada de todos os modos de acesso e sua interpretação para herança.
Classe Derivada -> Classe base | Privado | Público | Protegido |
---|---|---|---|
Privado | Não herdado | Não herdado | Não herdado |
Público | Privado | Público | Protegido |
Protegido | Privado | Protegido | Protegido |
Ordem dos construtores / herança dos destruidores
Quando as classes são herdadas, os construtores são chamados na mesma ordem em que as classes são herdadas. Se tivermos uma classe base e uma classe derivada que herda essa classe base, então o construtor da classe base (seja padrão ou parametrizado) será chamado primeiro seguido pelo construtor da classe derivada.
O programa a seguir demonstra a ordem dos construtores na herança. Temos uma classe Base “Base” que possui um construtor padrão e um construtor parametrizado. Derivamos uma classe desta chamada “Derivada”, que também possui um construtor padrão e outro parametrizado.
implementação de c ++ de tabela hash de encadeamento separada
A saída deste programa mostra a ordem em que os construtores são chamados.
#include using namespace std; //order of execution of constructors in inheritance class Base { int x; public: // default constructor Base() { cout Resultado:
Construtor padrão da classe base
Construtor padrão da classe base
Construtor padrão de classe derivada
Construtor parametrizado de classe base
Construtor parametrizado de classe derivada
Vemos que, depois de criar o objeto da classe base, criamos um objeto da classe derivada com um construtor padrão. Quando este objeto é criado, primeiro o construtor padrão da classe base é chamado e, em seguida, o construtor da classe derivada é executado.
Da mesma forma, quando o objeto da classe derivada é criado usando o construtor parametrizado, o construtor parametrizado da classe base é chamado primeiro e, em seguida, o construtor da classe derivada é chamado.
Observe que, se não houvesse um construtor parametrizado na classe base, o construtor padrão teria sido chamado até mesmo para construir o objeto de classe derivado parametrizado.
Mas a questão permanece: por que o construtor da classe base é chamado durante a construção dos objetos da classe derivada?
Sabemos que um construtor é usado para criar objetos da classe e também para inicializar os membros da classe. Quando o objeto da classe derivada é criado, seu construtor tem controle apenas sobre os membros da classe derivada.
No entanto, a classe derivada também herda os membros da classe base. Se apenas o construtor da classe derivada fosse chamado, os membros da classe base herdados pela classe derivada não seriam inicializados corretamente.
Como resultado, o objeto inteiro não será criado de forma eficiente. Esse é o motivo pelo qual todos os construtores da classe base são chamados primeiro quando um objeto de classe derivada é criado.
Tipos de herança
Dependendo da maneira como a classe é derivada ou de quantas classes base uma classe herda, temos os seguintes tipos de herança, conforme ilustrado na figura abaixo.

Exploraremos cada um desses tipos em nosso próximo tutorial sobre “Tipos de herança”.
Herança de modelo
Quando nossa implementação envolve modelos, então precisamos herdar ou derivar de classes de modelo e fazemos uso da herança de modelo aí.
Vamos pular diretamente para um exemplo de programação para entender melhor a herança usando modelos.
#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< Resultado:
basecls_Template obj = 100
derivadocls_Child obj1 (herdado de basecls_Template = A
No programa acima, temos um modelo chamado basecls_Template que define o modelo de classe para a classe base. Em seguida, definimos uma classe derivadacls_Child que desejamos derivar de uma classe de modelo.
Mas observe que a classe basecls_Template é apenas um tipo e não uma classe. Portanto, não podemos derivar a classe associatedcls_Child desse modelo.
Portanto, se declararmos a classe filha como:
class derivedcls_Child : public basecls_Template
Isso resultará em um erro. O motivo é basecls_Template ser um tipo de dados e não uma classe. Portanto, para herdar os membros de basecls_Template, devemos primeiro instanciá-lo antes de derivá-lo.
Portanto, a declaração acima, Classe derivadacls_Child: public basecls_Template funciona bem.
Nesta declaração, instanciamos o template basecls_Template para um template de classe de personagem. Uma vez que usamos esta classe de modelo instanciada, então as outras coisas seguintes, como criar e usar objetos, coincidem com o funcionamento normal de herança.
Composição
Até agora, vimos tudo sobre relacionamentos de herança. A herança descreve basicamente o tipo de relacionamento em que o relacionamento indica uma parte. Por exemplo, uma cobra é uma espécie de réptil. Também podemos dizer que Reptile faz parte da classe Animal.
Em conclusão, a herança indica 'É UM' tipo de relacionamento em que podemos dizer que a classe derivada é uma parte da classe base.
Também podemos representar relacionamentos como um todo. Por exemplo, se dissermos que a classe Salário faz parte da classe Funcionário, então não a estamos representando corretamente. Sabemos que Funcionário tem um salário. Assim, é mais conveniente dizer “O empregado tem um salário”.
Da mesma forma, se tomarmos a classe Veículos como exemplo, podemos dizer que Veículo tem Motor ou Veículo tem chassi. Assim, todos esses relacionamentos retratam 'TEM UM' relacionamentos que representam um objeto inteiro contido em outra classe. Isso é definido como Composição .
Os relacionamentos representados pela composição dependem uns dos outros. Por exemplo, um Chassis não pode existir sem um Veículo. Da mesma forma, o salário não pode existir sem um funcionário.
Podemos representar a composição em diagrama, conforme mostrado abaixo:

A composição também é denominada Contenção. Na representação acima, mostramos uma classe pai. Em contraste com a herança, incluímos um objeto de classe filho dentro da classe pai. Isso é contenção ou composição.
o que é um arquivo .swf
Vamos dar um exemplo de programação para entender isso.
#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< Resultado:
10001 Ved
A-101 Silver Springs Aundh Pune Maharashtra
Neste exemplo, temos uma classe pai Employee e uma classe filha Address. Dentro da classe pai Employee, declaramos um ponteiro para a classe Address e também inicializamos esse objeto no construtor Employee. Assim, retratamos a relação que o Funcionário tem com um Endereço que é de composição.
Como devemos decidir entre composição e herança?
Composição e herança representam os relacionamentos entre as classes. Enquanto a herança descreve o relacionamento “IS-A”, a composição descreve o relacionamento “HAS-A”.
Agora, a questão é quando devemos usar herança e quando devemos usar composição? Na verdade, não podemos decidir sobre as situações exatas de quando devemos usar qualquer uma delas. Isso ocorre porque cada um tem suas próprias vantagens e desvantagens.
Ambos promovem a reutilização do código. A herança pode tornar o código volumoso à medida que as soluções se tornam complexas, mas, ao mesmo tempo, também nos permite estender o código existente. Portanto, devemos usar herança quando nosso requisito é modificar e usar as propriedades e métodos de outra classe dentro da nova classe.
Em outras palavras, quando queremos adicionar mais propriedades e estender a classe existente. Por outro lado, quando não queremos modificar as propriedades e o comportamento de outra classe, mas simplesmente usá-la dentro da classe, partimos para a composição.
Portanto, a melhor decisão é se usar composição ou herança será feita pesando os prós e os contras de ambas as técnicas para a situação particular.
= >> Leia também Composição em Java
Conclusão
Assim, chegamos ao fim de nosso tópico sobre herança. Vimos vários modos de herança. Também vimos os tipos de herança, que exploraremos em nosso próximo tutorial. Aprendemos sobre a ordem dos construtores que são executados em caso de herança.
Também estudamos sobre modelos e herança. Precisamos instanciar um modelo antes de podermos usá-lo na herança, pois o próprio modelo é um tipo de dados e não podemos herdar de um tipo de dados.
A composição é outro tipo de relacionamento de classe e precisamos saber a situação exata primeiro e só então podemos decidir se usaremos composição ou herança.
Em nosso próximo tutorial, veremos mais sobre os tipos de herança.
=> Cuidado com a série de treinamento simples em C ++ aqui.
Leitura recomendada
- Tipos de herança em C ++
- Polimorfismo de tempo de execução em C ++
- Funções de amigo em C ++
- Uso de Selenium Select Class para lidar com elementos suspensos em uma página da Web - Selenium Tutorial # 13
- Classes e objetos em C ++
- Estático em C ++
- Tutorial de Pipes Unix: Pipes em Programação Unix
- Interface Java e tutorial de classe abstrata com exemplos