Herança

Uma classe (subclasse) herda as características, variáveis, atributos e métodos, definidas em outra classe (superclasse), podendo escrevê-los (métodos e atributos) novamente para uma forma mais específica de representar o comportamento do método herdado.

Uma subclasse herda métodos e atributos de sua superclasse; apesar disso, pode escrevê-los novamente para uma forma mais específica de representar o comportamento do método herdado. - See more at: http://www.devmedia.com.br/entendendo-e-aplicando-heranca-em-java/24544#sthash.gR3Yomor.dpuf
métodos e atributos de sua superclasse; apesar disso, pode escrevê-los novamente para uma forma mais específica de representar o comportamento do método herdado. - See more at: http://www.devmedia.com.br/entendendo-e-aplicando-heranca-em-java/24544#sthash.gR3Yomor.dpuf
métodos e atributos de sua superclasse; apesar disso, pode escrevê-los novamente para uma forma mais específica de representar o comportamento do método herdado. - See more at: http://www.devmedia.com.br/entendendo-e-aplicando-heranca-em-java/24544#sthash.gR3Yomor.dpuf

Para que a subclasse herde as características da superclasse, usa-se a palavra reservada extends logo após a definicação do nome da subclasse:


class NomeSubClasse extends NomeSuperClasse

Somente é permitido herança simples, ou seja, uma subclasse só pode herdar diretamente de apenas uma superclasse, embora a superclasse pode ser subclasse de outra superclasse.

A omissão da palavra extendes significa que a classe java.lang.Object será assumida como superclasse da nova classe.

A palavra super representa uma chamada de método ou acesso a um atributo da superclasse, por isso tem esse nome. Para se referir a um atributo ou a um método da superclasse em um método de uma subclasse, basta utilizar a referência super seguida do operador ponto e do nome do atributo ou do nome do método. super.atributo ou super.metodo

super ( ), invoca o construtor da superclasse, sem parâmetros.

Classe Principal:

Exemplo 1:

Classe Pessoa:

package heranca2;

public class Pessoa { 
   String nome, 
   idade, 
   endereco= "Avenida dos Indios, nº 0101";  

   public void ImprimeNome(){ 
      System.out.println("o nome é:"); 
      System.out.println("Endereco: " + endereco);  
   }
}

Classe fornecedor:

package heranca2;
public class Fornecedor extends Pessoa { 
   String cnpj;  

   public void ImprimeNome (){ 
      System.out.println("O nome do fornecedor é : " + nome + "\n Cnpj: " + cnpj); 
   } 
}

Classe Cliente:

package heranca2;
public class Cliente extends Pessoa { 
   String cpf; 
    
   public void ImprimeNome (){ 
      System.out.println("Nome do cliente é : " + nome + "\n Nº CPF: " + cpf + "\n Seu endereco :" + endereco);       
   } 


Classe Principal:

package heranca2;
public class Principal { 
 
   public static void main(String[] args) { 
      Cliente c = new Cliente(); 
      c.nome="Carla Matias"; 
      c.cpf="922.234.678-12"; 
      c.ImprimeNome(); 
       
      Fornecedor f = new Fornecedor (); 
      f.nome="Contru&Casa"; 
      f.cnpj="456.678.0987.23-67"; 
      f.ImprimeNome();    
   } 
}


run:
Nome do cliente é : Carla Matias
 Nº CPF: 922.234.678-12
 Seu endereco :Avenida dos Indios, nº 0101
O nome do fornecedor é : Contru&Casa
 Cnpj: 456.678.0987.23-67   

Exemplo 2:

Classe Pessoa:

package heranca3;
interface Pessoa { 
        public String getNome(); 
        public void   setNome(String nome); 
    }

Classe Funcionario:

package heranca3;
abstract class Funcionario implements Pessoa {

    public abstract int getMatricula();
    public abstract void setMatricula(int matricula);

Classe Programador:

package heranca3;
class Programador extends Funcionario {

    private String nome;
    private int matricula;

    public Programador() {}; 
     
        public String getNome() {
        return this.nome;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
    public int getMatricula() {
        return this.matricula;
    }
    public void setMatricula(int matricula) {
        this.matricula = matricula;
    }
    public String programar() {
        return "programando";
    }
}

Classe Coordenador:
package heranca3;

class Coordenador extends Funcionario {

