Home Aplicativo VirtualPet com herança
Post
Cancelar

Aplicativo VirtualPet com herança

Uma das principais características e vantagens da OO é a possibilidade de reutilização de código. Uma das propriedades que as classes podem ter que permite este reúso é a herança.

Assim como no mundo real, as gerações posteriores agregam características e conhecimento das gerações anteriores, a OO prevê que uma classe possa “passar” suas características e comportamentos para outras classes por meio do recurso da herança. Baseado no exemplo do jogo Virtual PET para criar a simulação de um bicho de estimação virtual, imagine que fosse necessário implementar algumas características especiais para um grupo específico de animais doméstico como aves.

Essa implementação seria a inserção dos atributos COR_PENA (literal) e VOA(lógico) e o método VOAR (método que receberá um número entre 0 e 100 para especificar a distância em metros que será percorrida pela ave, bem como retirará 0,5 caloria, para cada metro, se ela puder voar além de 3 metros do atributo força).

Você poderá até se perguntar: não há outros bichos que voam? Sim, porém para ilustrar este exemplo, serão mencionados apenas animais que voam e são domésticos (apesar de algumas pessoas criarem morcegos, abelhas, etc.). A partir daí, a primeira menção será inserir imediatamente na classe ANIMAL os atributos e o método solicitados. Nesse caso, todos os animais passariam a ter essas características e esse método. Isso seria extremamente errado, pois um gato não possui COR_PENA e não pode VOAR. A outra possibilidade seria criar outra classe chamada AVE e “copiar” todos os atributos e métodos para ela, acrescentando os já solicitados. Nesse caso, apesar de parecer mais correto, haveria dois inconvenientes.

Primeiro, a necessidade de codificar novamente uma outra classe com toda codificação. E o segundo, não haveria nenhuma ligação entre as classes. Isso faria com que qualquer alteração importante na classe Animal não fosse refletida na classe Ave.

A herança entre classes resolveria esse problema, pois a Ave não deixou de pertencer à classe. Ela apenas terá a necessidade de especificar mais algumas características e ações.

O sistema Virtual PET poderá ser confeccionado em uma ou mais classe, ou seja, se você tiver na classe Animal o método principal que gera a aplicação, dirá que essa classe é uma classe de definição e aplicação (possui as definições - atributos e métodos - e a aplicação - o método principal que tem a responsabilidade de executar o sistema). Porém, você poderá ter duas classes: Animal e Virtual PET, sendo a primeira uma classe de definição e a segunda de aplicação.

Primeira possibilidade

Primeira possibilidade: três classes, duas de definição (ANIMAL e AVE) e uma de aplicação (VIRTUAL PET). Veja o exemplo a seguir:

1P Diagrama de classes UML

Aqui está o diagrama de classe UML representando as classes “ANIMAL”, “AVE” e “VIRTUAL_PET” com base no código fornecido:

classDiagram
    class ANIMAL {
        - NOME : literal
        - CLASSE : literal
        - FAMILIA : literal
        - IDADE : numérico
        - CALORIA : numérico
        - FORCA : numérico
        - ESTADO : lógico
        + ANIMAL(N: literal, C: literal, F: literal)
        + ~ANIMAL()
        + INSERIR_NOME(N: literal)
        + INSERIR_CLASSE(C: literal)
        + INSERIR_FAMILIA(F: literal)
        + OBTER_NOME(): literal
        + OBTER_ESTADO(): literal
        + INSERIR_CLASSE(): literal
        + INSERIR_FAMILIA(): literal
        + COMER()
        + CORRER()
        + DORMIR()
    }

    class AVE {
        - COR_PENA : literal
        - VOA : lógico
        + AVE(NA: literal, CA: literal, FA: literal, CP: literal, V: lógico)
        + INSERIR_COR_PENA(CP: literal)
        + OBTER_COR_PENA(): literal
        + INSERIR_VOA(V: lógico)
        + OBTER_VOA(): lógico
        + VOAR(MTS: numérico)
    }

    class VIRTUAL_PET {
        - OPCAO : literal
        - ACAO : literal
        - N : literal
        - CL : literal
        - FM : literal
        - ANIMALVIRTUAL : ANIMAL
        - AVEVIRTUAL : AVE
        + VIRTUAL_PET()
    }

    ANIMAL <|-- AVE
    VIRTUAL_PET --> ANIMAL
    VIRTUAL_PET --> AVE

