Unidade: sobrecarga, construtores e herança 0
Unidade: sobrecarga, construtores e herança Sobrecarga Sobrecarregar (do inglês overload) um método é criar mais métodos com o mesmo nome, porém com assinaturas diferentes. Os parâmetros podem se diferenciar em tipo e/ou em quantidade assim como o tipo de retorno. Ficará a cargo de o compilador escolher, de acordo com a lista de argumentos enviados, os métodos a serem executados. Vamos dar uma olhada no seguinte método da classe Util. Podemos notar no método acima que ele deve receber dois valores inteiros e o método irá imprimir na tela a resposta da soma. Para testar esse método podemos ter algo parecido com: No exemplo anterior a resposta impressa na tela será Soma=7. Agora imagine que precisamos fazer um método que some números reais e não números inteiros. Para o usuário seria muito mais intuitivo se apenas trocasse os números usando algo do tipo: 1
Porém isso não vai funcionar, pois nosso método soma está esperando 2 números inteiros e não 2 números reais como parâmetros, dando erro na compilação, exceto se criarmos outro método que seja capaz de receber números reais. A classe ficaria assim: Dessa forma temos agora o método soma sobrecarregado e a chamada com números reais vai funcionar também. Podemos também sobrecarregar novamente o método soma e querer somar Strings, o processo seria o mesmo e o método ficaria assim. Além disse, podemos trocar o número de parâmetros de entrada, por exemplo, somar 3 números. Olhe o método a seguir: Claro que as possibilidades são ilimitadas e a sobrecarga vai depender das necessidades de cada projeto de classe. Em Java muitos métodos já são sobrecarregados. Por exemplo, o próprio comando de imprimir que sempre 2
usamos System.out.println possui várias sobrecargas. Você pode passar como parâmetro um número inteiro, um número real ou mesmo uma String que ele consegue imprimir na tela o que passou. Isso quer dizer que existe um método println que recebe um int, outro que recebe um double, outro que recebe uma String além de outros tipos. Construtor Construtores são métodos que são invocados automaticamente quando um objeto é instanciado. São métodos que nunca retornam nada e não possuem tipo. Em Java, sempre tem o mesmo nome da classe a que pertence. Vamos pensar em uma classe Data que tenha como atributos privados o dia, mês e ano. Algo do tipo: 3
A classe Data mostrada anteriormente, quando instanciada, atribui zero aos seus atributos. Veja o exemplo: No exemplo mostrado, será impresso 0/0/0, pois não foram atribuídos valores para os atributos do objeto. Mas se quisermos que, ao instanciar um objeto ele seja criado com um valor padrão de 01/01/1970? Nesse caso podemos criar um construtor, que em Java tem o mesmo nome da classe, precisa ser público e não tem tipo de retorno. Veja a classe Data como ficou: Com isso, agora quando instanciamos qualquer objeto da classe data, se não colocarmos valor aos seus atributos eles receberão o valor padrão. Um construtor nada mais é que um método, assim como os outros, que também pode ser sobrecarregado. No caso de métodos que não tem retorno, podemos alterar somente os seus parâmetros. Veja uma sobrecarga de construtor na classe Data a seguir. 4
Em Java existe uma referência para a própria classe através da palavrachave this. Assim, no construtor ao invés de usar dia = d, podemos usar this.dia = d. Nesse caso, podemos até usar as mesmas variáveis no construtor, já que podemos diferenciar as variáveis dos atributos. Agora, quando instanciamos um objeto da classe Data, podemos optar por usar o construtor que não tem parâmetros ou o construtor que possui 3 parâmetros. Veja como fica: No exemplo anterior, será impresso 1/1/1970 na primeira data e 25/12/2010 na segunda. 5
Herança Vamos recordar o conceito de abstração. Abstração é a capacidade de capturar as informações relevantes para representar na forma de classes. Ela pode ser considerada como uma generalização que tem como função obter propriedades e comportamentos essenciais determinando o que é importante para representar os objetos. Figura 1 Modelo de Abstração / Especialização Na Figura 1 anterior, vemos que criando um modelo hierárquico para representar meios de transporte, subir na hierarquia significa que estamos generalizando, obtendo informações que são comuns a todos os itens do nível inferior. Por outro lado, cada vez que descemos na estrutura, estamos sendo mais específicos e detalhados. Herança é o mecanismo pelo qual as linguagens orientadas a objetos possam fazer com que classes herdem características de outras classes. Com a herança pode-se economizar tempo durante o desenvolvimento de um programa baseando novas classes em classes já testadas, assim reaproveitando componentes já prontos. Além disso, isso aumenta a capacidade de adaptação e manutenção de um sistema, visto que ao ajustar uma classe pai, todas as classes que a usam na herança serão ajustadas automaticamente. Ao criar uma classe, ao invés de criar atributos e métodos do zero, você pode aproveitar atributos e métodos de classes existentes e testadas. A classe existente é chamada de superclasse, classe pai ou classe base e a nova classe é chamada de subclasse, classe filha ou classe derivada. 6
Uma subclasse também pode ter novos atributos e métodos além dos herdados da superclasse, pois ela será mais específica do que a superclasse que é mais genérica. A superclasse proporciona a funcionalidade que é comum a todas as suas subclasses, enquanto que uma subclasse proporciona a funcionalidade adicional que especializa seu comportamento, conforme ilustrado na Figura 2. Figura 2 Exemplo de superclasse e subclasses Em um diagrama de classes, subclasses podem ser superclasses de outras classes. Veja na Figura 3 que a classe Pós-Graduação é subclasse de Curso Universitário, mas também é superclasse de Especialização e Extensão. Figura 3 Hierarquia de Classes Veja outro exemplo na Figura 4 de uma estrutura de herança com vários níveis. A classe Animal é a mais genérica de todas e temos um exemplo de instâncias para as últimas subclasses da estrutura. 7
Figura 4 Hierarquia de Classes Algumas linguagens OO permitem fazer herança múltipla como o C++, o que significa que uma subclasse pode herdar características de duas ou mais classes. Isso permite que uma classe agrupe atributos e métodos de várias classes, conforme ilustra a Figura 5. Figura 5 Herança Múltipla Java não possui herança múltipla, porém consegue simular esse comportamento através do uso de Interfaces que veremos na próxima unidade. 8
Figura 6 Diagrama de classe UML de herança Vamos usar como base o diagrama de classes UML da Figura 6 para aprendermos como programar em Java a herança de classes. Claro que devemos começar com a superclasse mais genérica (MembroUniversidade), que não diferencia de nada do que já usamos anteriormente. 9
Note na classe anterior que o comum é criar uma classe sempre com os atributos privados, um construtor padrão, ou seja, um construtor que não tenha parâmetros para iniciar seus atributos com um valor padrão, um construtor com parâmetros que receba valores para todos os atributos além dos métodos de acesso set e get. Vamos agora implementar a classe Aluno que herda todas as características de MembroUniversidade. O aluno terá nome e nascimento, portanto usar CTRL+C e CTRL+V não é mais uma prática desejável para programadores OO. Através do mecanismo de herança vamos criar a subclasse Aluno usando a palavra chave extends. Veja a classe abaixo: Quando colocamos extends MembroUniversidade na frente da classe Aluno estamos dizendo que essa classe passa a ser uma subclasse e herda todos os atributos e métodos da superclasse. Portanto, Aluno também terá os atributos nome e nascimento e os métodos do pai. Note que além dos atributos herdados, Aluno também tem seus próprios atributos (RGM e curso), portanto também seus métodos de acesso set e get. Agora notem que o construtor sem parâmetros possui um item novo 10
super(). A palavra chave super refere-se sempre à superclasse da classe que você se encontra. No exemplo, o comando super() está chamando o construtor da classe pai. Veja agora que o construtor com parâmetros possui 4 argumentos, pois Aluno herdou 2 do pai e possui 2 próprios, portanto, ele precisa mandar 2 para o pai com super(no, na) e atribuir os outros 2 aos seus atributos. Veja agora como fica a classe Bolsista que será subclasse de Aluno. Veja novamente que além dos atributos herdados de aluno, Bolsista agora tem mais um chamado valorbolsa com seus próprios métodos de acesso. Note também que o construtor com parâmetros possui 5 argumentos, pois herdou 4 de Aluno e possui 1 próprio. Os 4 herdados precisam ser enviados ao pai através do comando super(no, na, r, cur), que já sabemos que chamará o construtor da classe pai. Claro que as classes Funcionário e Professor podem ser desenvolvidas de maneira simular, mas a pergunta é, posso instanciar objetos de qualquer umas das classes do diagrama? Sim, claro. Todas as classes do diagrama UML da Figura 6 são chamadas classes concretas, ou seja, permitem criar objetos. Veremos na próxima unidade um tipo especial de classe chamada Classe Abstrata que serve apenas para 11
estruturar outras classes, mas não gera objetos. Veja como podemos instanciar objetos das classes criadas, usando o construtor padrão e o construtor com parâmetros. Imagine agora que uma nova política diga que para qualquer membro da universidade, não importa se é aluno, professor, bolsista ou funcionário, se não for dito a data de nascimento, usar um valor padrão de 01/01/1970. Para isso basta alterarmos o construtor padrão da classe MembroUniversidade e todas as outras classes herdarão essa característica, o que seria mais complicado se tivéssemos que alterar um por um. 12
Referências SINTES, Tony. (2002) Aprenda Programação Orientada a Objetos em 21 dias. 1 ed. São Paulo: Pearson Education do Brasil, 2002, v. 1. DEITEL, P.; DEITEL, H. (2010) Java Como Programar, 8 ed. São Paulo: Pearson Education do Brasil, 2010. HORSTMANN, C.S.; CORNELL, G. (2010) Core Java. 8 ed. São Paulo: Pearson Education do Brasil, 2010, v. 1. 13
14 Responsável pelo Conteúdo: Prof. Ms. Amilton Souza Martha Lattes: http://lattes.cnpq.br/5455047756459479 Revisão Textual: Profª. Ms. Rosemary Toffoli www.cruzeirodosul.edu.br Campus Liberdade Rua Galvão Bueno, 868 01506-000 São Paulo SP Brasil Tel: (55 11) 3385-3000