    private String nome;
    private int matricula;

    public Coordenador() {} ; 
     
        public String getNome() {
        return this.nome;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
    public int getMatricula() {
        return this.matricula;
    }
    public void setMatricula(int matricula) {
        this.matricula = matricula;
    }

    public String mandar() {
        return "Mandando";
    }
}

Classe Principal:

package heranca3;
public class Principal { 
        public static void main(String[] args) { 
            Coordenador coor = new Coordenador(); 
            Programador prog = new Programador(); 
     
            Funcionario fprg = new Programador(); 
            Funcionario fcrd = new Coordenador(); 
     
            Funcionario temp; 
     
            prog.setMatricula(212); 
            prog.setNome("Mariana Soares"); 
     
            coor.setMatricula(213); 
            coor.setNome("Flavia Penteado"); 
     
            System.out.println(prog.getMatricula()+" - "+ prog.getNome()); 
            System.out.println(coor.getMatricula()+" - "+ coor.getNome()); 
     
            fprg.setMatricula(214); 
            fprg.setNome("Marina Souza"); 
     
            fcrd.setMatricula(215); 
            fcrd.setNome("Gabriela Fernanda"); 
     
            System.out.println(fprg.getMatricula()+" - "+ fprg.getNome()); 
            System.out.println(fcrd.getMatricula() +" - " + fcrd.getNome()); 
     
            temp = fprg; 
            fprg = fcrd; 
            fcrd = temp; 
     
            System.out.println(fprg.getMatricula()+" - "+ fprg.getNome()); 
            System.out.println(fcrd.getMatricula()+" - "+fcrd.getNome()); 
        } 
    }

run:
212 - Mariana Soares
213 - Flavia Penteado
214 - Marina Souza
215 - Gabriela Fernanda
215 - Gabriela Fernanda
214 - Marina Souza 

A palavra reservada this dentro do método cuja nome do atributo é igual ao nome do parâmetro e do atributo da classe possibilita fazer referência ao atributo de um objeto desta classe, considerando que nome é um atributo da classe e parâmetro de seu método, o atributo do método será this.nome, ou seja, a palavra this cria uma cópia do atributo da classe para que um objeto possa referênciá-la, podendo alterar o seu valor apenas para o objeto, isto garante que essa classe terá objetos com características semelhantes, pois, esta é a finalidade da classe, representar objetos com caracteristicas comuns.

A referência this é um valor especial através do qual é possível referir-se ao objeto atual de uma classe dentro de qualquer método da mesma. É através dessa referência que é possível identificar o objeto específico que invocou determinado método.

Exemplo 3:

Classe A:

package heranca5;

public class A  {
    protected int x, y;
    private int z;

    public A(int a, int b, int c) {
        x = a;
        y = b;
        z = c;
    }


    public int obterX() {
        return (x);
    }

    public int obterY() {
        return (y);
    }

    public int obterZ() {
        return (z);
    }

    public void alterarX(int a) {
        x = a;
    }

    public void alterarY(int a) {
        y = a;
    }

    public void alterarZ(int a) {
        z = a;
    }

    public void ImprimeValores() {
        System.out.println("O valor de X é: " + x);
        System.out.println("O valor de Y é: " + y);
        System.out.println("O valor de Z é: " + z);
    }
}


Classe B:

package heranca5;

public class B extends A {

    private int k;

    public B(int a, int b, int c, int d) {
        super(a, b, c);
        k = d;
    }

    public void ImprimeValores() {
        System.out.println("O valor de X é: " + x);
        System.out.println("O valor de Y é: " + y);
        System.out.println("O valor de K é: " + k);
        System.out.println("Z não é visível nesta classe.");
        System.out.println("O valor de Z da superclasse é: "
                + obterZ());
    }
}

Classe Main:

package heranca5;

public class Main {

