A herança é um mecanismo que permite estender uma classe sem modificar a classe original. Isso tem diversos benefícios que serão estudados posteriormente. Considere a classe Emprestimo
que desenvolvemos na etapa anterior. O modificador de acesso dos atributos foi alterado para protected
; explicaremos isso a seguir.
In [1]:
class Emprestimo {
protected float s;
protected int n;
protected float j;
protected int corrente;
protected float p;
public Emprestimo(float s, int n, float j) {
this.s = s;
this.n = n;
this.j = j;
corrente = 1;
this.p = s;
}
public float proximaParcela() {
float retorno = p;
corrente++;
if (corrente <= n)
p = p + (p * (j/100));
else
p = 0;
return retorno;
}
}
// codigo principal
Emprestimo emprestimo1 = new Emprestimo(200, 5, 1),
emprestimo2 = new Emprestimo(500, 7, 2);
int i = 1;
float p1 = emprestimo1.proximaParcela();
float p2 = emprestimo2.proximaParcela();
while (p1 > 0 || p2 > 0) {
if (p1 > 0)
System.out.println("Emprestimo 1: parcela " + i + " eh " + p1);
if (p2 > 0)
System.out.println("Emprestimo 2: parcela " + i + " eh " + p2);
p1 = emprestimo1.proximaParcela();
p2 = emprestimo2.proximaParcela();
i++;
}
Suponha que você quer criar uma classe herdeira chamada EmprestimoPlus
. Essa classe acrescenta um método totalPagar
que é capaz de calcular o valor total que será pago no empréstimo.
Para criar a classe herdeira basta usar a cláusula extends
:
public class EmprestimoPlus extends Emprestimo
Como os atributos estavam private
, nem mesmo a classe herdeira pôde acessá-los. O modificador protected
permite que os herdeiros acessem os atributos (mas não objetos externos).
A classe herdeira herda os atributos e métodos da superclasse e pode usá-los como se fossem dela, sem a necessidade de alguma referência específica.
Há casos especiais que a classe herdeira e a superclasse têm métodos com o mesmo nome (estudaremos adiante) ou quando se trata do construtor, porque a classe herdeira pode ter dúvidas se uma chamada de método se refere a classe corrente ou superclasse. Portanto, somente para casos especiais, há um jeito de fazer referência explícita à superclasse usando super
.
Note que o construtor da classe EmprestimoPlus
chama o método super
. A cláusula super
faz referência à superclasse. Quando super
é acionado como método sozinho ele se refere ao construtor da superclasse. O método super
seguido do nome de um método, por exemplo, super.metodo()
aciona o método especificado da superclasse.
Só é necessário usar o super
quando há dúvida. A classe herdeira tem acesso a todos os métodos da superclasse sem a necessidade de dizer que o método é da superclasse.
In [2]:
public class EmprestimoPlus extends Emprestimo {
public EmprestimoPlus(float s, int n, float j) {
super(s, n, j);
}
public float totalPagar() {
float total = 0,
parcela = p;
for (int i = 1; i < n; i++) {
total += parcela;
parcela = parcela + (parcela * (j/100));
}
return total;
}
}
EmprestimoPlus emprestimo1 = new EmprestimoPlus(200, 5, 1),
emprestimo2 = new EmprestimoPlus(500, 7, 2);
System.out.println("Total a pagar Emprestimo 1: " + emprestimo1.totalPagar());
System.out.println("Total a pagar Emprestimo 2: " + emprestimo2.totalPagar());
In [ ]:
Crie duas classes herdeiras de GarotoZumbi
com as seguintes funcionalidades:
Monstro
- Consegue crescer mais que o GarotoZumbi
(até cinco anos de idade). Monstro
também pode estar dormindo ou acordado em qualquer uma das idades.o*o
*
o*o
*
o*o
*****
*
o*o
*****
#####
*
o*o
*****
#####
/ \
Perfeito
- Tem outra aparência e tem dois outros estados milionario
e doido
, que muda a aparência dos olhos (vide exemplo abaixo). Os dois novos estados devem se aplicar a todas as idades. Ele também acrescenta um método chamado mudaEstado()
que muda o estado (ciclicamente) entre normal
, milionario
e doido
. Cada vez que o Perfeito
muda de estado, o novo estado é automaticamente mostrado. O Perfeito
não tem os estados acordado e dormindo.+-----+
| o-o |
| ___ |
\___/
1 ano
+-----+
| |
| o-o |
| ___ |
\___/
2 anos
+-----+
| |
| o-o |
| ___ |
| |
\_____/
3 anos (limite)
+-----+
| |
| $-$ |
| ___ |
| |
\_____/
milionário
+-----+
| |
| @-@ |
| ~ |
| |
\_____/
doido
Dica importante para o Monstro
: quando você coloca a contrabarra (\
) dentro das aspas ela se comporta como escape, portanto, para representar uma contrabarra em vez de um escape são necessárias duas contrabarras (\\
).
In [3]:
public class GarotoZumbi
{
protected int idade;
protected String estado;
protected String nome;
public GarotoZumbi(int idade, String estado, String nome) {
this.idade = idade;
this.estado = estado;
this.nome = nome;
}
public void mostra() {
// cabeleira
if (idade >= 2)
System.out.println(" *");
// corpo com olhos
if (estado.equalsIgnoreCase("acordado"))
System.out.println(" o*o");
else
System.out.println(" -*-");
// barba
if (idade >= 3)
System.out.println("*****");
System.out.println(nome);
System.out.println();
}
public void cresce() {
if (idade < 3)
idade++;
mostra();
}
public void acorda() {
estado = "acordado";
mostra();
}
public void dorme() {
estado = "dormindo";
mostra();
}
}
GarotoZumbi garoto = new GarotoZumbi(1, "acordado", "Asdrubal");
garoto.mostra();
garoto.dorme();
garoto.cresce();