Exercícios Resolvidos de Mais herança e mais polimorfismo

Ver Teoria

Enunciado

Implemente a hierarquia de herança múltipla definida pelo diagrama abaixo. Em cada classe defina um construtor, um atributo com getter e setter, e um método print, que imprime todos os dados do veículo.

Passo 1

Vamos nessa, pessoal!

Só de olhar pro diagrama da questão, a gente vê que temos um problema do diamante. Esse problema acontece quando uma classe derivada herda duas classes “irmãs”.

Observe que as classes V e i c u l o T e r r e s t e e V e i c u l o A q u a t i c o herdam características da classe V e i c u l o , e até aqui está tudo bem. O problema acontece na classe V e i c u l o A n f i b i o , pois ao herdas as classes V e i c u l o T e r r e s t e e V e i c u l o A q u a t i c o , ela acabada herdado também duas cópias de tudo que existe na classe V e i c u l o , gerando vários conflitos e ambiguidades. A melhor forma de resolver isso é efetuando uma herança virtual da classe V e i c u l o . E depois vamos precisar lembrar que o construtor da classe V e í c u l o A n f i b i o vai p

Um resumo de como resolver o problema do diamante está abaixo:

Para resolver o diamante a gente herda a classe do topo de forma virtual, e modifica um pouquinho o construtor da classe de baixo.

Mas antes de mais nada, vamos começar com o cabeçalho do código:

Passo 2

Vamos definir a classe raiz V e i c u l o

Vamos declarar o atributo privado M o d e l o do tipo s t r i n g que representa o modelo do veículo.

Em seguida, vamos declarar o construtor dessa classe para inicializar o atributo:

Para ter acesso ao atributo privado, vamos desenvolver métodos setters e getters

E pra terminar a classe vamos desenvolver o método p r i n t ( ) que imprime o conteúdo de todos os atributos da classe. Nesse caso, temos apenas um atributo, então vai ser tranquilo. Um ponto importante é que o método p r i n t vai existir dentro das classes filhas também, ou seja, vai sofrer polimorfismo e por isso o ideal é declarar esse método como virtual.

E prontinho, a classe V e i c u l o está pronta.

Passo 3

Show, vamos agora pra classe V e i c u l o T e r r e s t r e , essa classe vai herdar a classe V e i c u l o , mas tem um detalhe, estamos tratando de um problema do diamante e nessa situação precisamos efetuar uma herança virtual:

c l a s s   C l a s s e D e r i v a d a   : v i r t u a l   p u b l i c   C l a s s e B a s e

No código é assim:

Beleza, vamos desenvolver o conteúdo da classe. Vamos declarar um atributo chamado C a l i b r a g e m que representa a pressão do pneu desse veículo.

Depois, vamos desenvolver um construtor para inicializar os atributos da classe. Aqui vamos aproveitar para executar o construtor da classe mãe V e i c u l o para inicializar o atributo herdado M o d e l o :

Seguindo em frente, vamos desenvolver métodos setter e getter para o atributo da classe:

E antes de finalizar a classe vamos efetuar um polimorfismo sobre o método p r i n t para que ele imprima também o atributo dessa classe:

E assim concluímos a classe V e i c u l o T e r r e s t r e .

Passo 4

A próxima classe que vamos desenvolver é a V e i c u l o A q u a t i c o . Da mesma forma que a classe anterior temos que lembrar que estamos resolvendo um problema do diamante então na hora de executar a herança vamos ter de fazer uma herança virtual:

Massa! Agora é só desenvolver a classe com tranquilidade. Vamos criar um atributo F l u t u a que se for t r u e representa um barco, e se for f a l s e representa um submarino.

O passo seguinte é desenvolver um método construtor que inicializa o atributo dessa classe, e que também executa o construtor da classe mãe.

Como o atributo F l u t u a é privado, vai ser necessário construir um setter e um getter:

E pra terminar, a gente vai efetuar um polimorfismo sobre o método p r i n t ( ) para que ele imprima os atributos existentes dentro dessa classe:

Passo 5

Belezinha, agora chegou a hora do ponto final da questão, desenvolver a classe V e i c u l o A n f i b i o . Tenha sempre em mente que as quatro classes estão relacionadas pelo problema do diamante, e isso será importante mais na frente.

Aqui vamos utilizar herança dupla para herdar as classes V e i c u l o T e r r e s t r e e V e i c u l o A q u a t i c o . Um ponto interessante é que não é necessário efetuar herança virtual aqui.

Show de bola, com as classes herdadas podemos adicionar um atributo à classe anfíbia:

E agora podemos nos concentrar no construtor da classe. Aqui entra o detalhe. Normalmente, não é necessário chamar o construtor da classe “avó”. Porém, quando se trata de um diamante é necessário fazer uma chamada explicita ao construtor da classe ancestral.

Então vamos fazer um construtor que faz chamada aos construtores das classes V e i c u l o T e r r e s t r e , V e i c u l o A q u a t i c o e V e i c u l o , e depois inicializa o atributo M a r c a

E agora o mais difícil acabou! Precisamos criar um setter e um getter para o atributo M a r c a pois ele é privado:

E pra finalizar a classe vamos executar o polimorfismo do método p r i n t para que ele imprima todos os atributos herdados e originais da classe V e i c u l o A n f i b i o :

Passo 6

Beleza! Agora só resta a gente testar!

Criamos um objeto da classe V e i c u l o A n f i b i o e executamos o método p r i n t ( )

O resultado é:

Resposta