    public static void main(String[] args) {
        B obj1 = new B(10, 20, 30, 40);
        obj1.ImprimeValores();
        obj1.alterarY(100);
        obj1.ImprimeValores();
    }
}

run:
O valor de X é: 10
O valor de Y é: 20
O valor de K é: 40
Z não é visível nesta classe.
O valor de Z da superclasse é: 30
O valor de X é: 10
O valor de Y é: 100
O valor de K é: 40
Z não é visível nesta classe.
O valor de Z da superclasse é: 30


Exemplo 4:

Classe Principal:

package heranca6;

public class Principal {
    public static void main(String[] args)
    {
        SuperClasse e1 = new SuperClasse(1,2,3,4);
        SubClasse e2 = new SubClasse(6,7,8,9,10);
        SuperClasse e3 = new SubClasse(11,12,13,14,15); // Funciona pois toda sub-classe "também é" classe
        // SubClasse e4 = new SuperClasse(21,21,22,23); // Nao funciona pois uma super-classe não é classe
        e1.imprime();
        e2.imprime();
        e3.imprime();
        ((SuperClasse)e3).imprime();
        // e3.novoImprime(); // Nao funciona pois, mesmo e3 contendo um objeto do tipo SubClasse, a variável é do tipo SuperClasse
        ((SubClasse)e3).novoImprime(); // o 'cast' permite a execucao do metodo novoImprime, note que o programador precisa ter certeza que o conteudo de e3 é compatível com SubClasse
        // ((SubClasse)e1).novoImprime(); // Nao funciona pois o objeto que está em e1 não é compatível com o tipo SubClasse [porém não dará erro de compilação e sim de execução]
        
        
        /* Note que:
         * 1. e3 eh uma variavel do tipo SuperClasse e recebe um objeto do
         *    tipo SubClasse;
         * 2. a classe SubClasse nao tem acesso (visibilidade) ao atributo
         *    da super-classe, porem este atributo existe e eh impresso.
         * 3. o cast da penultima linha significa "leia e3 como sendo do tipo SubClasse, garantindo
         *    assim acesso ao metodo 'novoImprime()' da sub-classe Exemplo1Sub.
         *    Isto funciona pois a instancia e3 contem um objeto do tipo SubClasse
         */
    }
}

Classe SubClasse:

package heranca6;

class SubClasse extends SuperClasse{
    int e;
    
    public SubClasse(int w, int x, int y, int z, int e) {
        super(w, x, y, z);
        this.e = e;
    }
    int getE(){
        return e;
    }

    void acessaCampos() {
        System.out.println("Metodo acessaCampos da sub-classe Exemplo1Sub.");
        System.out.println("A = " + getA());
        System.out.println("B = " + getB());
        System.out.println("C = " + getC());
        // System.out.println("D = " + getD()); // NAO FUNCIONA pois getD() eh private
        System.out.println("E = " + getE());
    }
    
    void imprime(){
        System.out.println("Metodo imprime da sub-classe Exemplo1Sub.");
        super.imprime();
        System.out.println("E = " + getE());
    }

    void novoImprime(){
        System.out.println("Metodo novoImprime da sub-classe Exemplo1Sub.");
    }
}

Classe SuperClasse:

package heranca6;

class SuperClasse {
    public int a;
    protected int b;
    int c;
    private int d;

    SuperClasse(int w, int x, int y, int z) {
        a = w;
        b = x;
        c = y;
        d = z;  
    }
    
    void imprime() {
        System.out.println("Metodo imprime da super-class Exemplo1Super.");
        System.out.println("A = " + a);
        System.out.println("B = " + b);
        System.out.println("C = " + c);
        System.out.println("D = " + d);
    }
    public int getA() {
        return a;
    }
    protected int getB() {
        return b;
    }
    int getC() {
        return c;
    }
    private int getD() {
        return d;
    } 
}


Exemplo 5:

Para que não escrevamos o mesmo código duas ou mais vezes em classes diferentes, podemos criar uma só superclasse chamada Pessoa para representar todos as outras classes, que apresentam comportamentos comuns a classe pai. Este processo tem o nome de Generalização.

Classe Pessoa:

import java.util.Date;
public class Pessoa {
    public String nome;
    public String cpf;
    public Date data_nascimento;
    
