Programação I Aula 6 (Herança, Polimorfismo e Encapsulamento) Prof. Gilberto Irajá Müller Última atualização 8/4/2009 Herança • A herança permite derivar uma nova classe mais especializada a partir de outra classe mais genérica existente • A classe mais genérica é chamada de superclasse • A classe derivada é chamada de subclasse • Herda os atributos (desde que não sejam privates) • Permite adicionar novos atributos (que será visível somente na subclasse) • Em relação aos métodos, a subclasse poderá utilizá-los/herdálos (superclasse), bem como criar novos métodos e alterá-los • Métodos construtores não são herdados (porém podemos chamá-los dentro do construtor da subclasse) Herança • A representação de Herança (generalização/especialização) utilizando a notação da UML é: Classe A Superclasse ou classe-pai Classe B Subclasse ou classe filha • Lembre-se: Cada objeto da classe B também é um objeto da classe A, podendo ter alguns membros diferentes da classe origem Herança • Exemplo O que temos de diferente na subclasse Gerente? Herança • Exemplo anterior em JAVA Extends Funcionario? Super? Herança • Sintaxe de herança em JAVA modificadores class nomeSubClasse extends nomeSuperClasse { atributos; métodos; } Herança • A classe Object Quando criamos uma classe qualquer em JAVA, na verdade, estamos herdando implicitamente da classe Object Exemplo: public class Pessoa { ... } Na verdade, o JAVA traduz como: public class Pessoa extends Object { ... } Estamos herdando de forma indireta nossas classes! Herança • A classe Object A classe em questão, possui alguns métodos que todas as demais classes irão herdar, como por exemplo: String toString() boolean equals(Object outroObjeto) int hashCode() ... Contudo, para utilizá-los, é recomendável que seja sobrescrito, ou seja, OVERRIDING! Herança • Exercício 6.1 Lembram da classe Pessoa? Pois bem, faça o diagrama de classes utilizando herança para a classe PessoaJuridica com um novo atributo chamado CNPJ (string) e um método exibeDados() considerando o atributo CNPJ Como ficaria a classe PessoaJuridica em JAVA? Herança • Membros da subclasse (métodos) • Sobrescrever um método. Para sobrescrever um método na subclasse é necessário que o tipo de retorno, o nome e os parâmetros e seus tipos sejam exatamente iguais. Exemplo: PessoaJuridica.exibeDados(); • Herdar (utilizar) um método da superclasse. Todo método que não é sobrescrito na subclasse, ao ser chamado, será utilizado o método da superclasse. Exemplo: PessoaJuridica.getNome(); • Métodos criados apenas na subclasse, somente poderão ser utilizados na subclasse. Exemplo: funcionario.setNomeiaSecretario(“Pituca”); Herança • Membros da subclasse (atributos) • Atributos não podem ser sobrescritos, ou seja, não é permitido a alteração de um nome de método da superclasse a partir da subclasse! • Herdar (utilizar) os atributos da superclasse. Porém, não se pode fazer o acesso direto ao atributo, apenas utilizando o seu método de acesso (get ou set). Isso quando o atributo da superclasse é “private”. Exemplo: nome, salario e numeroDeDependentes • Pode-se criar novos atributos. Lembre-se: somente a subclasse poderá acessar o atributo diretamente, ou seja, sem utilização dos métodos de acesso. Usso quando o atributo é declarado como “private”. Exemplo: nomeSecretaria Herança • Chamada de métodos da subclasse • Quando um objeto chama um determinado método, temos as seguintes situações: • Se é um método da subclasse que sobrescreve um método da superclasse, o da subclasse é acionado (ele esconde o da superclasse) • Se o método chamado só existe na superclasse, ele será acionado (a subclasse herda métodos da superclasse que ela não sobrescreve) • Se o método é exclusivo da subclasse, ele será acionado • Se o método chamado não existe na subclasse, nem na superclasse, nem na superclasse da superclasse, e em nenhuma superclasse hierarquia acima, então acontece um erro. Herança • Exercício 6.2 Filha f1 = new Filha(); f1.m1(); ___________________ f1.m2(); ___________________ f1.m3(); ___________________ f1.m4(); ___________________ Herança • Construtores da subclasse • Os construtores da superclasse não são herdados pela subclasse, portanto, esta deverá ter seus próprios construtores • Contudo, ao criar um construtor de uma subclasse, precisaremos inicializar os atributos herdados pela superclasse, então, utilizamos a chamada (palavra reservada) super(...) Exemplo: • Obs.: Se o construtor da subclasse não chama um construtor da superclasse, então, o construtor padrão da superclasse é chamado automaticamente. Se a superclasse não tem um construtor padrão, dá erro de compilação. Herança • Exercício 6.3 Qual o efeito do seguinte construtor na subclasse Gerente quando um objeto é instanciado? public Gerente(String nomeSecretaria) { this.nomeSecretaria = nomeSecretaria; } Herança • Exercício 6.4 Escreva um outro construtor para a subclasse Gerente que inicialize todos os seus atributos (inclusive o nome da sua secretária) Herança • Visibilidade • Uma subclasse não possui acesso aos atributos privados da superclasse, ou seja, o único acesso ao atributo se dá através dos métodos de acesso (get e set) • O atributo definido como private é acessível somente pela classe que o declarou • O exemplo a seguir da subclasse gerente ocorrerá erro porque e aonde? public void exibeDados(){ System.out.println(“Nome: “ + nome); System.out.println(“Salário: “ + salario); System.out.println(“Dependentes: “ + numeroDeDependentes); System.out.println("Secretária: " + nomeSecretaria); } Herança • Visibilidade • A alternativa seria: public void exibeDados(){ super.exibeDados(); System.out.println ("Secretária: " + nomeSecretaria); } • Ou: Declarar os atributos na superclasse (nome, salário e numeroDeDependentes) com a visibilidade protected A visibilidade protected (#), permite acessar diretamente um atributo na subclasse, ou seja, não há necessidade de acesso via método! Herança • Uso da palavra-chave super • É usada, quando necessária, na subclasse, para chamar construtor ou método da superclasse • Para chamar um método construtor: • A palavra super seguida imediatamente de parênteses chama o construtor da superclasse de mesma assinatura • Neste caso, deve ser a primeira instrução dentro de um construtor da subclasse • Para chamar um método NÃO construtor: • A palavra super seguida de ponto e nome de um método da superclasse, chama o método correspondente da superclasse • Este tipo de chamada pode aparecer em qualquer lugar de qualquer método ou construtor da subclasse Herança • Uso da palavra-chave super • Exemplo chamando um método construtor • Exemplo chamando um método NÃO construtor Herança • Exercício 6.5 O que é sobrecarga (OVERLOADING)? O que é sobrescrita (OVERRIDING)? Herança • Exercício 6.6 Indique o que cada método e construtor são: (i) sobrecarga ou (ii) sobrescrita Polimorfismo • É a realização de uma tarefa de formas diferentes (poli – muitas; morphos – formas). Uma utilização importante do polimorfismo em Java ocorre na herança, quando dois objetos, sendo um da superclasse e outro da subclasse, respondem diferentemente à mesma chamada de um método • Primeiramente, vamos entender a conversão de um tipo de objeto para outro (upcasting) Polimorfismo • Exemplo: Pai p; • Declara p como uma referência da superclasse Pai – isto define a vocação de p: referenciar qualquer objeto do tipo Pai. • Em Java, podemos atribuir um objeto da subclasse a uma referência de sua superclasse. (Esta operação é chamada upcasting, de up type casting) • A regra anterior é razoável, pois todo objeto da subclasse É UM objeto da sua superclasse. Então, podemos atribuir a p um objeto Filha: p = new Filha(); Polimorfismo • Exemplo: Observe, a seguir, p acionando métodos: • p.m1(); ________________________ • p.m2(); ________________________ • p.m3(); ________________________ Uma referência de superclasse só reconhece membros disponíveis na superclasse, mesmo que esteja apontando para um objeto de subclasse. Polimorfismo • Resumindo, o upcasting é a conversão de um objeto de tipo mais específico para um tipo mais genérico, feita implicitamente através de atribuição, mas a partir da conversão só os membros do tipo mais genérico podem ser acessados sem artifícios. Polimorfismo • Para o nosso exemplo: como acessar o método m3? A resposta está no downcasting (down type casting) • Em Java, a atribuição de um objeto de superclasse a uma referência de subclasse, sem uma coerção explícita, não é permitida. Exemplo: Filha f = p; • O downcasting é realizado utilizando o operador de casting de classes. Exemplo: Filha f = (Filha) p; f.m3(); Polimorfismo • Esta realidade, citada na frase anterior, é algo verificado por Java apenas em tempo de execução. Se o objeto for do tipo da subclasse, a coerção será válida, mas se não for, ocorrerá uma ClassCastException • Para proteger nosso código dessa incerteza, convém usar o operador especial instanceof com a seguinte sintaxe: VariávelObjeto instanceof NomeClasse Exemplo: if (p instanceof Filha){ Filha f = (Filha) p; f.m3(); } Polimorfismo • Exemplo de conversão e seus erros: Polimorfismo • Exemplo de Polimorfismo Polimorfismo • Exemplo de Polimorfismo HOT TOPIC • • • • Classe: representa um conjunto de objetos com características afins. Uma classe define o comportamento dos objetos, através de métodos, e quais estados ele é capaz de manter, através de atributos. Exemplo de classe: Os seres humanos. Objeto é uma instância de uma classe. Um objeto é capaz de armazenar estados através de seus atributos e reagir a mensagens enviadas a ele, assim como se relacionar e enviar mensagens a outros objetos. Exemplo de objetos da classe Humanos: João, José, Maria. Atributos são características de um objeto. Basicamente a estrutura de dados que vai representar a classe. Exemplos: Funcionário: nome, endereço,telefone, CPF, ....; Carro: nome, marca, ano, cor, ...; Livro: autor, editora, ano. Por sua vez, os atributos possuem valores. Por exemplo, o atributo cor pode conter o valor azul. O conjunto de valores dos atributos de um determinado objeto é chamado de estado. Métodos definem as habilidades dos objetos. Bidu é uma instância da classe Cachorro, portanto tem habilidade para latir, implementada através do método deUmLatido(). Um método em uma classe é apenas uma definição. A ação só ocorre quando o método é invocado através do objeto, no caso Bidu. Dentro do programa, a utilização de um método deve afetar apenas um objeto em particular; Todos os cachorros podem latir, mas você quer que apenas Bidu dê o latido. Normalmente, uma classe possui diversos métodos, que no caso da classe Cachorro poderiam ser sente(), coma() e morda(). HOT TOPIC • • • • • Mensagem é uma chamada a um objeto para invocar um de seus métodos, ativando um comportamento descrito por sua classe. Também pode ser direcionada diretamente a uma classe (através de uma invocação a um método estático). Sobrecarga (OVERLOADING) é a utilização do mesmo nome para símbolos ou métodos com operações ou funcionalidades distintas. Geralmente diferencia-se os métodos pela sua assinatura. Exemplo: Um método Carro que recebe como parâmetro dois atributos (cor, placa), e outro método Carro que recebe como parâmetro (cor, placa, modelo). Sobrescrita (OVERRIDING) é o mecanismo que permite sobrescrever um método por completo em uma subclasse. Está relacionado com o conceito de polimorfismo. Herança (ou generalização) é o mecanismo pelo qual uma classe (subclasse) pode estender outra classe (superclasse), aproveitando seus comportamentos (métodos) e variáveis possíveis (atributos). Há Herança Múltipla quando uma subclasse possui mais de uma superclasse. Essa relação é normalmente chamada de relação "é um". Um exemplo de herança: Mamífero é superclasse de Humano. Ou seja, um Humano é um mamífero. Associação é o mecanismo pelo qual um objeto utiliza os recursos de outro. Pode tratar-se de uma associação simples "usa um" ou de um acoplamento "parte de". Por exemplo: Um humano usa um telefone. A tecla "1" é parte de um telefone. HOT TOPIC • • • • Encapsulamento consiste na separação de aspectos internos e externos de um objeto. Este mecanismo é utilizado amplamente para impedir o acesso direto ao estado de um objeto (seus atributos), disponibilizando externamente apenas os métodos que alteram estes estados. Exemplo: você não precisa conhecer os detalhes dos circuitos de um telefone para utilizá-lo. A carcaça do telefone encapsula esses detalhes, provendo a você uma interface mais amigável (os botões, o monofone e os sinais de tom). Abstração é a habilidade de concentrar nos aspectos essenciais de um contexto qualquer, ignorando características menos importantes ou acidentais. Em modelagem orientada a objetos, uma classe é uma abstração de entidades existentes no domínio do sistema de software. Polimorfismo é o princípio pelo qual duas ou mais classes derivadas de uma mesma superclasse podem invocar métodos que têm a mesma assinatura (lista de parâmetros e retorno) mas comportamentos distintos, especializados para cada classe derivada, usando para tanto uma referência a um objeto do tipo da superclasse. Interface é um contrato entre a classe e o mundo externo. Quando uma classe implementa uma interface, ela está comprometida a fornecer o comportamento publicado pela interface. Métodos • Referências bibliográficas • http://inf.unisinos.br/~anibal • http://pt.wikipedia.org/wiki/Orienta%C3%A7%C3%A3o_a_objetos