LP_Aula14 Herança 1. Definição Como o próprio nome sugere, na orientação a objetos o termo herança se refere a algo herdade. Em Java, a herança ocorre quando uma classe passa a herdar características (variáveis e métodos) definidas em outra classe, especificada como sua ancestral ou superclasse. A técnica da herança possibilita o compartilhamento ou reaproveitamento de recursos definidos anteriormente em outra classe. A classe fornecedora dos recursos recebe o nome de superclasse e a receptora dos recursos, de subclasse. Outro termo envolvido como herança é a especialização. Uma vez que uma classe herda características de outra, ela pode implementar partes especificas não contempladas na classe original (superclasse), tornando-se especializada em algum processo. A técnica da herança é extremamente utilizada em Java. Praticamente todas as aplicações com janelas, applets e servlets se beneficiam desse recurso. Para melhor o esclarecimento dos conceitos de herança e especialização, observe os exemplos seguintes. Vamos iniciar com a classe Pessoa do exemplo abaixo: public class Pessoa { private String nome; public void setNome(String nome) { this.nome = nome; } public String getNome() { return (nome); } } A classe Pessoa possui uma variável de instância “nome” e dois métodos setNome e getNome para manipular seu conteúdo. Essa classe pode ser especializada, uma vez que existem outros tipos de pessoa, como física e jurídica. Observe as classes seguintes de PessoaFisica e PessoaJuridica. Ambas estendem a funcionalidade da classe Pessoa, adicionando uma variável e dois métodos. Em Java, o mecanismo de herança é realizado pela inserção da palavra extends na declaração do nome da classe, seguido pela classe a partir da qual a herança será recebida. Linguagem de Programação Página 1 LP_Aula14 public class PessoaFisica extends Pessoa { private String rg; public void setRg(String rg) { this.rg = rg; } public String getRg() { return (rg); } public void mostraClasse() { System.out.println("classe PessoaFisica"); } } public class PessoaJuridica extends Pessoa { private String cnpj; public void setCnpj(String cnpj) { this.cnpj = cnpj; } public String getCnpj() { return (cnpj); } public void mostraClasse() { System.out.println("classe PessoaJuridica"); } } A classe PessoaFisica extende (por meio da palavra extends) a funcionalidade da classe Pessoa, herdando todo seu estado e comportamento e acrescentando novas funcionalidades: a variável “rg” e seus métodos de manipulação. Suponha que uma outra classe utilize PessoaFisica, declarando um objeto da seguinte forma: PessoaFisica pf = new PessoaFisica(); Ao criar o objeto “pf”, ele recebe todas as variáveis de instância e todos os métodos presentes nas classes Pessoa e PessoaFisica, ou seja, o objeto “pf” conterá as variáveis “nome”, “rg” e os métodos setNome, getNome, setRg e getRg. De forma similar, o mesmo ocorre com um objeto da classe PessoaJuridica. E importante salientar que se a classe Pessoa (superclasse do exemplo) for alterada, todas as mudanças são refletidas nas classes PessoaFisica e PessoaJuridica (as subclasses). Agora suponha que seja necessário estender também as funcionalidades da classe PessoaFisica. Vejamos no próximo exemplo: Linguagem de Programação Página 2 LP_Aula14 public class Funcionario extends PessoaFisica { private String cartao; public void setCartao(String cartao) { this.cartao = cartao; } public String getCartao() { return (cartao); } } A classe Funcionario estende a funcionalidade da classe PessoaFisica pelo mecanismo de herança, especializando ainda mais a classe original Pessoa. Por meio do mecanismo de herança, torna-se possível a criação de uma hierarquia de classe. Conforme a figura abaixo, o diagrama das classes criadas no exemplo de acordo com a notação UML. A hierarquia das classes criada pelo mecanismo de herança faz com que a subclasse Funcionario herde as funcionalidades da subclasse PessoaFisica que herda as funcionalidades da superclasse Pessoa. Da mesma forma, a subclasse PessoaJuridica herda as funcionalidades da superclasse Pessoa. Todas as subclasses foram criadas a partir da classe Pessoa. Imagem Qualquer alteração realizada numa classe de nível superior vai refletir nas classes de níveis inferiores. O mecanismo de herança possibilita que classes sejam criadas e adicionadas à hierarquia sem necessidade de alteração no código das classes, pois cada uma define exatamente suas funcionalidades. São como engrenagens que se encaixam umas nas outras. As classes adicionadas a uma hierarquia podem especializar ou restringir o comportamento das classes superiores. Para concretizar o exemplo de herança, o código abaixo apresenta a classe UsaFuncionario. Apesar de a classe Funcionario declara apenas a variável “cartao” e seus metodod set e get, todas as variáveis e métodos de suas classes ancestrais podem ser usados. public class UsaFuncionario { public static void main(String args[]) { Funcionario funcionario = new Funcionario(); funcionario.setNome("Lucas"); funcionario.setRg("25.654.678-x"); funcionario.setCartao("RH845"); System.out.println(funcionario.getNome()); System.out.println(funcionario.getRg()); System.out.println(funcionario.getCartao()); } } Linguagem de Programação Página 3 LP_Aula14 Outro ponto a ser considerado ser refere a restringir o uso da herança entre classes. Suponha que você queira definir que uma determinada classe não permita que outras classes se aproveitam de seu funcionamento, ou seja, você deseja proibir o uso da herança para essa classe. Isso é possível por meio do uso da palavra final. Veja como ficaria no caso da classe Pessoa: public final class Pessoa Se você alterar a classe pessoa para final, ocorre um erro em suas subclasses, já que Pessoa não poderá ser herdada por nenhuma classe. Conforme apresentado, a herança constitui uma importante técnica para a orientação a objetos (e para Java), possibilitando que o código já criado seja reaproveitado e especializando em outra. Como um exemplo mais pratico considere a seguinte situação: a linguagem Java fornece um componente gráfico por meio da classe JButton. Essa classe cria um botão padronizado, contendo dezenas de atributos e métodos associados. Um desenvolvedor pode reaproveitar todas as características já definidas em JButton e cria um botão personalizado (com uma cor de fundo padrão, tamanho etc.) chamado, por exemplo, MyButton. Com isso, em todos os sistemas, o desenvolvedor poderia usar seu botão personalizado, no caso o MyButton. Linguagem de Programação Página 4