    public Pessoa(String _nome, String _cpf, Date _data) {
        this.nome = _nome;
        this.cpf = _cpf;
        this.data_nascimento = _data;
    }
}


Percebe-se que a classe Pessoa possui nome, CPF, e data de nascimento como atributos; além de um construtor, que recebe estes três dados como parâmetro, e assim preenche os atributos do objeto. Na criação de um objeto Pessoa, o programa deve fornecer seus dados.

Porque o uso de this? Porque as variáveis de instâncias da classe Pessoa podem ser acessadas várias vezes através do seu construtor, com isso, as mesmas não recebe diretamente um valor.

Classe Aluno:

package heranca9;
import java.util.Date;

public class Aluno extends Pessoa {

    public Aluno(String _nome, String _cpf, Date _data) {
        super(_nome, _cpf, _data);
    }
    public String matricula;
}

Classe Pessoa:

package heranca9;
import java.util.Date;
public class Pessoa {
    public String nome;
    public String cpf;
    public Date data_nascimento;
   
    public Pessoa(String _nome, String _cpf, Date _data) {
        this.nome = _nome;
        this.cpf = _cpf;
        this.data_nascimento = _data;
    }
}

Classe Professor:

package heranca9;
import java.util.Date;

public class Professor extends Pessoa {

    public Professor(String _nome, String _cpf, Date _data) {
        super(_nome, _cpf, _data);
    }
    public double salario;
    public String disciplina;
}

Classe Funcionario:

package heranca9;
import java.util.Date;

public class Funcionario extends Pessoa {

    public Funcionario(String _nome, String _cpf, Date _data) {
        super(_nome, _cpf, _data);
    }
    public double salario;
    public Date data_admissao;
    public String cargo;
}

As novas classes criadas possuem suas características (atributos e métodos) próprias, mas possuem também propriedades comuns: os atributos nome, data de nascimento e CPF. Podemos ver que cada construtor das novas classes possui uma chamada super(_nome, _cpf, _data).

A palavra super representa uma chamada de método ou acesso a um atributo da superclasse, por isso tem esse nome. No caso em questão, foi  usando o super para invocar o construtor da superclasse Pessoa, que recebe os três parâmetros e preenche os atributos do objeto. Então, quando é criado um objeto do tipo Aluno, por exemplo, utilizando “new Aluno(“nome”,”cpf”,new Date())”, a classe Aluno invocará o construtor Pessoa(String,String,Date), e então seus atributos serão preenchidos com os dados enviados por parâmetro.

Classe Principal:

package heranca9;
import java.util.Date;

public class Principal {
    public static void main(String[] args) {
        Aluno i = new Aluno("Jose Francisco", "123.456.789-00", new Date());
        System.out.println("Veja como os atributos foram preenchidos\n\nNome: " + i.nome);
        System.out.println("CPF: " + i.cpf);
        System.out.println("Data de nascimento: " + i.data_nascimento.toString());
    }
}


run:
Veja como os atributos foram preenchidos

Nome: Jose Francisco
CPF: 123.456.789-00
Data de nascimento: Wed Feb 27 21:14:36 BRT 2013

Deve-se saber que todos os métodos e atributos públicos e protegidos da superclasse serão herdados, caso utilize-se o extends Classe na definição de uma nova classe derivada. Portanto, os métodos e atributos privados (private) não serão herdados, e não se tem acesso a eles nem com a utilização da palavra especial super.

Apesar da classe derivada herdar os comportamentos públicos da classe base, nada (ou quase nada) impede que se  implementem de novo os métodos e atributos que se quiser na subclasse. Podee-se sobrescrever métodos das superclasses, criando assim um novo comportamento para funções específicas.

Exemplo 6:

Classe Mamifero:

public class Mamifero {
 
    //Atributos genéricos, ou seja, que são comuns em todos os mamíferos
    private String peso;
    private String altura;
 
    // Métodos get e set para acesso aos atributos
    public String getAltura() {
        return altura;
    }
    public void setAltura(String altura) {
        this.altura = altura;
    }
    public String getPeso() {
        return peso;
    }
    public void setPeso(String peso) {
        this.peso = peso;
    }
}

Classe Cachorro:

public class Cachorro extends Mamifero{
 
    //Atributo especifico do cachorro
    private String corPelo;
 
    //Métodos get e set de acesso ao atributo
    public String getCorPelo() {
        return corPelo;
    }
 
    public void setCorPelo(String corPelo) {
        this.corPelo = corPelo;
    }
}

Classe Homem:

public class Homem extends Mamifero{
 