Observe que a classe VIRTUAL_PET é representada separadamente, mesmo que seja apenas uma coleção de variáveis e métodos relacionados. Os relacionamentos de herança e composição são mostrados corretamente no diagrama.

1P Algoritmo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
classe ANIMAL
  
  protegido NOME, CLASSE, FAMILIA : literal
  protegido IDADE,CALORIA,FORCA: numérico
  protegido ESTADO:lógico
  construtor ANIMAL (N, C, F: literal)  
    NOME ← N
    CLASSE ← C
    FAMILIA ← F
    CALORIA ← 10
    FORCA ← 10
    ESTADO ← verdadeiro
    IDADE ← 0   
  fim-construtor

  destruidor ANIMAL (  )  
    ESTADO ← falso
    FORCA ← 0 
      escreva "Morto!"  
  fim-destruidor

  método público INSERIR_NOME (N: literal)  
      NOME ← N  
  fim-método

  método público INSERIR_CLASSE (C: literal)  
      CLASSE ← C  
  fim-método

  método público INSERIR_FAMILIA (F: literal)  
    FAMILIA ← F  
  fim-método

  método público literal OBTER_NOME (  )
    retorne NOME   
  fim-método

  método público literal OBTER_ESTADO (  )  
    retorne ESTADO   
  fim-método

  método público literal INSERIR_CLASSE (  )  
    retorne CLASSE   
  fim-método

  método público literal INSERIR_FAMILIA (  )  
    retorne FAMILIA   
  fim-método

  método público COMER (  )  
    se (ESTADO e FORCA > 10)   
      então CALORIA ← CALORIA + 20
        FORCA ← FORCA - 10
    senão se (ESTADO)
      então escreva "O animal está morto e não pode comer!"
      senão escreva "O animal está exausto!Faça-o dormir um pouco!"  
      fim-se  
    fim-se  
  fim-método

  método público CORRER ( )  
    se (ESTADO e FORCA > 10 e CALORIA > 10 )   
      então CALORIA ← CALORIA - 10
        FORCA ← FORCA - 10
    senão se (ESTADO)  
      então escreva "O animal está morto e não pode correr!"
    senão se (CALORIA < 10)  
      então escreva "O animal está fraco!Faça-o comer!"
    senão escreva "O animal está exausto! Faça-o dormir!"  
      fim-se  
  fim-método

  método público DORMIR ( )  
    se (ESTADO)   
      então CALORIA ← CALORIA - 5
        FORCA ← FORCA +20
    senão escreva "O animal está morto!"  
    fim-se  
  fim-método.
fim-classe

classe AVE herda_de ANIMAL

privado COR_PENA: literal
privado VOA:lógico

construtor AVE (NA,CA,FA,CP,V:literal)
  super.ANIMAL (NA, CA, FA)
  COR_PENA ← CP
  VOA ← V
fim-construtor

método público INSERIR_COR_PENA(CP:literal)
  COR_PENA ← CP
fim-método

método público literal OBTER_COR_PENA(  )
  retorne COR_PENA 
fim-método

método público INSERIR_VOA(V:lógico)
    VOA ← V
fim-método

método público lógico OBTER_VOA(  )
    retorne VOA 
fim-método

método público VOAR ( MTS:numérico )
  se (super.ESTADO e VOA e FORCA > = 3 e CALORIA > MTS*0,5)
    então CALORIA ← CALORIA -  MTS*0,5
      FORCA ← FORCA - 3
  senão se (super.ESTADO)
    então escreva "A ave está morta e não pode voar!"
  senão se (não VOA)
    então escreva "A ave não voa!"
  senão escreva "A ave está exausta! Faça-a dormir um pouco!"
  fim-se
fim-classe

classe VIRTUAL_PET

início

