Escolar Documentos
Profissional Documentos
Cultura Documentos
Java
Objetivo
Entender os principais conceitos de Programao Orientada a Objetos (POO) e a sua aplicao no desenvolvimento de aplicaes em Java
Pr-Requisitos
Conhecimentos da sintaxe e tipos de dados bsicos da linguagem Java, vista sob o ponto de vista da Programao Estruturada (ver o mdulo De Pascal Para Java)
Esquentando os Motores
Escreva um programa em Java que, dado um nmero de at quatro algarismos (passado na linha de comando), escreva na tela a sua representao por extenso > java Extenso 1234 Mil duzentos e trinta e quatro
Gerenciar a complexidade crescente dos sistemas sendo construdos nas empresas, viabilizando o trabalho conjunto de grandes equipes e o cumprimento de metas de qualidade, prazo e oramento Aumentar a produtividade dos analistas e programadores pela reutilizao de cdigo pronto e depurado escrito em sistemas anteriores ou adquiridos no mercado
Paradigmas de Programao
Programao Orientada a Eventos Programao Orientada a Objetos Programao Estruturada Programao Procedural
Paradigmas de Programao
Estilo de Interface com o Usurio Conceitos de Negcio (Entidades, Atividades, etc) Lgica de Programao Funcionamento da Mquina
POO e Java
1. Conceitos de POO 2. Classes e Objetos em Java 3. Interfaces 4. Relacionamentos entre classes 5. Outros recursos OO de Java
1. Conceitos de POO
Objeto Encapsulamento Classe Instncia Objetos como caixas-pretas Herana e Tipos Polimorfismo Sobreposio e sobrecarga Construtores
Objeto
Um objeto representa qualquer coisa do mundo real que seja manipulada pelo nosso programa, ou ento representa blocos de construo do prprio programa
Objeto
Estado so informaes sobre o objeto, como a sua cor, seu peso, o saldo da conta-corrente, etc Comportamento so coisas que podem ser feitas com ou pelo objeto, como depositar em uma conta-corrente ou mudar a cor de uma janela
Objetos tambm tem uma identificao, de modo que possamos diferenciar entre vrios objetos semelhantes
Encapsulamento
Dizemos que um objeto em um programa encapsula todo o estado e o comportamento, de modo que podemos tratar o objeto como uma coisa s, em vez de ter vrias variveis e subprogramas isolados entre si por isso que um programa em Java costuma ser formado por vrios objetos em vez de apenas um Os objetos encapsulados corretamente so independentes da programa onde eles so utilizados
Classe
Vrios objetos semelhantes possuem o mesmo tipo de informao em seu estado e tem o mesmo comportamento Dizemos que estes objetos pertencem a uma mesma classe, ou so de um certo tipo de classe Assim, uma classe ContaCorrente pode definir todo o estado e comportamento que uma conta-corrente pode ter
Estado e Comportamento
Armazenamos este estado nos atributos do objeto Estes atributos so chamados ainda de variveis de instncia da classe
O comportamento de um objeto tudo o que ele sabe fazer, e tudo o que pode ser feito com ele
Instncia
Dizemos que um objeto em particular de uma dada classe uma instncia desta classe Em Java, definimos classes e criamos variveis que referenciam instncias de uma classe O estado do objeto/instncia salvo em variveis da instncia, e o comportamento definido por mtodos na classe Criamos instncias de uma classe utilizando o comando new
Classe x Instncia
Os funcionrios Fernando e Ricardo O Corsa Verde placa LCW 1666 A Nota Fiscal #21234 referente a um gaveteiro de escritrio, 4 puxadores cromados e uma cadeira
Em um programa Orientado a Objetos, escrevemos (programamos) definies de classes em vez de programas e subrotinas Apenas durante a execuo deste programa so criadas instncias das classes que foram definidas Cada instncia possui o seu prprio conjunto de atributos, independente de outras instncias da mesma ou de outras classes Todas as instncias de uma mesma classe compartilham as mesmas definies de mtodos
Quando falamos de objeto, nos referimos tanto ao conceito geral de um tipo de objetos (classe) quanto a um objeto em particular de uma dada classe (instncia) Nas linguagens de programao OO, tanto classes quanto instncias podem ser manipuladas como objetos, utilizando a mesma sintaxe para acesso a mtodos e atributos Os objetos de classe esto sempre disponveis, enquanto que as instncias devem ser criadas (devemos instanciar os objetos)
Uma boa prtica tratar os objetos como se fossem caixas-pretas. Isto significa que no permitimos a nada fora do objeto modificar o seu estado Desta forma evitamos que erros em uma parte do programa tenham consequncias em outras partes do mesmo Este o princpio do ocultamento de informaes
Em Java, isto significa que nenhum cdigo fora do objeto pode modificar os atributos (variveis) internas ao objeto. O estado do objeto modificado como consequncia da execuo dos seus mtodos comum criar mtodos do tipo setAtributo e getAtributo quando tudo o que queremos salvar ou recuperar uma informao dentro de um objeto
A Classe ContaCorrente
Definir uma classe Instanciar objetos desta classe Utilizar mtodos destas instncias
ContaCorrente.java
Class ContaCorrente { private double saldo = 0; public void deposito (double valor) { saldo += valor; } public void saque (double valor) { saldo -= valor; } public double getSaldo () { return saldo; } }
A Classe ContaCorrente
Possui apenas um atributo: saldo O valor deste atributo pode ser recuperado pelo mtodo getSaldo O saldo de uma conta-corrente modificado em consequncia das operaes de saque e depsito executados sobre ele, da os mtodos com o mesmo nome Embora seja permitido, evite utilizar acentos em nomes de classes, mtodos e atributos
Caixa.java
class Caixa { static public void main (String[] args) { ContaCorrente conta = new ContaCorrente(); System.out.println ("Saldo inicial = " + conta.getSaldo ()); conta.deposito (100.00); System.out.println ("Novo saldo = " + conta.getSaldo ()); } }
O Programa Caixa
definido pela classe Caixa, que contm apenas o mtodo esttico main Mtodos estticos (static) so ditos mtodos de classe, podemos executa-los (invoca-los) sem antes instanciar objetos desta classe O mtodo Caixa.main apenas instancia um objeto da classe ContaCorrente, consulta o seu saldo e realiza um depsito, verificando ento o novo saldo; no passa de um programa de testes, mas um sistema real teria uma classe Caixa responsvel pela interao com o usurio
Exerccio
Modifique o programa Caixa.java para criar vrias instncias de ContaCorrente e realizar depsitos de valores diferentes em cada uma, comprovando que cada instncia mantm o seu prprio estado Mova o mtodo main da classe Caixa para a classe ContaCorrente, de modo que ela mesma contenha um programa principal, ou melhor, um mtodo de teste que demonstre o seu uso e funcionalidade
Discusso
Por que no declarar o atributo saldo como pblico (public) e realizar aritmtica diretamente com o seu valor? Isto no seria mais simples? De quem (qual mtodo, qual classe) seria a responsabilidade de verificar se existe saldo suficiente em uma conta para a realizao de um saque?
Em geral se entende facilmente a idia de objetos informacionais, isto , objetos que representam conceitos ou coisas sobre as quais armazenamos informaes em nossos sistemas Mas para se obter resultados mais efetivos das tcnicas de OO, temos que explorar principalmente os objetos de atividade, isto , objetos que representam atividades, processos ou transaes realizadas pelo sistema
Transferencia.java
class Transferencia { private ContaCorrente origem; private ContaCorrente destino; private double valor; // mtodos setXXX para os atributos // origem, destino e valor, exemplo: public void setOrigem (ContaCorrente origem) { this.origem = origem; } public ContaCorrenet getOrigem () { return origem; } // continua...
Transferencia.java
A Palavra-Chave this
Quando um mtodo de instncia necessita obter uma referncia instncia em particular que o est executando, ele pode usar a referncia pr-definida this H duas situaes principais para o uso do this:
Eliminar conflitos de nome, como entre o argumento origem e o atributo origem da classe Transacao Passar referncias a si mesmo para outros objetos, de modo similar ao Me do Visual Basic ou ao Self do Delphi
static public void main (String[] args) { ContaCorrente contaOrigem = new ContaCorrente(); contaOrigem.deposito (1000.00); ContaCorrente contaDestino = new ContaCorrente(); contaDestino.deposito (2000.00); System.out.println ("Antes da transferencia"); System.out.println ("Saldo origem = " + contaOrigem.getSaldo ()); System.out.println ("Saldo destino = " + contaDestino.getSaldo ()); Transferencia pagamento = new Transferencia (); pagamento.setOrigem (contaOrigem); pagamento.setDestino (contaDestino); pagamento.setValor (250.00); pagamento.realiza (); System.out.println ("Depois da transferencia"); System.out.println ("Saldo origem = " + contaOrigem.getSaldo ()); System.out.println ("Saldo destino = " + contaDestino.getSaldo ()); }
Conceitos x Cdigo
Em situaes simples como o ltimo exemplo, podemos ser tentados a incluir a lgica da operao diretamente em nosso programa, ou a simplesmente definir um mtodo que realize a operao, sem criar a classe Transferencia. Entretanto o conceito de uma transferencia de valores entre duas contas importante o suficiente no dia-a-dia de um banco para justificar o seu encapsulamento em uma classe isolada Classes e objetos devem representar conceitos, e no apenas serem sacos de cdigo em Java
Uma aplicao bancria real teria vrias outras funcionalidades associadas a uma classe Transferencia, por exemplo:
Registro histrico, para fins de auditoria e emisso do extrato para o cliente Compensao de fundos entre bancos diferentes Restries sobre operaes (ex: caixa eletrnico ou na agncia; horrio comercial ou noturno)
A classe Transferencia pode ser expandida sem efeitos colaterais negativos no restante do sistema
Discusso
Mtodos de uma classe devem modificar o estado de uma nica instncia desta desta classe Operaes que envolvam modificar o estado de vrias instncias diferentes (mesmo que sejam da mesma classe) devem ser encapsulados em classes de atividade As classes de atividade podem validar se receberam toda a informao correta antes de realizar a atividade e so mais amigveis a ferramentas visuais
Herana ou Especializao
Uma classe pode ser derivada de outra classe, e desta forma herdar tanto seu estado quanto o seu comportamento A criao de subclasses (classes derivadas de uma superclasse) permite o aumento incremental da funcionalidade dos nossos objetos ou sua especializao Se precisarmos de um objeto que faa o mesmo que outro objeto faz e mais alguma coisa, aproveitamos o cdigo que j est pronto e testado, definindo uma subclasse contendo apenas as novidades
ContaRemunerada.java
class ContaRemunerada extends ContaCorrente { public void aplicaRendimentos (double taxa) { deposito (getSaldo () * taxa); } // mtodo main para teste da classe static public void main (String[] args) { ContaRemunerada conta = new ContaRemunerada(); System.out.println ("Saldo inicial = " + conta.getSaldo ()); conta.deposito (100.00); conta.aplicaRendimentos (0.05); System.out.println ("Novo saldo = " + conta.getSaldo ()); } }
A Classe ContaRemunerada
Extende a classe ContaCorrente, de modo que ela tambm possui o atributo saldo e os mtodos saque, deposito e getSaldo Acrescenta o mtodo aplicaRendimentos ( claro que uma implementao real desta classe verificaria qual taxa aplicar de acordo com a data do ltimo saque ou deposito e recolheria impostos ou taxas de servio)
Boas Prticas
H uma grande tentao de definir atributos protegidos (protected) em superclasses, de modo que as subclasses possam manipular diretamente estes atributos, em vez de utilizar apenas os mtodos fornecidos (pblicos) pela superclasse Entretanto, esta prtica aumenta o risco de modificaes na superclasse refletirem no funcionamento incorreto da subclasse Portanto devemos ocultar informaes tambm entre superclasses e subclasses!
Variveis cujo tipo seja uma classe podem referenciar tanto objetos da classe declarada quanto de classes derivadas O Java define a classe Object, de modo que se possa definir variveis capazes de referenciar objetos de qualquer classe Toda classe em Java extende implicitamente Object graas existncia da classe Object que podemos utilizar PrintWriter.println ou Vector.add com instncias de qualquer classe
Exerccio
Escreva um programa (chame de Subtipo.java) que realize uma Transferencia entre uma ContaCorrente e uma ContaRemunerada Como uma ContaRemunerada deriva de ContaCorrente, ela efetivamente uma ContaCorrente, ou seja, variveis ou argumentos do tipo ContaCorrente podem referenciar tambm objetos do tipo ContaRemunerada Portanto a classe Transferencia no necessita ser modificada para lidar com instncias de ContaRemunerada
Subtipo.java
class Subtipo { static public void main (String[] args) { ContaCorrente conta1 = new ContaCorrente(); conta1.deposito (100.00); ContaRemunerada conta2 = new ContaRemunerada(); conta2.deposito (200.00); System.out.println ("Conta Corrente = " + conta1.getSaldo ()); System.out.println ("Conta Remunerada = " + conta2.getSaldo ()); Transferencia transf = new Transferencia(); transf.setOrigem (conta1); transf.setDestino (conta2); transf.setValor (50.00); transf.realiza (); System.out.println ("Conta Corrente = " + conta1.getSaldo ()); System.out.println ("Conta Remunerada = " + conta2.getSaldo ()); } }
Polimorfismo
Todas as referncias a objetos em Java (sejam variveis de instncia, variveis locais ou argumentos de mtodos) so ditas referncias polimrficas, pois podem referenciar objetos de vrias classes diferentes. O polimorfismo (ou o uso de referncias polimrficas) permite escrever cdigo genrico, que no ser modificado pela adio de novas classes ao sistema O cdigo genrico mais simples de criar e de manter, e evita duplicaes de esforo
Referncias Polimrficas
A classe Trasferencia utiliza referncias polimrficas, pois os atributos origem e destino podem referenciar tanto instncias de ContaCorrente quanto de qualquer outra subclasse, como ContaRemunerada Se futuramente criarmos outros tipos de conta, elas podero ser utilizadas como origem ou destino de transferncias, sem que a classe Transferencia necessite ser modificada ou mesmo recompilada Java expande o conceito de polimorfismo para permitir expanses pontuais da aplicao
Sobrecarga
Temos outra forma de polimorfismo em Java: podemos definir mtodos com o mesmo nome, porm recebendo argumentos diferentes Chamamos a esta forma de polimorfismo de sobrecarga de mtodos A sobrecarga pode mudar tanto a quantidade quanto os tipos dos argumentos; mas no pode mudar o tipo do valor de retorno de um mtodo
ContaRemunerada2.java
class ContaRemunerada2 extends ContaCorrente { private double taxaPadrao; // mtodos get/set para o atributo taxaPadrao public void aplicaRendimentos () { aplicaRendimentos (taxaPadrao); } public void aplicaRendimentos (double juros) { deposito (getSaldo () * juros); } // mtodo main para teste da classe }
A Classe ContaRemunerada2
Digamos que toda ContaRemunerada possua uma taxa (de rendimento) padro, armazenada como um atributo de instncia Em ocasies especiais, o banco pode decidir dar um rendimento maior para uma conta, por exemplo se o titular da conta foi sorteado em uma promoo As duas verses do mtodo aplicaRendimentos lidam respectivamente com a situao normal e com a ocasio especial
Boas Prticas
Na definio de mtodos sobrecarregados, h uma tendncia a copiar o cdigo de uma verso do mtodo para a outra, que ento editada para realizar o comportamento pretendido Quando a lgica na verso original do mtodo modificada, facilmente se esquece de modificar tambm a cpia no mtodo sobrecarregado Por isso deve-se escrever verses sobrecarregadas de mtodos invocando sempre a verso mais completa, evitando duplicao de cdigo
Inicializao de Instncias
Nem sempre faz sentido instanciar uma classe deixando seus atributos com valores zero ou vazio Podemos desejar estabelecer valores padro para alguns atributos, pr-fixados ou calculados no momento da instanciao (ex: data/hora correntes) Podemos necessitar de informaes externas para criar instncias de uma classe no faz sentido deixar os atributos vazios nem seus valores podem ser calculados automaticamente (ex: CPF de um cliente, nmero de srie de NF)
Mtodos Construtores
Sempre que uma classe instanciada, o mtodo construtor invocado sobre a nova instncia O compilador Java fornece um construtor padro caso no seja definido nenhum outro construtor O construtor um mtodo pblico, sem tipo de retorno, com o mesmo nome da classe Caso o construtor receba argumentos, eles so especificados nos parnteses aps o nome da classe no comando new Podemos sobrecarregar construtores
ContaCorrente v2
class ContaCorrente { private double saldo; public ContaCorrente () { /*vazio*/ } public ContaCorrente (double saldoInicial) { deposita (saldoInicial); } // aqui seguem as definies de saldo, deposito e getSaldo // iguais verso 1 da classe ... }
Transferencia v2
class Transferencia { private ContaCorrente origem; private ContaCorrente destino; private double valor; public Transferencia () { } public Transferencia (ContaCorrente origem, ContaCorrente destino, double valor) { setOrigem (origem); setDestino (destino); setValor (valor); } // continua
Transferencia v2
// definio dos mtodos get/set para origem, destino e valor, // alm do mtodo realiza, confirme a verso 1 da classe ... static public void main (String[] args) { ContaCorrente conta1 = new ContaCorrente(120.00); ContaCorrente conta2 = new ContaCorrente(130.00); System.out.println ("Saldo Inicial1 = " + conta1.getSaldo ()); System.out.println ("Saldo Inicial2 = " + conta2.getSaldo ()); Transferencia transf = new Transferencia ( conta1, conta2, 50.00); transf.realiza (); System.out.println ("Saldo Inicial1 = " + conta1.getSaldo ()); System.out.println ("Saldo Inicial2 = " + conta2.getSaldo ()); } }
Boas Prticas
Utilize no construtor os mtodos setXXX definidos para a classe; assim garantimos que as regras de validao de dados definidas por eles sero aplicadas tambm nos construtores No obrigatrio ter um construtor sem argumentos (muitas vezes ele no deve existir para garantir a integridade de dados das instncias), mas ele necessrio para a manipulao em IDEs visuais Procure escrever todos os construtores em funo de um nico construtor mais completo (com mais argumentos) da mesma classe ou da superclasse
ContaRemunerada v3
class ContaRemunerada extends ContaCorrente { private double taxaPadrao; public ContaRemunerada (double saldoInicial, double taxa) { super (saldoInicial); setTaxaPadrao (taxa); } public ContaRemunerada (double saldoInicial) { this (saldoInicial, 0.05); } public ContaRemunerada () { this (0); } // ...
This e Super
Como this referencia a prpria instncia, ele pode ser utilizado para invocar outros construtores da mesma classe A palavra-chave super referencia a super-classe da instncia; em geral utilizada para chamar o construtor da superclasse Caso no seja inclusa a chamada ao construtor da superclasse, ser invocado o construtor sem argumentos Mtodos construtores no so herdados!
E os Destrutores?
Linguagens com alocao de memria explcita definem mtodos destrutores, executados automaticamente quando o objeto descartado Um objeto Java pode nunca ser descartado (porque o programa foi encerrado antes da execuo do coletor de lixo) por isso no faz sentido definir destrutores Operaes de finalizao ou limpeza, como fechar arquivos e conexes a Bds, devem ser realizadas por mtodos comuns, chamados explicitamente para a liberao de recursos externos
Sobreposio
Uma classe derivada pode sobrepor mtodos herdados, modificando o seu comportamento ou anulando-os completamente Se um mtodo declarado tanto na superclasse quanto na subclasse, o mtodo da subclasse predomina Em uma referncia polimrfica, predomina a verso do mtodo definida pela classe da instncia referenciada, e no a verso definida na classe declarada para a referncia
ContaEspecial.java
class ContaEspecial extends ContaCorrente { private double limite; // construtores com e sem argumentos, veja ContaRemunerada // mtodos get/set para o atributo limite public void saque (double valor) { if (getSaldo() + limite >= valor) super.saque (valor); } // mtodo main para teste da classe }
A Classe ContaEspecial
Adiciona o atributo limite, que impe um limite para o saldo negativo da conta a ContaEspecial no permite que o cliente se endivide sem controle Sobrecarrega o mtodo saque para garantir que o limite seja respeitado
Boas Prticas
Sempre que sobrecarregamos um mtodo de uma superclasse, h uma dependncia em relao forma como a superclasse realiza o mesmo mtodo Esta dependncia pode ser explicitada (e o cdigo da subclasse simplificado, evitando duplicao de cdigo) utilizando o mtodo original como parte da lgica do mtodo sobrecarregado A referncia super permite o acesso aos mtodos originais dentro de mtodos sobrecarregados
Exerccio
Crie um programa que, utilizando a classe Transferencia, seja capaz de realizar transferncias entre contas corrente, contas remuneradas e contas especiais Utilize construtores para simplificar os seus mtodos de teste O polimorfismo o conceito mais til de POO sob o ponto de vista da produtividade dos desenvolvedores, mas tambm um dos mais difcies de se assimilar
Frequentemente se define subclasses que apenas fornecem valores padro (defaults) para alguns atributos da superclasse, e ocasionalmente os mtodos setXXX destes atributos so sobrecarregados para evitar a modificao destes atributos Tambm se define subclasses que no acrescentam ou modificam nenhuma das caractersticas herdadas, mas servem apenas para que outras classes possam reconhecer tipos diferentes de objetos com o mesmo comportamento
Exerccio
Suponha que o nosso banco considere trs classes de cliente: o cliente salrio, que no pode ter saldo negativo; o cliente especial, que pode ter um limite de R$1000,00 negativos em sua conta corrente; e o cliente vip, que recebe um crdito de R$5.000,00 como limite de saldo negativo Defina subclasses de ContaEspecial para cada um desses tipos de clientes e escreva um programa de teste que realize saques dentro e fora dos limites de cada conta
ContaClienteVIP.java
class ContaClienteVIP extends ContaEspecial { public ContaClienteVIP () { this (0); } public ContaClienteVIP (double saldoInicial) { super (saldoInicial, 5000.00); } }
Caso alguma operao venha a ser autorizada apenas para certos tipos de contas (clientes), podemos utilizar o operador instanceof
class AlgumaOperacao { private ContaCorrente contaOrigem; public void realiza () { if (contaOrigem instanceof ContaClienteVIP) // realiza a operao else // gera uma excesso } //...
Instanceof e Herana
O operador respeita a noo de que uma instncia de uma subclasse tambm uma instncia das suas superclasses:
ContaClienteVIP instanceof ContaCorrente == true ContaClienteVIP instanceof ContaEspecial == true ContaClienteVIP instanceof ContaRemunerada == false
3. Interfaces
Classes abstratas Refatorao Mtodos abstratos Casses abstratas puras e Interfaces Interfaces e tipos de dados Casts
Classes Abstratas
Muitas vezes temos conceitos que se aplicam a todo um conjunto de classes, determinando comportamentos que gostaramos de herdar de uma superclasse, mas no faria sentido instanciar objetos desta superclasse Definimos ento esta superclasse como sendo abstrata, de modo que ela possa fornecer estado e comportamento para classes derivadas, ou utiliza-la como tipo de dados para referncias, mas no seja permitido criar instncias As classes que podem ser instanciadas so denominadas classes concretas
Evoluo do Projeto
A definio origial da classe ContaCorrente possu um bug: ela permite que a realizao de saques mesmo que no haja saldo para satisfazer a operao Corrigir a classe ContaCorrente ir prejudicar o funcionamento da classe ContaEspecial O que necessitamos de uma classe para representar o conceito abstrato de Conta, fornecendo a funcionalidade genrica que ser herdada por ContaCorrente, ContaEspecial e ContaRemunerada
ContaAbstrata.java
abstract class ContaAbstrata { private double saldo = 0; public void deposito (double valor) { saldo += valor; } public void saque (double valor) { saldo -= valor; } public double getSaldo () { return saldo; } }
A Classe ContaAbstrata
Ela exatamente igual definio original de ContaCorrente, apenas acrescida da palavra-chave abstract e com o novo nome Seu objetivo fornecer apenas a manuteno do saldo para as classes derivadas, que so por sua vez responsveis por decidir quando saques e depsitos so permitidos, e por manter informaes adicionais necessrias para o clculo de rendimentos ou multas Em um sistema real, a ContaAbstrata tambm manteria histricos, auditoria, segurana, etc
ContaCorrente.java v3
class ContaCorrente extends ContaAbstrata { // construtores public void saque (double valor) { if (getSaldo () >= valor) super.saque (valor); } } // mtodo main para teste da classe
A Classe ContaCorrente v3
Note que ela idntica classe ContaEspecial se for removido o atributo limite As classes ContaRemunerada e ContaEspecial passam a especializar ContaAbstrata em vez de ContaCorrente A classe Transferencia continua funcionando com os trs tipos de contas, apesar das modificaes, desde que suas referncias polimrficas sejam ajustadas para o tipo ContaAbstrata Bons sistemas OO permitem modificaes extensas sem efeitos colaterais ou bolas de neve
Refatorao
No desenvolvimento de sistemas de modo geral, e em especial em sistemas OO, frequentemente decidimos mover a funcionalidade presente em uma dada classe para uma nova superclasse ou subclasse Ou ainda decidimos que certa lgica necessria em vrios mtodos ento decidimos criar um novo mtodo privativo (private) O processo de reescrever classes e mtodos para evitar a duplicao de cdigo ou aumentar o seu reaproveitamento chamado de refatorao
Refatorao x Qualidade
A refatorao de cdigo pode parecer perda de tempo a princpio, pois o tempo gasto poderia ser utilizado no desenvolvimento de novas funcionaldiades no sistema Entretanto, a refatorao aumenta a qualidade e a clareza do cdigo, ou a sua resistncia mudanas, de modo que ela contribui para a maior qualidade e sobrevida do sistema Lembrando: mais de 80% do tempo e esforo gasto em um sistema (ou em um mdulo do sistema) ocorre depois da entrega da sua primeira verso ao usurio!
Discusso
Mtodos Abstratos
O uso do polimorfismo exige a compatibilidade de tipo entre os objetos envolvidos, o que em geral se obtm com o uso de superclasses Mas h situaes em que no possvel fornecer uma implementao padro para ser herdada; criar uma classe abstrata com mtodos vazios no elegante... Nestes casos a implementao da superclasse abstrata incompleta: as classes concretas derivadas devem complementar o comportamento herdado
Mtodos Abstratos
Um mtodo abstrato fornece apenas uma assinatura, mas nenhuma implementao Mtodos abstratos s podem ser definidos em classes abstratas Uma subclasse deve implementar todos os mtodos abstratos herdados, ou deve ser ela mesma declarada como sendo abstrata
Transferencia.java v2
abstract class Transferencia { // atributos origem, destino e valor protected abstract double getLimite (); public void realiza () { if (valor <= getLimite ()) { origem.saque (valor); destino.deposito (valor); } } }
Transferencia v2
Pequenos valores podem ser transferidos pelo caixa eletrnico; Valores maiores podem ser transferidos na agncia; Valores muito grandes devem ser realizados por emisso (e posterior depsito) de cheques administrativos
O mtodo abstrato getLimite permite que classes especializadas para a agncia e para o caixa eletrnico e herdem a capacidade de realizar transferncias e sejam capazes de validar o limite de forma segura
TransferenciaAgencia.java e Transferencia24hs.java
class TransferenciaAgencia extends Transferencia { protected double getLimite () { return 20000.00 } } class Transferencia24hs extends Transferencia { protected double getLimite () { return 3000.00 } }
O mtodo abstrato getLimite corresponde a um atributo limite Em alguns tipo de transferncia o valor do limite pode ser calculado em funo de outros parmetros Ex: limite de R$500,00 para saques antes das 20:00hs, limite de R$100,00 para saques depois das 20:00hs Mtodos abstratos permitem a uma subclasse modificar um algoritmo implementado na superclasse, o que mais poderoso do que apenas parametrizar um algoritmo pr-fixado
As subclasses de Transferncia poderiam sobrecarregar o mtodo realiza para verificar se o valor est dentro dos limites permitidos para a subclasse Entretanto a existncia de um limite parte do conceito de transferncia entre contas, portanto deve ser expresso de alguma forma na classe abstrata Manter esta funcionalidade na superclasse (validao do limite) permite que ela trate corretamente a integridade transacional, auditoria, etc
Mtodos Protegidos
Quando um mtodo existe apenas para uso das subclasses podemos defini-lo como sendo protegido (protected) Desta forma podemos decidir que comportamento exposto para qualquer outra classe e que comportamentos so expostos apenas para as subclassses Tambm podemos definir atributos protegidos, mas no recomendado (ocultamento de informaes) Mtodos abstratos no so necessariamente protegidos
Investimentos
Uma caderneta de poupana simples rende juros sobre a quantia que no for movimentada durante o ms, de modo que ela no tem um nico saldo Cadernetas multidata podem render juros em vrias datas de aniversrio diferentes, de acordo com a realizao de depsitos Fundos de ao possuem uma quantidade de quotas e um valor da quota Mas interessante manipular investimentos da mesma forma que contas-corrente, realizando saques, depsitos, transferencias, ...
Poderamos definir classes FundoDeAcoes e CadernetaDePoupanca herdando de ContaAbstrata (para utilizar o polimorfismo) e sobrepondo todos os mtodos... no usufruindo do comportamento herdado, mas apenas das definies de mtodos Em linguagens OO podemos definir classes abstratas puras (onde todos os mtodos so abstratos) para utilizar polimorfismo sem herdar comportamentos que no sero utilizados O Java extende este conceito para a definio de interfaces
Interfaces
Interfaces so classes que no definem a implementao dos mtodos, mas apenas as suas assinaturas (nomes e argumentos) Interfaces no podem ter atributos Todos os mtodos de uma interface so implicitamente abstratos e pblicos Uma classe pode extender apenas uma nica superclasse (para evitar conflitos entre os comportamentos herdados), mas pode implementar vrias interfaces (mesmo que elas definam mtodos com a mesma assinatura)
interface Conta { void saque (double valor); void deposito (double valor); double getSaldo (); } abstract class Conta { public abstract void saque (double valor); public abstract void deposito (double valor); public abstract double getSaldo (); }
Podemos declarar variveis tipadas por interfaces da mesma forma que variveis tipadas por classes O primeiro caso indica uma referncia para qualquer objeto que implemente a interface O segundo caso indica uma referncia para qualquer objeto da classe ou de suas subclasses Interfaces permitem definir funcionalidade baseada em conceitos que se aplicam a vrias classes distintas (em hierarquias de especializao diferentes)
Extends x Implements
Uma classe extende outra classe Uma classe impementa vrias interfaces Uma interface extende vrias interfaces Uma classe pode, ao mesmo tempo, extender outra classe e implementar vrias interfaces
Investimento.java
interface Conta { void saque (double valor); void deposito (double valor); double getSaldo (); } interface Investimento extends Conta { Date getProximoAniversario (); void aplicaRendimentos (); } class ContaAbstrata implements Conta { private double saldo; //...
A Interface Investimento
Investimentos so tipos de Conta, pois podem sober operaes de saque e deposito Alm disso, investimentos recebem rendimentos em datas de aniversrio pr-definidas O mesmo cdigo pode realizar transferncias entre quaisquer tipos de Contas e/ou Investimentos O mesmo programa de retaguarda pode realizar a aplicao de rendimentos a cada dia em todos os tipos de investimentos
CadernetaDePoupanca.java
class CadernetaDePoupanca implements Investimento { private double saldoInicial; private double depositosPendentes; public void saque (double valor) { saldoInicial -= valor; } public void deposito (double valor) { depositosPendentes += valor; } public double getSaldo () { return saldoInicial + depositosPendentes; } // continua
CadernetaDePoupanca.java
private java.util.Date dataAbertura; public Date getProximoAniversario () { // calcula o prximo aniversario a partir da data de // abertura (mesmo do ms, ou o prximo dia til) } public void aplicaRendimentos () { if (/* hoje o dia do aniversrio*/) deposito (saldoInicial * getTaxaMesCorrente ()); saldoInicial += depositosPendentes; depositosPendentes = 0; } private static double getTaxaMesCorrente () { // ...
ContaRemunerada v3
class ContaRemunerada extends ContaAbstrata implements Investimento { //... public void saque (double valor) { //... } public void aplicaRendimentos () { //... } // ... }
Interfaces e instanceof
Uma instncia considerada como sendo cada uma das interfaces implementadas pela sua classe
ContaEspecial instanceof Conta == true ContaEspecial instanceof Investimento == false ContaRemunerada instanceof Conta == true ContaRemunerada instanceof Investimento == true ContaRemunerada instanceof ContaAbstrata == true CadernetaDePoupanca instanceof Conta == true
Tipagem Forte
O compilador Java verifica chamadas a mtodos de acordo com o tipo declarado para a varivel que referncia o objeto Assim uma varivel do tipo Conta pode referenciar uma ContaEspecial, mas no pode invocar o mtodo setLimite Somos obrigados a copiar a referncia para uma varivel (referncia) declarada como ContaEspecial Mas o compilador tambm no ir aceitar esta atribuio
Atribuies e Casts
// compila e funciona corretamente Conta conta = new ContaRenumerada (); Investimento invest = new ContaRenumerada (); // a instncia compatvel, mas o compilador no aceita invest = conta; // a instncia tem esta capacidade, mas o compilador no aceita conta.aplicaRendimentos (); // Temos que utilizar um cast para compatibilizar as referncias invest = (Investimento)conta; ((Investimento)conta).aplicaRendimentos(); // As duas linhas acima sero verificadas em tempo de // execuo, evitando erros de tela azul
Compatibiliade de Tipos
Uma subclasse compatvel com a superclasse Uma classe compatvel com as interfaces implementadas
Um quadrado com duas divises uma interface Um quadrado com trs posies uma classe Setas triangulares expressam relacionamentos de especializao (setas cheias) ou de implementao (setas tracejadas) Texto em itlico indica classe ou mtodo abstrato Texto sublinhado indica atributo ou mtodo esttico (de classe)
Usar ou no a Herana Coeso e Acoplamento Agregao Delegao Value Objects JavaBeans Colees Camadas da aplicao e o modelo MVC
A herana permite escrever menos cdigo (mais produtividade) entretanto ela cria uma forte dependncia entre subclasse e superclasse Modificaes na superclasse podem comprometer o funcionamento da subclasse Pense bem antes de usar herana: realmente existe especializao a nvel conceitual (no mundo real) ou apenas uma coincidncia que as classes tenham estado e/ou comportamento semelhantes?
Um Mal Exemplo
Pense em vrias janelas de uma mesma aplicao: elas tem elementos comuns, como um mesmo menu, um mesmo toolbar, uma mesma barra de status, ... Isto significa que devemos criar uma superclasse com esses elementos, e derivar dela classes para cada janela da nossa aplicao? No, porque conceitualmente uma janela no um subtipo (ou uma especializao) da outra janela. Janelas de uma aplicao em geral tem propsitos completamente diferentes
Coeso: uma boa classe (ou um bom mtodo) coeso, o que significa que ele serve apenas um propsito bemdefinido Acoplamento: uma boa classe (ou um bom mtodo) pouco acoplada com outras classes (ou mtodos), ou seja, tem poucas (idealmente nenhuma) dependncias sobre o funcionamento de outras classes (ou mtodos)
Agregao
Em geral melhor agregar classes do que derivar classes Agregar classes usar classes como partes constituintes de outras classes Uma instncia da classe A contm instncias da classe B: A agrega B ou A composta por B Em Java, isto significa que uma classe tem atributos que armazenam objetos de outras classes No exemplo, cada janela pode conter um atributo toolbar, um atributo menu, etc
Agregao e Delegao
Nem sempre o fato de uma classe agragar outra classe deve ser exposto Podemos utilizar o objeto agregado apenas para utilizar sua funcionalidade, delegando tarefas para ele Uma subclasse delega automaticamente para a superclasse
Exemplos
Agregao: Toda conta ou investimento possui um histrico de operaes, utilizado para gerar extratos Delegao: Um objeto conta delega uma solicitao de extrato para o objeto de histrico agregado Composio: Cada objeto histrico contm vrios objetos operao, referentes a depsitos, retiradas, transferncias, pagamentos, recolhimento de impostos, ...
Agregaes em Java
Definimos atributos que sejam referncias a outros objetos Definimos atributos que sejam referncias arrays ou colees de outros objetos Esses atributos podem ser inicializados (as referncias instanciadas) no construtor da classe Lembre que instanciar uma coleo ou array no instancia os objetos referenciados por cada elemento
Exerccio
Extrato tambm uma agregao de Operacao Cada operao de saque ou retirada adiciona uma Operacao ao Histrico agregado Conta
O histrico parte de uma conta (e consequentemente de um investimento) e contem operaes representando tudo o que foi feito sobre a conta desde a sua criao Um extrato um relatrio entregue ao cliente em um dado instante de tempo, relacionando as operaes realizadas sobre uma conta em um dado perodo de tempo Como se v, apesar de ambos serem agregados de operaes, eles possuem finalidades, atributos e capacidades diferentes
Classes de Coleo
comum se criar classes cuja principal finalidade gerenciar instncias de outras classes Estas classes incorporam a funcionalidade de criar, destruir, localizar e organizar (ordenar, filtrar) as instncias agregadas por ela Classes de coleo tambm so naturais para lgica de negcios que envolve vrias instncias de uma mesma classe ou de tipos compatveis Ex: aplicao dos rendimentos mensais em cadernetas de poupana
Colees em Java
Colees de objetos necessrios realizao da lgica de negcios da aplicao estas colees so parte dos conceitos da aplicao e representam objetos do mundo real Colees de objetos que representam estruturas de dados estas colees so ferramentas para a implementao das colees de negcios ou da lgica de mtodos de negcio especficos
O Java original possua apenas as classes Vector e Hashtable para representar colees dinmicas, enquando que os arrays representam colees estticas O Java2 definiu uma nova API de colees permitindo isolar a lgica de negcios de algoritmos especializados de busca e ordenao ou de compromissos de performance x consumo de memria
H dois tipos bsicos de coleo: Collections e Maps Uma Collection apenas agrega vrios objetos de qualquer tipo Um Map associa pares de objetos na forma (chave, valor) Qualquer tipo de coleo pode ser percorrida atravs de um objeto especializado que implementa a interface Iterator
Collections
H dois subtipos de Collection em Java: Sets representam conjuntos, no podem conter duplicatas e no preservada a ordem dos elementos Lists representam listas ordenadas, no sentido de que preservada a ordem de insero dos elementos na coleo, e podem conter duplicatas
Colees Ordenadas
SortedSets so Sets capazes de retornar seus elementos segundo um critrio de ordenao definido previamente SortedMaps so Maps capazes de retornar seus elementos segundo um critrio de ordenao definido previamente sobre suas chaves
Compatibilidade Retroativa
Vector foi refatorado em um List e HashTable foi refatorada como um Map, mas ambos esto presentes para compatibilidade retroativa recomenda-se utilizar as novas classes definidas no Java2, como:
ArrayList a implementao mais comum de List HashSet a implementao mais comum de Set TreeSet a implementao mais comum de SortedSet
A interface Collection
Iterators
Toda coleo capaz de fornecer um objeto Iterator que contm a inteligncia sobre como percorrer todos os elementos da coleo A interface Iterator implementa os mtodos:
hasNext: indica se chegamos ou no ao fim da coleo next: fornece uma referncia para o prximo objeto da coleo
Um iterator percorre a coleo sequenciamente, do incio ao fim Podemos ter vrios objetos Iterator independentes para uma mesma coleo
Exemplo: Percorre.java
class Percorre { public static void main (String[] args) { // popula a coleo List lista = new ArrayList(); lista.add ("Primeiro"); lista.add ("Segundo"); lista.add ("Terceiro"); // percorre a coleo Iterator it = lista.iterator (); while (it.hasNext ()) { String elemento = (String)it.next (); System.out.println (elemento); } } }
Sobre o Exemplo
O loop while utilizado para percorrer a coleo lista poderia ser escrito da mesma forma para qualquer outro tipo de coleo Observe o uso de casts na chamada ao mtodo next, pois as interfaces Collection e Iterator declaram seus argumentos e valores de retorno como referncias a Object
Exerccio
Modifique o exemplo Percorre.java para criar e percorrer um Set em vez de um List S ser necessrio modificar a instanciao da coleo, a sua populao e o loop while permanecem inalterados Os elementos so retornados na ordem em que foram inseridos? Experimente tambm inserir elementos duplicados e depois percorrer um List e um Set.
A Interface List
add (int index, Object element) set (int index, Object element) Object get (int index) int indexOf (Object element) int lastIndexOf (Object element) List sublist (int from, int to)
melhor precorrer uma lista utilizando o Iterator do que utilizando os mtodos get e size.
A classe java.util.Collections fornece mtodos estticos para buscar elementos, ordenar, inverter, embaralhar e outras operaes sobre colees quaisquer
A classe java.util.Array contm um mtodos estticos que permitem transformar um array em uma lista para usufriur das funcionalidades em Collections
A Interfafe Map
put (key, value) get (key) remove (key) containsKey (key) containsValue (value) size isEmpty
putAll clear
Obtemos um Iterator sobre a coleo de chaves (keySet) e utilizamos o mtodo get(key) sobre cada chave retornada pelo Iterator Obtemos um Iterator sobre a coleo de valores (values) Obtemos um Iterator sobre a coleo de pares (entrySet), que retorna objetos Map.Entry com a seguinte interface:
Exemplo: PercorreMapa.java
class PercorreMapa { public static void main (String[] args) { // popula o mapa Map mapa = new HashMap(); mapa.put ("Um", "Primeiro"); mapa.put ("Dois", "Segundo"); mapa.put ("Trs", Terceiro"); // percorre o mapa Iterator it = mapa.keySet().iterator (); while (it.hasNext ()) { String chave = (String)it.next (); String valor = (String)mapa.get (chave); System.out.println (valor); } } }
class PercorreMapa2 { public static void main (String[] args) { // popula o mapa Map mapa = new HashMap(); mapa.put ("Um", "Primeiro"); mapa.put ("Dois", "Segundo"); mapa.put ("Trs", Terceiro"); // percorre o mapa Iterator it = mapa.keySet().iterator (); while (it.hasNext ()) { Object chave = it.next (); // println e get delcaram Object como argumento System.out.println (mapa.get (chave)); } } }
Exerccios
Reescreva o exemplo PercorreMapa.java para utilizar as duas outras formas de se percorrer um Map Qual delas seria mais adequada para fornecer os objetos armazenados em um Map para um mtodo que espere receber uma referncia a Collection como argumento? Experimente: como exibir os elementos contidos dentro de um mapa ordenados pela chave ou pelo valor?
Exemplo: OrdenaMapa.java
import java.util.*; class OrdenaMapa { public static void main (String[] args) { // popula o mapa Map uf = new HashMap(); uf.put ("RJ", "Rio de Janeiro"); uf.put ("SP", "So Paulo"); uf.put ("MG", "Minas Gerais"); uf.put ("ES", "Esprito Santo"); // ordena pelas siglas System.out.println ("Ordenado pelas chaves..."); List chaves = new ArrayList (); chaves.addAll (uf.keySet()); Collections.sort (chaves); // continua...
Exemplo: OrdenaMapa.java
// continuao... // percorre o mapa Iterator it = chaves.iterator (); while (it.hasNext ()) { String chave = (String)it.next (); String valor = (String)uf.get (chave); System.out.println (chave + "\t" + valor); } } }
Observe que foi necessrio inserir os elementos do Set retornado por keySet em um List para que fosse possvel ordena-los.
A classe ComparaNomes
class ComparaNomes implements Comparator { public int compare(Object o1, Object o2) { Map.Entry e1 = (Map.Entry)o1; Map.Entry e2 = (Map.Entry)o2; String nome1 = (String)e1.getValue (); String nome2 = (String)e2.getValue (); return nome1.compareTo (nome2); } }
Podemos definir esta classe no prprio arquivo OrdenaMapa.java, mas ela no ser visvel para nenhuma classe em outros arquivos
Colees Personalizadas
Alm de criarmos colees de negcio para representar conceitos da aplicao, tambm criamos colees apenas para simplificar as chamadas a mtodos, eliminando a necessidade de casts frequentes Muitas vezes estas colees so atributos de classe (estticos)
Exerccio
Crie a classe MapaStrings para facilitar o uso de um Map onde tanto chaves quanto valores so Strings, e modifique o exemplo PercorreMapa para utilizar esta casse Observe que no podemos sobrecarregar o mtodo get para retornar um String!
Exerccio Opcional
Criar a classe Contas que contm todas as contas e investimentos definidos para o sistema Definir um mtodo para localizar uma conta dado o seu id (nmero) este atributo deve ser acrescentado interface Conta! Esta classe torna a aplicao independente do fato das contas serem armazenadas em memria, em um arquivo, em um banco de dados ou serem acessadas via WebServices!
Igualdade x Identidade
Cada instncia de uma mesma classe considerada um objeto nico e diferente dos demais Mas no mundo real existe ainda o conceito de igualdade Tome duas canetas: podemos reconhece-las como sendo iguais (so ambas novas, da mesma cor, do mesmo modelo e fabricante, ..) mesmo assim as reconhecemos como dois objetos diferentes, que podem ser manipuladas de modos diferentes
Value Objects
Muitas classes representam valores: Integer, String, Date, ... Objetos de valor (value objects) possuem o conceitos de igualdade Muitos objetos no possuem o conceito de igualdade, ou no permitem que hajam duas instncias com exatamente o mesmo estado Ex: Nota fiscal (mesmo que sejam duas notas fiscais para o mesmo produto e para o mesmo cliente, ainda so duas notas fiscais diferentes)
Devem sobrepor o mtodo equals (Object o), definido na classe Object Devem sobrepor o mtodo hashCode(), tambm definido na classe Object Dois objetos iguais devem retornar o mesmo hashCode para que possam ser manupulados corretamente dentro de Colees Recomenda-se que seja implementado o mtodo toString() Recomenda-se tambm um construtor que inicialize todos os atributos
Sets e Maps simples ou colees ordenadas podem funcionar erroneamente caso sejam utilizados para armazenar instncias de classes que no sejam Value Objects
equals determina se o objeto j est presente no Set ou se achave j est presente no Map no podem haver chaves duplicadas, embora objetos iguais possam estar associados a chaves diferentes hashCode utilizado nos algoritmos de hashsing utilizados por Set e Map
Endereco.java
class Endereco { private String logradouro; private int numero ; private String complemento; private String bairro; private String cep; // mtodos get/set para os atributos public Endereco () {} public Endereco (String logradouro, int numero, ...) { this.logradouro = logradouro; this.numero = numero; .... }
Endereco.java
public boolean equals (Object obj) { if (o instanceof Endereco) { Endereco e = (Endereco)obj; return ( ( logradouro == null && e.getLogradouro() == null ) || ( logradouro != null && logradouro.equals (e.getLogradouro ()) ) && ( numero == e.getNumero () ) && ... } else return false; }
Endereco.java
public int hashCode () { return (logradouro + numero + ...).hashCode (); } public String toString () { return logradouro + ", " + numero + " " + complemento ... } }
Exerccio
Crie uma classe Telefone que funcione como um Value Object Ela deve conter ao menos os atributos cdigo de rea, nmero e ramal O mtodo toString deve gerar o nmero convenientemente formatado, mas sem espaos ou pontuao suprfulos (experimente com e sem cdigo de rea) Escreva um programa de teste que instancie e compare vrios objetos Telefone
Discusso
Comparable Podem ser comparados. Necessria em objetos inseridos em colees ordenadas, a no ser que seja fornecido um Comparator Cloneable Podem ser clonados (podemos criar cpias deles, com estados independentes no a mesma coisa que copiar todos os atributos!) Serializable Podem ser salvos (persistidos) em memria no-voltil e recuperados para o seu estado original
JavaBeans
So classes onde:
Existe um construtor sem argumentos Existem mtodos get/set para todos os atributos So serializveis
Podem ser utilizadas como componentes em aplicaes GUI, pginas web, ...
Domnios de Objetos
Classes em uma camada s devem interagir com classes de domnios inferiores, fomentando a reutilizao e a manutenabilidade do sistema Domnio da Aplicao Domnio de Negcio
Atividade/Transao, Relacionamento, Papel ou Atributo gerenciamento e reconhecimento de eventos
Domnio de Arquitetura
Interface humana, Banco de Dados e Comunicao
Domnio de Base
Exemplo Hipottico
Domnio da Aplicao
gerenciamento (FormDeBusca) e reconhecimento de eventos (FiltroDePesquisa)
Domnio de Negcio
O Modelo MVC
Outra forma popular de diviso das classes de uma aplicao em camadas conforme o seu papel o Modelo Model-View-Controller
Model (Modelo) representa as informaes manipuladas pela aplicao View (Visualizao) representa uma visualizao destas informaes ou uma inteface para a sua edio Controller (Controlador) determina mudanas sobre o modelo e provoca a atualizao das visualizaes correspondentes
O falado desenvolvimento em trs camadas consiste na separao fsica da aplicao em trs camadas, hospedadas em ns diferentes da rede:
Apresentao, que fornece a interface com o usurio Negcios, que fornece a inteligncia da aplicao Persistncia, que armazena e recupera informaes de um banco de dados
A Java API
O maior benefcio do Java padronizar no apenas classes fundamentais, mas tambm classes semnticas, estruturais e da Camada de Arquitetura J existem esforos em vrias indstrias para padronizar classes na camada de Negcio, via EJBs ou WebServices O objetivo final das metodologias OO construir novas aplicaes apenas acrescentando novas classes na camada de Aplicao, reutilizando as classes prexistentes da camada de Negcio
Tratamento de Erros
Como um objeto informa a outro que algo no funcionou ou no possvel? Em linguagens estruturadas, definimos cdigos de retorno ou variveis de status Mas a necessidade constante de testar por esses cdigos e variveis prejudica a clareza da lgica de negcios Alm disso, frequentemente estes testes so omitidos e bugs se propagam sem serem detectados na origem
Excesses
Linguagens OO modernas como Java, C++ e ObjectPascal definem o conceito de excesso Uma excesso um objeto tratado de modo especial pelo ambiente de execuo (run-time): sua gerao provoca o trmino imediato do subprograma onde foi gerado, do programa chamador e assim sucessivamente at que o programa principal seja terminado ou algum subprograma capture a excesso Semelhante ao conceito de sinal no Unix ou de evento no Windows
Excesses em Java
So disparadas pelo comando throw So capturadas em blocos try..catch de modo a no interferir com a lgica de negcios as excesses so tratadas parte Caso no sejam capturadas por um mtodo, devem ser declaradas na sua assinatura pela clusula throws No capturar nem declarar uma excesso impede a compilao do programa, de modo que possveis falhas na execuo do mtodo tenham que ser tratadas em algum momento pela aplicao
Exceptions e Throwables
Todas as excesses so subclasses de Throwable Mas apenas as subclasses de Exception so verificadas pelo compilador As subclasses de Error no necessitam ser capturadas nem declaradas Toda excesso carrega uma mensagem descritiva, um stack frame (sequncia de mtodos at o momento da excesso) e possivelmente outras excesses aninhadas Frequentemente definimos novas excesses dentro do contexto da aplicao
Exceptions x RuntimeErrors
IOException FileNotFoundException SecurityException SaldoInsuficienteException LimiteTransferenciaEletroni caExcedidoException No utilizamos instanceof para diferenciar subclasses de Exception, mas sim mltiplas clusulas catch para um mesmo bloco try
NullPointerException ClassCastException DivisionByZero NumberFormatException ArrayIndexOutOfBoundsEx ception Podemos capturar RuntimeErrors utilizando blocos try..catch, apenas no somos obrigados a faze-lo pelo compilador
A lgica de negcio no deve interagir com o usurio, mas apenas gerar excesses para que a lgica de interface com o usurio (ou a lgica de um outro objeto de negcios) possa decidir como responder excesso e/ou fornecer feedback adequado ao usurio Em geral no devemos expor excesses de uma camada inferior para objetos de camadas superiores; por isso aninhamos excesses (veja o mtodo Throwable.getCause)
Exerccio
Modificar as classes e interfaces do exemplo de contas bancrias para gerar excesses quando saques e transferncias no puderem ser realizados:
SaqueNaoAutorizadoException SaldoInsuficienteException extends SaqueNaoAutorizadoException LimiteInsuficienteException extends SaqueNaoAutorizadoException LimiteOperacaoExcedido extends SaqueNaoAutorizadoException TransferenciaNaoAutorizadaException e subclasses
Gerenciando Classes
Uma aplicao tpica em Java define dezenas ou milhares de classes Aplicaes comerciais podem definir milhares de classes O prprio Java define milhares de classes para atividades comuns como criar interfaces grficas ou acessar bancos de dados Como garantimos que os nomes das classes no entrem em coliso uns com os outros?
Pacotes
A soluo do Java o conceito de pacote Pense em pacotes como subsistemas da sua aplicao, ou como uma biblioteca de objetos com um objetivo comum O Java define uma srie de pacotes padro:
java.math define classes para matemtica de preciso java.sql define classes para bancos de dados relacionais java.text ajuda na internacionalizao de programas java.util contm vrias estruturas de dados java.net contm classes para comunicao em redes
Pacotes
Os nomes de pacotes iniciados por java e javax so reservados para futuras expanses na API padro do Java Os seus pacotes devem ser nomeados de acordo com o domnio Internet da sua empresa ou instituio, por exemplo br.eti.lozano ou com.acme Vrias classes de um ou mais pacotes podem ser agrupados arquivo JAR, que nada mais do que um arquivo ZIP
Utilizando Pacotes
O comando import permite que um programa Java utilize classes definidas em um pacote Podemos incluir somente uma classe de um pacote
include java.util.Random;
Incluir um pacote no inclui subpacotes, ou seja, incluir java.util.* no inclui java.util.zip.* Todo programa inclui automaticamente o pacote java.lang, que define String, Double, Math e etc
Criando Pacotes
O comando package indica que a classe definida em um arquivo *.java faz parte de um pacote Voc deve criar subdiretrios correspondentes aos nomes dos seus pacotes, caso contrrio as suas classes no sero encontradas pela JVM Note que as classes tambm podem ser pblicas ou privativas em relao ao seu pacote, de modo que no precisamos expor todas as classes de um subsistema para o restante da aplicao!
Deve seguir a diviso do sistema em mdulos e tambm o conceito de camadas apresentado anteriormente:
Exemplo Simples
banco.conta contm as classes relacionadas com contas correntes e assemelhadas banco.investimento contm as classes relacionadas com investimentos diversos banco.transacoes contm as classes relacionadas com transferncias e etc banco.historico contm as classes relacionadas com extrato
Pacotes e Diretrios
banco
banco
conta
Conta ContaCorrente ContaEspecial
transacoes
Transferencia TransferenciaAgencia Transferencia24hs
investimento
CadernetaDePoupanca ContaRemunerada
historico
Operacao Historico
Pacotes e o CLASSPATH
Quando utilizamos vrios pacotes em uma mesma aplicao, torna-se necessrio incluir o diretrio raiz da aplicao no CLASSPATH, caso contrrio as classes no sero capazes de localizar umas s outras Ou ento iniciamos todas as compilaes partir do diretrio raiz, referenciando os arquivos *.java pelo path relativo
Windows > javac banco\conta\ContaCorrente.java > javac banco\investimento\*.java Linux $ javac banco/conta/ContaCorrente.java $ javac banco/investimento/*.java
Pacotes e o CLASSPATH
A opo -cp (classpath) dos comandos java e javac podem quebrar o galho em algumas situaes
> cd banco\conta > javac -cp ..\.. *.java > java -cp ..\.. banco.conta.ContaEspecial
Exerccio
Reorganizar as classes do sistema bancrio na estrutura de pacotes sugerida, recompilar todas as classes e executar alguns programas de teste Ser necessrio incluir comandos import em algumas classes, ex: banco.transacao.Transferencia deve importar banco.conta.Conta
Extensibilidade e Desacoplamento
At agora sempre acessamos mtodos e atributos de classes por meio de referncias a tipos declarados e conhecidos em tempo de compilao Como IDEs, servidores de aplicaes e aplicaes baseadas em plug-ins interagem com classes cujos tipos no so conhecidos em tempo de compilao? A resposta est nos mecanismos de reflexo e introspeco definidos nos pacotes java.lang e java.lang.reflect
A classe Class fornece o mtodo forName para carregar a classe nomeda na JVM, retornando uma referncia ao objeto que representa a classe (lembram que classes tambm so objetos em Java?) Objetos da classe Class fornecem mtodos para obter referncias a construtores (getConstructor) e mtodos (getMethod) Podemos ainda relacionar todos os mtodos, todos os atributos, saber os valores de retorno, ...
Utilizando as classes Object, Class, Constructor e Method podemos instanciar qualquer tipo de objeto em tempo de execuo, inclusive objetos de classes inexistentes durante a compilao do programa, e executar qualquer mtodo suportado pela classe ou por suas instncias! Cuidado com as excesses como ClassNotFoundException, NoSuchMethodException ou IllegalAccessException
Exemplo: Instancia.java
Import java.lang.reflect.*; class Instancia { public static void main (String[] args) throws Exception { // obtm uma referncia classe Class classe = Class.forName ("java.math.BigDecimal"); // obtm uma referncia a um construtor para a classe Class[] tiposConstrutor = { String.class }; Constructor ctor = classe.getConstructor (tiposConstrutor); Object[] argsConstrutor = { "120.5" }; Object obj = ctor.newInstance (argsConstrutor); // continua...
Exemplo: Instancia.java
// continuao... // obtm uma referncia ao mtodo toString da instncia Class[] tiposMetodo = { Object.class }; Method metodo = classe.getMethod ("equals", tiposMetodo); //Object[] argsMetodo = { new BigDecimal (args[0]) }; Object[] argsMetodo = { new java.math.BigDecimal ("120.5") }; Object result = metodo.invoke (obj, argsMetodo); // exibe o resultado System.out.println ("O resultado foi " + result); } }
6. Metodologias OO
UML no metodologia! As Metodologias modernas so interativas, evitando a diviso do projeto em etapas estanques e rgidas Anlise, Projeto, Codificao e Testes so realizados de maneira incrementalmente para cada parte do sistema, de modo a obter feedback do usurio o mais cedo possvel
Classes aninhadas e annimas Java e cdigo nativo Vrios pacotes padro do Java Pacotes de extenso para Web Services, computao distribuda, Wireless, Web, ... Servidores de aplicao Padres de Projeto Outros tipos de diagramas UML Outras linguagens que geram bytecodes para a JVM
Referncias Recomendadas
Thinking in Java, Bruce Eckel Fundamentos do Desenho Orientado a Objetos com UML, Meilir Page-Jones Java Design, Building Better Apps & Applets, Peter Coad & Mark Mayfield www.xprogramming.com www.agilemodeling.com www.junit.org