Capítulo 9 Herança 1
Herança Herança Classe derivada Membros protected Sobrescrição Cláusula super Herança de construtores Métodos final Classes final Classes abstratas A classe Object O método toString() 2
Herança Conta numero nome saldo getNumero() setNumero() getNome() setNome() getSaldo() depositar() retirar() ContaPoupanca capitalizar() bloquearSaldo() ContaCorrente debitarTarifa()
Herança - Classe derivada public class ContaPoupanca extends Conta { /** * Adiciona a rentabilidade da poupança. * Deve ser executado uma vez por mês. */ public void capitalizar(double taxaJuros) { double rentabilidade = getSaldo() * taxaJuros; depositar(rentabilidade); } 4
(declarado em ContaPoupanca) Herança Na aplicação principal: ContaPoupanca c2 = new ContaPoupanca(); c2.setNumero(8505); c2.setNome("Maria"); c2.depositar(1000.0); c2.retirar(200.0); c2.capitalizar(0.018); System.out.print("Saldo atual: "); System.out.print(c2.getSaldo()); Membros herdados (declarados em Conta) Membro próprio (declarado em ContaPoupanca)
Membros protected Na classe base (mãe): public class Conta { private int numero; private String nome; private double saldo; . . . . . . . . . . . . } Na classe derivada (filha): public class ContaPoupanca extends Conta { public void capitalizar(double taxaJuros) { saldo += (saldo * taxaJuros); } Atributo saldo inacessível Declarado na classe Conta como private. Visível apenas na classe Conta
Membros protected Na classe base (mãe): public class Conta { private int numero; private String nome; protected double saldo; . . . . . . . . . . . . } Na classe derivada (filha): public class ContaPoupanca extends Conta { public void capitalizar(double taxaJuros) { saldo += (saldo * taxaJuros); } Atributo saldo (protected) Declarado na classe Conta Visível na classe ContaPoupanca Invisível em outras classes
Exercício A partir da classe Funcionario fornecida pelo instrutor e especificada no diagrama abaixo, crie uma classe derivada (filha) denominada Motorista acrescentando os atributos: placaAutomovel : String cnh : String e seus devidos métodos get’s e set’s. Crie uma outra classe chamada ExibeDados contendo o método main que deverá instanciar a classe Motorista, preencher todos os seus atributos e exibí-los conforme o próximo slide. Funcionario getMatricula() setMatricula(long) getNome() setNome(String) getSalario() setSalario(double)
Exercício (cont.) A classe ExibeDados deverá exibir: Matricula: 123 Nome : Manuel da silva Salario : 2000.0 CNH : 6578985 Placa : ABC-1234
Sobrescrição (overwriting) Conta ... ... ... ... retirar() ContaPoupanca ... ... ContaCorrente ... retirar()
Sobrescrição Ocorre quando a classe filha reimplementa um método já existente na classe mãe. Para sobrescrever um método, deve-se criar na classe filha um método com... mesmo nome; mesmos parâmetros de entrada; mesmo tipo de retorno ...daquele existente na classe mãe.
Sobrescrição public class ContaCorrente extends Conta { .... /** Retirada agora cobra CPMF */ public void retirar(double valor) { saldo -= valor; saldo -= 0.0025 * valor; } 12
Desta vez ocorre a cobrança de CPMF sobre o valor a ser retirado. Sobrescrição Na aplicação principal: ContaCorrente c3 = new ContaCorrente(); c3.setNumero(8505); c3.setNome("Maria"); c3.depositar(1000.0); c3.retirar(2000.0); System.out.print("Saldo atual: "); System.out.print(c3.getSaldo()); Desta vez ocorre a cobrança de CPMF sobre o valor a ser retirado.
Cláusula super Utilizada para referenciar os atributos e métodos implementados na classe base (classe mãe) public class ContaCorrente extends Conta { .... public void retirar(double valor) { super.retirar(valor); saldo -= 0.0025 * valor; } Executa o método retirar() da mesma forma que foi implementado na classe Conta
Herança de construtores Ao instanciar um objeto, os métodos construtores de seus ancestrais são executados em cascata a fim de construir uma instância consistente da classe solicitada. new ContaConjunta(215.5); Conta Conta(String) Conta(double) Conta(int) ContaCorrente ContaCorrente(String) ContaCorrente(int, double) ContaConjunta ContaConjunta(int) ContaConjunta(double) 1 2 3
Herança de construtores Se uma classe base possuir métodos construtores, a classe derivada deverá possuir um ou mais métodos construtores, e estes deverão, através da cláusula super, escolher qual dos construtores da classe base será chamado. Esta cláusula super deverá ser a primeira instrução presente no método construtor da classe derivada.
Herança de construtores public class ContaCorrente extends Conta { . . . . . . public ContaCorrente(int num, double valor) { super(valor); . . . . . . } public ContaCorrente(String nome) { super(nome); . . . . . . } Inicializa a classe base através do construtor que possui um double Realiza outras instruções de inicialização inerentes à classe ContaCorrente
Métodos final A cláusula final é utilizada para bloquear a sobrescrição de métodos pelas classes filhas. public class Conta { . . . . . . public final void depositar(double valor) { } Ao criar uma classe derivada da classe acima, não podemos sobrescrever o método depositar pois foi definido como final.
Classes final A cláusula final também pode ser utilizada na declaração de classes. public final class Conta { . . . . . . } Neste caso, estamos declarando uma classe Conta como sendo uma classe que não permite a criação de classes derivadas.
Classe Abstrata public abstract class Conta { public int numero; public String nome; double saldo; public abstract void depositar (double v); public abstract void retirar (double v); public double getSaldo () { return saldo; } } 20
Classe Abstrata Na aplicação principal: Conta c1 = new Conta(); // Não funciona 21
Classe Abstrata public class ContaCorrente extends Conta { /* Implementação Obrigatória */ public void depositar (double v) { saldo += v; } /* Implementação Obrigatória */ public void retirar (double v) { if (saldo >= v) saldo -= v * 1.0025; else System.out.println("Saldo insuficiente"); } } 22
Classe Abstrata Na aplicação principal: ContaCorrente c = new ContaCorrente(); c.depositar(100.0); c.retirar(50.0); System.out.println(“Saldo atual: ” + c.getSaldo()); 23
A classe Object O princípio de herança é aplicada a toda e qualquer classe que possamos elaborar no Java. A própria linguagem Java possui centenas de classes utilitárias já prontas para uso, possuindo os mesmo princípios de orientação a objeto mostrados até agora. Uma destas classes é chamada Object. Ela foi criada para servir como base de herança para toda e qualquer outra classe desenvolvida no Java.
A classe Object public class Conta . . . . . . . . . . . . } extends Object {
A classe Object clone() equals(Object) finalize() getClass() hashCode() notify() notifyAll() toString() wait() wait(long) wait(long, int)
O método toString() Retorna uma representação literal da entidade representada pela classe. Pode ser sobrescrita por sua classe para retornar algum nome ou frase que represente o objeto instanciado a partir daquela classe.
O método toString() public class ClienteVO { private long numero; private double saldo; private String nome; . . . . . . public String toString() { return numero + “-” + nome; }
O método toString() Na aplicação principal: Será exibido: Conta c = new Conta(1005, “João Silva”, 1500); . . . . .; System.out.println(c); Será exibido: 1005 – João Silva
System.out.println(mot); Exercício Altere a classe Motorista criada no último exercício e sobrescreva o método toString() para que este retorne um único String contendo os dados do motorista no formato exigido. Altere a classe ExibeDados modificando a chamada para exibição de dados do motorista utilizando a instrução abaixo: System.out.println(mot); Crie também uma instância da classe Funcionario e exiba seus dados da mesma forma utilizada para a classe Motorista (seu método toString() já foi implementado). 30