OPCAO,ACAO,N,CL,FM :literal
ANIMAL ANIMALVIRTUAL 
AVE  AVEVIRTUAL 
escreva "Você quer cuidar de uma ave ou outro animal? Digite 1 → Ave, 2 → Outro animal  ou 0 → Encerrar"

leia OPCAO
enquanto (OPCAO <> 0) faça

se (OPCAO = 1)
  então escreva "Qual o nome da sua ave?"
  leia N
  escreva "Qual a classe da sua ave?"
  leia CL
  escreva "Qual a família da ave?"
  leia FM
  escreva "Qual  a cor da pena da ave?"
  leia CP 
  escreva "A sua ave voa?"
  leia V
  AVEVIRTUAL ← novo AVE (N,CL,FM,CP,V)
  escreva "Sua ave ",AVEVIRTUAL.OBTER_NOME( ), "nasceu!"
  senão escreva "Qual o nome do seu animal?"
  leia N
  escreva "Qual a classe do seu animal?"
  leia CL
  escreva "Qual a família do seu animal?"
  leia FM
  ANIMAL VIRTUAL ← ANIMAL(N,CL,FM)
  escreva "Seu animal ",ANIMAL.OBTER_NOME( ), "nasceu!"
fim-se
repita
  se (OPCAO = 1)
    então se (ANIMAL VIRTUAL.OBTER_ESTADO( ) )
    então escreva "Digite a ação você quer ?"
    escreva "C → Comer, R → correr ou D → Dormir ou E → Encerrar"
    leia ACAO
  senão ACAO ← "MORTO"
  fim-se
caso ACAO
  seja "C" faça ANIMAL VIRTUAL.COMER( )
  seja "R" faça ANIMAL VIRTUAL.CORRER( )
  seja "D" faça ANIMAL VIRTUAL.DORMIR( )
  seja "E" faça escreva "Você está abandonando seu animal!"
  seja "MORTO" faça escreva "Seu animal morreu! Não há mais chance!"
  senão escreva "Ação inválida!"
fim-caso
senão se (AVEVIRTUAL.OBTER_ESTADO( ) )
  então escreva "Digite a ação você quer ?"
  escreva "C ← Comer, R ← correr, V← Voar,  D ← Dormir ou E ← Encerrar"
  leia ACAO
senão ACAO ← "E"
fim-se
caso ACAO
  seja "C" faça AVEVIRTUAL.COMER( )
  seja "R" faça AVEVIRTUAL.CORRER( )
  seja "V" faça AVEVIRTUAL.VOAR ( )
  seja "D" faça AVEVIRTUAL.DORMIR ( )
  seja "E" faça escreva "Você está abandonando seu animal!"
  seja "MORTO" faça escreva "Seu animal morreu! Não há mais chance!"
  senão escreva "Ação inválida!"
fim-caso
fim-se

até que (ACAO = "E")
  escreva "Você quer cuidar de uma ave ou outro animal? Digite 1 → Ave, 2→ Outro animal  ou 0→ Encerrar"
  leia OPCAO
fim-enquanto

fim
fim-classe

Segunda possibilidade

Segunda possibilidade: duas classes, uma somente de definição (ANIMAL) e outra contendo definição e aplicação (AVE). Como mostra o exemplo a seguir:

2P diagrama de classes

Aqui está o diagrama de classes UML em formato Mermaid para as classes “ANIMAL” e “AVE”:

classDiagram
    class ANIMAL {
        - NOME : literal
        - CLASSE : literal
        - FAMILIA : literal
        - IDADE : numérico
        - CALORIA : numérico
        - FORCA : numérico
        - ESTADO : lógico
        + ANIMAL(N: literal, C: literal, F: literal)
        + ~ANIMAL()
        + INSERIR_NOME(N: literal)
        + INSERIR_CLASSE(C: literal)
        + INSERIR_FAMILIA(F: literal)
        + OBTER_NOME(): literal
        + OBTER_ESTADO(): literal
        + INSERIR_CLASSE(): literal
        + INSERIR_FAMILIA(): literal
        + COMER()
        + CORRER()
        + DORMIR()
    }

    class AVE {
        - COR_PENA : literal
        - VOA : lógico
        + AVE(NA: literal, CA: literal, FA: literal, CP: literal, V: literal)
        + INSERIR_COR_PENA(CP: literal)
        + OBTER_COR_PENA(): literal
        + INSERIR_VOA(V: lógico)
        + OBTER_VOA(): lógico
        + VOAR(MTS: numérico)
    }

    ANIMAL <|-- AVE