    // Atrinuto especifico da classe Homem
    private String corCabelo;
 
    // Métodos get e set de acesso ao atributo
    public String getCorCabelo() {
        return corCabelo;
    }
 
    public void setCorCabelo(String corCabelo) {
        this.corCabelo = corCabelo;
    }
}

Classe Principal:

package heranca10;

public class Principal {
    public static void main(String[] args) {
 
        // instanciamos um objeto do tipo Cachorro
        Cachorro cachorro = new Cachorro();
 
        // acessando os métodos da superclasse Mamífero
        cachorro.setAltura("30 cm");
        cachorro.setPeso("10 kg");
        System.out.println("Cachorro: " + cachorro.getAltura()+" "+ cachorro.getPeso() );
 
        // Acessando o método especifico da classe Cachorro
        cachorro.setCorPelo("Marrom");
 
        // instanciamos um objeto do tipo Homem
        Homem homem = new Homem();
 
        // acessando os métodos da superclasse Mamífero
        homem.setAltura("1,70 m");
        homem.setPeso("85 kg");
 
        // Acessando o método especifico da classe Homem
        homem.setCorCabelo("Preto");
         System.out.println("Homem: " + homem.getAltura()+" "+ homem.getPeso() );
    }
   
}

run:
Cachorro: 30 cm 10 kg
Homem: 1,70 m 85 kg

exemplo de uma modelagem de uma escola, representando alunos, e professores e funcionários; pois é provável que tenhamos algumas características comuns entre eles. Logo, para que não escrevamos o mesmo código duas ou mais vezes em classes diferentes, podemos criar uma só superclasse chamada Pessoa para representar todos os atores do nosso universo acadêmico, inserindo nela os comportamentos comuns aos três tipos de “pessoas”. Este processo tem o nome de Generalização. - See more at: http://www.devmedia.com.br/entendendo-e-aplicando-heranca-em-java/24544#sthash.gR3Yomor.dpuf
exemplo de uma modelagem de uma escola, representando alunos, e professores e funcionários; pois é provável que tenhamos algumas características comuns entre eles. Logo, para que não escrevamos o mesmo código duas ou mais vezes em classes diferentes, podemos criar uma só superclasse chamada Pessoa para representar todos os atores do nosso universo acadêmico, inserindo nela os comportamentos comuns aos três tipos de “pessoas”. Este processo tem o nome de Generalização. - See more at: http://www.devmedia.com.br/entendendo-e-aplicando-heranca-em-java/24544#sthash.gR3Yomor.dpuf
para que não escrevamos o mesmo código duas ou mais vezes em classes diferentes, podemos criar uma só superclasse chamada Pessoa para representar todos os atores do nosso universo acadêmico, inserindo nela os comportamentos comuns aos três tipos de “pessoas”. Este processo tem o nome de Generalização. - See more at: http://www.devmedia.com.br/entendendo-e-aplicando-heranca-em-java/24544#sthash.gR3Yomor.dpuf

Para este artigo, utilizaremos o exemplo de uma modelagem de uma escola, representando alunos, e professores e funcionários; pois é provável que tenhamos algumas características comuns entre eles. Logo, para que não escrevamos o mesmo código duas ou mais vezes em classes diferentes, podemos criar uma só superclasse chamada Pessoa para representar todos os atores do nosso universo acadêmico, inserindo nela os comportamentos comuns aos três tipos de “pessoas”. Este processo tem o nome de Generalização.

Vejamos uma possível modelagem da classe Pessoa.

- See more at: http://www.devmedia.com.br/entendendo-e-aplicando-heranca-em-java/24544#sthash.gR3Yomor.dpuf
Para este artigo, utilizaremos o exemplo de uma modelagem de uma escola, representando alunos, e professores e funcionários; pois é provável que tenhamos algumas características comuns entre eles. Logo, para que não escrevamos o mesmo código duas ou mais vezes em classes diferentes, podemos criar uma só superclasse chamada Pessoa para representar todos os atores do nosso universo acadêmico, inserindo nela os comportamentos comuns aos três tipos de “pessoas”. Este processo tem o nome de Generalização. - See more at: http://www.devmedia.com.br/entendendo-e-aplicando-heranca-em-java/24544#sthash.gR3Yomor.dpufClasse Principal: