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 e herdam características da classe , e até aqui está tudo bem. O problema acontece na classe , pois ao herdas as classes e , ela acabada herdado também duas cópias de tudo que existe na classe , gerando vários conflitos e ambiguidades. A melhor forma de resolver isso é efetuando uma herança virtual da classe . E depois vamos precisar lembrar que o construtor da classe 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
![]()
Vamos declarar o atributo privado do tipo 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 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 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 está pronta.
Passo 3
Show, vamos agora pra classe , essa classe vai herdar a classe , mas tem um detalhe, estamos tratando de um problema do diamante e nessa situação precisamos efetuar uma herança virtual:
No código é assim:
![]()
Beleza, vamos desenvolver o conteúdo da classe. Vamos declarar um atributo chamado 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 para inicializar o atributo herdado :

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 para que ele imprima também o atributo dessa classe:

E assim concluímos a classe .
Passo 4
A próxima classe que vamos desenvolver é a . 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 que se for representa um barco, e se for 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 é privado, vai ser necessário construir um setter e um getter:
![]()
E pra terminar, a gente vai efetuar um polimorfismo sobre o método 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 . 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 e . 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 , e , e depois inicializa o atributo

E agora o mais difícil acabou! Precisamos criar um setter e um getter para o atributo pois ele é privado:
![]()
E pra finalizar a classe vamos executar o polimorfismo do método para que ele imprima todos os atributos herdados e originais da classe :

Passo 6
Beleza! Agora só resta a gente testar!
Criamos um objeto da classe e executamos o método

O resultado é:

Resposta