Este é o diagrama de classes UML que representa a estrutura das classes “ANIMAL” e “AVE”. A classe “ANIMAL” contém os atributos NOME, CLASSE, FAMILIA, IDADE, CALORIA, FORCA e ESTADO, juntamente com os métodos construtor, destruidor e outros métodos como INSERIR_NOME, INSERIR_CLASSE, OBTER_NOME, COMER, CORRER e DORMIR.

A classe “AVE” herda da classe “ANIMAL” e adiciona os atributos COR_PENA e VOA, juntamente com os métodos construtor, INSERIR_COR_PENA, OBTER_COR_PENA, INSERIR_VOA, OBTER_VOA e VOAR.

A seta “ANIMAL <– AVE” indica que a classe “AVE” herda da classe “ANIMAL”.

2P algoritmo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
classe ANIMAL

protegido NOME, CLASSE, FAMILIA : literal
protegido IDADE,CALORIA,FORCA: numérico
protegido ESTADO:lógico
construtor ANIMAL (N, C, F: literal)

  NOME ← N
  CLASSE ← C
  FAMILIA ← F
  CALORIA ← 10
  FORCA ← 10
  ESTADO ← verdadeiro
  IDADE ← 0 

fim-construtor
destruidor ANIMAL (  )

  ESTADO ← falso
  FORCA ← 0 
  escreva "Morto!"

fim-destruidor
método público INSERIR_NOME (N: literal)
  NOME ← N
fim-método

método público INSERIR_CLASSE (C: literal)
  CLASSE ← C
fim-método

método público INSERIR_FAMILIA (F: literal)
  FAMILIA ← F
fim-método

método público literal OBTER_NOME (  )
  retorne NOME 
fim-método

método público literal OBTER_ESTADO (  )
  retorne ESTADO 
fim-método

método público literal INSERIR_CLASSE (  )
  retorne CLASSE 
fim-método

método público literal INSERIR_FAMILIA (  )
  retorne FAMILIA 
fim-método

método público COMER (  )
  se (ESTADO e FORCA > 10) 
    então CALORIA ← CALORIA + 20
      FORCA ← FORCA - 10
  senão se (ESTADO)
    então escreva "O animal está morto e não pode comer!"
    senão escreva "O animal está exausto!Faça-o dormir um pouco!"
  fim-se
  fim-se
fim-método

método público CORRER ( )
  se (ESTADO e FORCA > 10 e CALORIA > 10 ) 
    então CALORIA ← CALORIA - 10
      FORCA ← FORCA - 10
  senão se (ESTADO)
    então escreva "O animal está morto e não pode correr!"
  senão se (CALORIA < 10)
    então escreva "O animal está fraco! Faça-o comer!"
  senão escreva "O animal está exausto! Faça-o dormir!"
  fim-se
  fim-se
fim-método

método público DORMIR ( )
  se (ESTADO) 
    então CALORIA ← CALORIA - 5
    FORCA ← FORCA +20
  senão escreva "O animal está morto!"  
  fim-se  
fim-método

fim-classe

classe AVE herda_de ANIMAL
  
privado COR_PENA: literal
privado VOA:lógico

construtor AVE (NA,CA,FA,CP,V:literal)  
  super.ANIMAL (NA, CA, FA)
  COR_PENA ← CP
  VOA ← V  
fim-construtor

método público INSERIR_COR_PENA(CP:literal)
  COR_PENA ← CP  
fim-método

método público literal OBTER_COR_PENA(  )  
  retorne COR_PENA   
fim-método

método público INSERIR_VOA(V:lógico)  
  VOA ← V  
fim-método

método público lógico OBTER_VOA(  )  
  retorne VOA   
