Você está na página 1de 186

Programao Orientada a Objetos com

Java

Fernando Lozano Consultor Independente


fernando@lozano.eti.br www.lozano.eti.br Sun Java Certified Programmer IBM Visual Age Certified Associate Developer MCSE - MCSD RHCE - LPICP - SCP

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

Por Que POO?

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

5.1. Excesses 5.2. Pacotes 5.4. Reflexo

6. Metodologia para desenvolvimento OO

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

O programa Uma Conta-corrente Um cliente Uma janela Um boto

Objeto

Assim como as coisas no mundo real, os objetos tem estado e comportamento


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

O usurio Fernando e o usurio Ricardo

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

O estado de um objeto toda a informao que ele carrega


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

O comportamento definido pelos mtodos da classe

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

A classe Funcionrio A classe Carro de Passeio A classe Nota Fiscal

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

Classes em Programas de Computador

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

Objetos, Classes e Instncias

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)

Classes e Instncias no Computador


contaCorrente1 nmero: 12345 saldo: 2.500,00

ContaCorrente saque (valor) deposito (valor) getSaldo()

contaCorrente2 nmero: 11223 saldo: 420,00

Objetos como Caixas-Pretas

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

Objetos como Caixas-Pretas

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

Os arquivos ContaCorrente.java e Caixa.java demonstram como:


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?

Classes Tambm Representam Processos

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

// continuao... public void realiza () { origem.saque (valor); destino.deposito (valor); } }

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

Mtodo de testas para a classe Transferencia

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

Esteja Preparado para o Futuro

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

Quando definir mtodos e quanto definir classes de atividade?


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)

Especializao de Classes no Computador


contaRemunerada1 contaCorrente1 nmero: 12345 saldo: 2.500,00 ContaRemunerada aplicaRendimentos (taxa) ContaCorrente contaRemunerada2 contaCorrente2 nmero: 11223 saldo: 420,00 saque (valor) deposito (valor) getSaldo()

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!

Classes Como Subtipos

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

Herana e Valores Padro

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); } }

Note que desta vez foi fornecida a definio completa da classe!

Identificando Tipos de Classes

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

Refatorar cdigo x Compatibilidade retroativa

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

O valor que pode ser transferido depende de onde feita a transferncia:


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 } }

Discusso: Mtodo Abstrato getLimite x Atributo limite

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

Discusso: Mtodos Abstratos x Sobreposio

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, ...

Classes Abstratas Puras

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)

Equivalncia entre Interfaces e Classes Abstratas

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 (); }

Interfaces e Tipos de Dados

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

As conveses para cima so automticas


Uma subclasse compatvel com a superclasse Uma classe compatvel com as interfaces implementadas

As converses para baixo devem ser explicitadas por meio de casts


Superclasse para subclasse Interface para classe implementadora

Veja adiante o tpico sobre colees

Diagrama de Classes UML

Diagrama de Classes UML


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)

4. Relacionamentos entre Classes


Usar ou no a Herana Coeso e Acoplamento Agregao Delegao Value Objects JavaBeans Colees Camadas da aplicao e o modelo MVC

Cuidado com a Herana!

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

Parmetros de Qualidade do Softwae

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

Defina as classes Operacao, Historico e Extrato, e inclua na interface Conta o mtodo


public Extrato getExtrato (Date dataInicio, Date dataFim)

Extrato tambm uma agregao de Operacao Cada operao de saque ou retirada adiciona uma Operacao ao Histrico agregado Conta

Discusso: Porque ter classes Historico e Extrato?

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

Devemos diferenciar entre dois tipos de classes de coleo:

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

Veja mais adiante o conceito de camadas da aplicao

API de Colees do Java

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

Interfaces de Coleo do Java


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

Atuam sobre elementos individuais da coleo:


Realizam operaes sobre todos os elementos da coleo:


size isEmpty contains add remove iterator

containsAll addAll removeAll clear toArray

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

Adiciona Collection os mtodos


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.

Utilitrios para Colees e Arrays

A classe java.util.Collections fornece mtodos estticos para buscar elementos, ordenar, inverter, embaralhar e outras operaes sobre colees quaisquer

No confundir com a interface java.util.Collection!

A classe java.util.Array contm um mtodos estticos que permitem transformar um array em uma lista para usufriur das funcionalidades em Collections

