Java – Heranças

Após o último artigo sobre classes que pode ser consultado aqui, o assunto deste irá focar-se no tema de herança de classes em Java. Tal como o conceito que todos sabemos, por exemplo, um dia vamos herdar tudo aquilo que os nossos pais têm. Não fugindo muito à regra, em Java acontece tal e qual a mesma situação. Para tal, vamos começar por criar um projecto novo com o nome “Heranca” mas antes, dar a resposta ao desafio lançado na semana passada.

Correção do desafio

Bastava na main, utilizar o código fornecido e usar as funções gets e sets. Esperamos que tenha acertado, caso contrário, terá outro desafio hoje para “vingar”!

public static void main(String[] args) {
        Jogador ronaldo = new Jogador("Ronaldo", 30, 85, 190, 20);
        Jogador messi = new Jogador("Messi", 29, 10, 100, 20);

        //Escrever o nome do primeiro jogador
        System.out.println("Nome: " + ronaldo.getNome());

        // Escrever o nome do segundo jogador
        System.out.println("Nome: " + messi.getNome());

        // Mudar o nome do Ronaldo para Quaresma
        ronaldo.setNome("Quaresma");

        // Mudar o nome do Messi para Maradona
        messi.setNome("Maradona");

        //Escrever o nome do primeiro jogador (Sera Quaresma)
        System.out.println("Nome: " + ronaldo.getNome());

        // Escrever o nome do segundo jogador (Sera Maradona)
        System.out.println("Nome: " + messi.getNome());
}

Herança

Tal como poderá ver na imagem seguinte, as classes “filhos” irão herdar as propriedades da classe “pai”. Quero com isto dizer que todos os atributos e funções que estiverem na classe “animal” serão herdados na classe “cão” e “gato”:

herança

O próximo passo será então aplicar o que observamos na imagem. Para isso, vamos proceder à criação de uma classe “Animal”. Se pensarmos na situação de um animal, todos os animais têm um nome, uma idade e, todos eles nascem (construtor) e morrem. Acontece que cães e gatos têm uma esperança média de vida diferentes, pelo que morrem em alturas diferentes.


Então repare que na classe animal, o método “morrer” é “abstract”, isto porque a função pertence a todos os animais mas, cada animal tem a sua forma de morrer pelo que o corpo da mesma só será programado dentro de cada um dos filhos:

public abstract class Animal {
    int idade;
    String nome;
    
    // Construtor e gets
    public Animal(int idade, String nome){
        this.idade = idade;
        this.nome = nome;
    }
    
    public int getIdade(){
        return idade;
    }
    
    public String getNome(){
        return nome;
    }
    //fim construtor e gets
    
    // função de movimento
    public abstract void morrer();        
}

Com a classe animal criada, vamos então proceder à criação da classe “Cão”

Com a classe cão criada, o leitor terá de acrescentar uma pequena linha de código que fará toda a diferença, adicionando apenas a linha “extends Animal”:

public class Cao extends Animal{
(...)

O que está a ser passado para código é que o cão é uma extensão da classe animal. Rapidamente vai perceber que o código já está a dar erros pelo que poderá utilizar todas as ferramentas do Netbeans para o ajudar. Com o rato, clique na lampada à esquerda e clique em “Implement all abstract methods”:

Cao

E repare que todos os métodos da classe Animal foram implementados. Neste caso, o morrer. Então vamos concluir esta classe da seguinte forma:

public class Cao extends Animal{
    boolean morto;

    public Cao(int idade, String nome) {
        // Passagem dos argumentos para o construtor Animal que é a classe super (pai)
        super(idade, nome);
       
        // atributo só da classe cão
        morto = false;
    }

    @Override
    public void morrer() {
        if(idade==2){
            System.out.println("O cao morreu 🙁 ");
            morto = true;
        }else{
            idade++;
            ladrar();
        }
    }
    
    // Funcao apenas da classe cao
    public void ladrar(){
        System.out.println("aoooooo");
    }
}

No código acima, repare no construtor. A chamada do “super” é importante pois recorde o leitor, a classe animal tem um construtor com atributos obrigatórios, pelo que aquele super está a passar os argumentos obrigatórios à classe construtor. Temos também uma variável que apenas pertence à classe cão (atributo morto) e ainda estamos a indicar que quando o cão atingir a idade de 2 anos, irá morrer. Sempre que um ano passa, o cão irá ladrar (esta função é uma função que pertence apenas ao cão pelo que é implementada na classe “cao”.

À semelhança do que se fez para a classe cão, implementar a classe gato. A diferença é que nesta, o gato morre quando tem 5 anos de idade:

public class Gato extends Animal{
    boolean morto;

    public Gato(int idade, String nome) {
        // Passagem dos argumentos para o construtor Animal que é a classe super (pai)
        super(idade, nome);
        
        // Atributo só da classe gato
        morto = false;
    }
    
    @Override
    public void morrer() {
        if(idade==5){
            System.out.println("O gato morreu 🙁 ");
            morto = true;
        }else{ 
            idade++;
            miar();
        }
    }
    
// Funcao apenas da classe gato
    public void miar(){
        System.out.println("Miauuu");
    }
}

Para testarmos o exemplo, nada melhor que na função main colocarmos o seguinte código e verificar que recebemos a mensagem de o cão a ladrar e o gato a miar. Logo de seguida, como a idade do cão irá atingir os 2 anos, este irá falecer:

public static void main(String[] args) {
        Cao cao = new Cao(1, "Bob");
        Gato gato = new Gato(3, "Tobias");
        
        // O cao não vai morrer mas a sua idade passa para 2 e vai ladrar
        cao.morrer();
        
        // O gato não vai morrer mas vai miar
        gato.morrer();
        
        // O cao vai morrer pois a sua idade é 2
        cao.morrer();      
    }

Desafio

Como de costume, iremos lançar um desafio ao leitor. Desafiamos que tente implementar agora, um novo animal. Um “Cachorro”.

A seguinte imagem poderá ajudar a compreender o objetivo:

desafio

O cachorro deverá ter a seguinte função:

public void asneira(){
        System.out.println("fiz asneiras");
    }

Mostre-nos que realmente percebeu o artigo ou deixe as suas dúvidas em comentário ou envie mail para erbi.silva@techemportugues.com

Fonte das imagens