fim-método

método público VOAR ( MTS:numérico )  
  se (super.ESTADO e VOA e FORCA > = 3 e CALORIA > MTS*0,5)  
    então CALORIA ← CALORIA -  MTS*0,5
      FORCA ← FORCA - 3
  senão se (super.ESTADO)
    então escreva "A ave está morta e não pode voar!"
  senão se (não VOA)  
    então escreva "A ave não voa!"
  senão escreva "A ave está exausta! Faça-a dormir um pouco!"  
  fim-se  
  fim-se
fim-método

início

OPCAO,ACAO,N,CL,FM :literal
ANIMAL ANIMAL VIRTUAL 
AVE  AVEVIRTUAL 

escreva "Você quer cuidar de uma ave ou outro animal? Digite 1 → Ave, 2 → Outro animal  ou 0 → Encerrar"
leia OPCAO

enquanto (OPCAO <> 0) faça
  se (OPCAO = 1)
    então escreva "Qual o nome da sua ave?"
    leia N
    escreva "Qual a classe da sua ave?"
    leia CL
    escreva "Qual a família da ave?"
    leia FM
    escreva "Qual  a cor da pena da ave?"
    leia CP 
    escreva "A sua ave voa?"
    leia V
    AVEVIRTUAL ← novo AVE (N,CL,FM,CP,V)
    escreva "Sua ave ",AVEVIRTUAL.OBTER_NOME( ), "nasceu!"
  senão escreva "Qual o nome do seu animal?"
    leia N
    escreva "Qual a classe do seu animal?"
    leia CL
    escreva "Qual a família do seu animal?"
    leia FM
    ANIMALVIRTUAL ← ANIMAL(N,CL,FM)
    escreva "Seu animal ",ANIMAL.OBTER_NOME( ), "nasceu!"
  fim-se
repita
  se (OPCAO = 1)
    então se (ANIMALVIRTUAL.OBTER_ESTADO( ) )
    então escreva "Digite a ação você quer ?"
    escreva "C → Comer, R → correr ou D → Dormir ou E → Encerrar"
    leia ACAO
  senão ACAO ← "MORTO"
fim-se

caso ACAO
  seja "C" faça ANIMALVIRTUAL.COMER( )
  seja "R" faça ANIMALVIRTUAL.CORRER( )
  seja "D" faça ANIMALVIRTUAL.DORMIR ( )
  seja "E" faça escreva "Você está abandonando seu animal!"
  seja "MORTO" faça escreva "Seu animal morreu! Não há mais chance!"
  senão escreva "Ação inválida!"
fim-caso
senão se (AVEVIRTUAL.OBTER_ESTADO( ) )
  então escreva "Digite a ação você quer ?"
  escreva "C → Comer, R → correr, V → Voar,  D → Dormir ou E → Encerrar"
  leia ACAO
senão ACAO ← "E"
fim-se

caso ACAO
  seja "C" faça AVEVIRTUAL.COMER( )
  seja "R" faça AVEVIRTUAL.CORRER( )
  seja "V" faça AVEVIRTUAL.VOAR ( )
  seja "D" faça AVEVIRTUAL.DORMIR ( )
  seja "E" faça escreva "Você está abandonando seu animal!"
  seja "MORTO" faça escreva "Seu animal morreu! Não há mais chance!"
  senão escreva "Ação inválida!"
fim-caso
fim-se

até que (ACAO = "E")
  escreva "Você quer cuidar de uma ave ou outro animal? Digite 1 → Ave, 2 → Outro animal  ou 0 → Encerrar"
  leia OPCAO
fim-enquanto

fim
fim-classe

Implementação

A implementação da primeira possibilidade, usando 3 classes está no repositório do Github: github.com/jocile/virtualpet

Referências

GitHub VirtualPet

Xavier, Gley Fabiano Cardoso - Lógica de programação cap. 10, E-book. Disponível em: https://bibliotecadigitalsenac.com.br/?from=%3FcontentInfo%3D1306#/legacy/epub/1306. Acesso em 19/05/2023

Esta postagem está licenciada sob CC BY 4.0 pelo autor.