No confundir com a classe java.lang.Array!

A Interfafe Map

Atuam sobre pares (chave, valor) individuais:


Atuam sobre o conjunto de pares


put (key, value) get (key) remove (key) containsKey (key) containsValue (value) size isEmpty

putAll clear

Geram colees partir dos pares


keySet values entrySet

Como Percorrer um Map

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:

getKey getValue setValue

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); } } }

Nem Sempre Precisamos dos Casts

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.

E para Ordenar pelos Valores?

Acrescentar ao exemplo anterior:


// ordena pelos nomes System.out.println ("Ordenado pelas valores, com chaves..."); List pares = new ArrayList (); pares.addAll (uf.entrySet()); Collections.sort (pares, new ComparaNomes()); // percorre o mapa Iterator it3 = pares.iterator (); while (it3.hasNext ()) { Map.Entry par = (Map.Entry)it3.next (); System.out.println (par.getKey() + "\t" + par.getValue()); }

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)

Value Objects em Java

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

Value Objects e Colees

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

Quais destas classes seriam Value Objects?


CPF ContaCorrente Cliente Produto Aniversrio Peso

Caractersticas Opcionais de Objetos Java

Especificadas por interfaces definidas em java.lang

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

Classes Semnticas, Estruturais e Fundamentais

Exemplo Hipottico

Domnio da Aplicao
gerenciamento (FormDeBusca) e reconhecimento de eventos (FiltroDePesquisa)

Domnio de Negcio

Atividade/Transao (Transferencia), Relacionamento (Fornecedor), Papel (Cliente) ou Atributo (ItemNotaFiscal)

Domnio de Arquitetura Domnio de Base

Interface humana (JFrame), Banco de Dados (Resultset) e Comunicao (URLConnection)

Classes Semnticas (Date), Estruturais (Vector) e Fundamentais (String)

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

MVC no Trs Camadas!

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

Os modelos de Domnios de Classes, MVC ou Trs Camadas (Three-Tier) no so mutuamente excludentes!

5. Outros Recursos OO de Java


Excesses Pacotes Reflexo

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

Onde e Quando capturar Exceptions?

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;

Podemos incluir todo um pacote


include java.util.*

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!

Estrutura de Pacotes para uma Aplicao

Deve seguir a diviso do sistema em mdulos e tambm o conceito de camadas apresentado anteriormente:

com.acme.vendas.base com.acme.vendas.comissao.negocio com.acme.vendas.comissao.gui com.acme.vendas.comissao.web com.acme.vendas.comissao.entidades com.acme.vendas.produtos.negocio ...

Exemplo Simples

Suponha uma organizao para o sistema bancrio


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

Leia classes como classes e interfaces

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

Na execuo temos que indicar o nome completo da classe e no do arquivo *.class


> java banco.conta.ContaCorrente > java banco.investimento.TransacaoAgencia

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

Instanciando uma Classe dado o seu Nome

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, ...

Invocao Dinmica de Mtodos

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

Sugesto de Metologia para Desenvolvimento OO


1. Parta da perspectiva do usurio do seu sistema, e:
a. Identifique as entidades presentes no seu sistema, criando classes informacionais correspondentes a cada uma b. Identifique as atividades, processos, transaes e fluxos de trabalho realizadas pelo sistema, criando classes de atividade para cada um c. As classes definidas nesta etapa no devem realizar nenhum tipo de interao com o usurio!

Sugesto de Metologia para Desenvolvimento OO


2. Ainda sob a perspectiva do usurio:
a. Desenhe as telas, pginas, relatrios e formatos de arquivos ou tabelas, encapsulando cada um em sua prpria classe de visualizao b. Detalhe a interao do usurio com cada tela, pgina, etc, criando classes controladoras para a interao com cada uma

Sugesto de Metologia para Desenvolvimento OO


3. Agora, sob a perspectiva do desenvolvedor:
a. Tome um caso de uso por vez (um tipo de interao entre o usurio e o sistema) b. Revise as definies de classes e interfaces utilizadas por este caso de uso c. Escreva casos de teste automatizados para cada requisito deste caso de uso d. Implemente as classes e mtodos correspondentes a cada requisito e. O caso de uso s est terminado quando todos os testes rodarem ok

O Que No Vimos Ainda...


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

Você também pode gostar