322
.

FJ-11 Java e Orientação a Objetos

  • Upload
    vutu

  • View
    221

  • Download
    1

Embed Size (px)

Citation preview

Page 1: FJ-11 Java e Orientação a Objetos

.

Page 2: FJ-11 Java e Orientação a Objetos
Page 3: FJ-11 Java e Orientação a Objetos

EstaapostiladaCaelumvisaensinardeumamaneiraelegante,mostrandoapenasoqueénecessárioequandoénecessário,nomomentocerto,poupandoo leitordeassuntosquenãocostumamserdeseuinteresseemdeterminadasfasesdoaprendizado.

ACaelumesperaquevocêaproveiteessematerial.Todososcomentários,críticasesugestõesserãomuitobem-vindos.

Essa apostila é constantemente atualizada edisponibilizadano sitedaCaelum.Sempre consulteositeparanovasversõese,aoinvésdeanexaroPDFparaenviaraumamigo,indiqueositeparaqueelepossasemprebaixarasúltimasversões.Vocêpodeconferirocódigodeversãodaapostilalogono naldoíndice.

Baixesempreaversãomaisnovaem:www.caelum.com.br/apostilas

Esse material é parte integrante do treinamento Java e Orientação a Objetos e distribuídogratuitamente exclusivamente pelo site da Caelum. Todos os direitos são reservados à Caelum. Adistribuição, cópia, revenda eutilizaçãoparaministrar treinamentos são absolutamente vedadas.Parausocomercialdestematerial,porfavor,consulteaCaelumpreviamente.

SOBREESTAAPOSTILA

Page 4: FJ-11 Java e Orientação a Objetos

2233

55679

10101112121315151617171819

202023242425

Sumário

1ComoAprenderJava1.1Oqueérealmenteimportante?1.2Sobreosexercícios1.3Tirandodúvidaseindoalém

2OqueéJava2.1Java2.2UmabrevehistóriadoJava2.3MáquinaVirtual2.4Javalento?HotspoteJIT2.5VersõesdoJavaeaconfusãodoJava22.6JVM?JRE?JDK?Oquedevobaixar?2.7OndeusareosobjetivosdoJava2.8Especificaçãoversusimplementação2.9ComooFJ-11estáorganizado2.10Compilandooprimeiroprograma2.11Executandoseuprimeiroprograma2.12Oqueaconteceu?2.13Parasabermais:comoéobytecode?2.14Exercícios:ModificandooHelloWorld2.15Oquepodedarerrado?2.16Umpoucomais...2.17Exercíciosadicionais

3VariáveisprimitivaseControledefluxo3.1Declarandoeusandovariáveis3.2Tiposprimitivosevalores3.3Exercícios:Variáveisetiposprimitivos3.4Discussãoemaula:convençõesdecódigoecódigolegível3.5Castingepromoção

SumárioCaelum

Page 5: FJ-11 Java e Orientação a Objetos

272929303132333335

363638404042434548505254545959

61616466697072747476

7777

3.6Oifeoelse3.7OWhile3.8OFor3.9Controlandoloops3.10Escopodasvariáveis3.11Umblocodentrodooutro3.12Parasabermais3.13Exercícios:Fixaçãodesintaxe3.14Desafios:Fibonacci

4Orientaçãoaobjetosbásica4.1Motivação:problemasdoparadigmaprocedural4.2Criandoumtipo4.3UmaclasseemJava4.4Criandoeusandoumobjeto4.5Métodos4.6Métodoscomretorno4.7Objetossãoacessadosporreferências4.8Ométodotransfere()4.9Continuandocomatributos4.10Parasabermais:UmaFábricadeCarros4.11Umpoucomais...4.12Exercícios:OrientaçãoaObjetos4.13Desafios4.14Fixandooconhecimento

5Modificadoresdeacessoeatributosdeclasse5.1Controlandooacesso5.2Encapsulamento5.3GetterseSetters5.4Construtores5.5Anecessidadedeumconstrutor5.6Atributosdeclasse5.7Umpoucomais...5.8Exercícios:Encapsulamento,construtoresestatic5.9Desafios

6EclipseIDE6.1OEclipse

CaelumSumário

Page 6: FJ-11 Java e Orientação a Objetos

7879818587888992

939394959798

100

102102104106107110111111113120

123123127128129131133133138

139139

6.2ApresentandooEclipse6.3ViewsePerspective6.4Criandoumprojetonovo6.5Criandoomain6.6Executandoomain6.7Pequenostruques6.8Exercícios:Eclipse6.9Discussãoemaula:Refactoring

7Pacotes-Organizandosuasclassesebibliotecas7.1Organização7.2Diretórios7.3Import7.4Acessoaosatributos,construtoresemétodos7.5UsandooEclipsecompacotes7.6Exercícios:Pacotes

8Ferramentas:jarejavadoc8.1Arquivos,bibliotecaseversões8.2GerandooJARpeloEclipse8.3Javadoc8.4GerandooJavadoc8.5Exercícios:JareJavadoc8.6Importandoumjarexterno8.7Exercícios:Importandoumjar8.8Manipulandoacontapelainterfacegráfica8.9Exercícios:Mostrandoosdadosdacontanatela

9Herança,reescritaepolimorfismo9.1Repetindocódigo?9.2Reescritademétodo9.3Invocandoométodoreescrito9.4Polimorfismo9.5Umoutroexemplo9.6Umpoucomais...9.7Exercícios:HerançaePolimorfismo9.8Discussõesemaula:Alternativasaoatributoprotected

10ClassesAbstratas10.1Repetindomaiscódigo?

SumárioCaelum

Page 7: FJ-11 Java e Orientação a Objetos

141142144146146

148148152156157158161162

164164166170171174175176177179179180182182

184184184185186190191194195

10.2Classeabstrata10.3Métodosabstratos10.4Aumentandooexemplo10.5Parasabermais...10.6Exercícios:ClassesAbstratas

11Interfaces11.1Aumentandonossoexemplo11.2Interfaces11.3Dificuldadenoaprendizadodeinterfaces11.4Exemplointeressante:conexõescomobancodedados11.5Exercícios:Interfaces11.6Exercíciosavançadosopcionais11.7Discussão:favoreçacomposiçãoemrelaçãoàherança

12Exceçõesecontroledeerros12.1Motivação12.2Exercícioparacomeçarcomosconceitos12.3ExceçõesdeRuntimemaiscomuns12.4Outrotipodeexceção:CheckedExceptions12.5UmpoucodagrandefamíliaThrowable12.6Maisdeumerro12.7Lançandoexceções12.8Oquecolocardentrodotry?12.9Criandoseuprópriotipodeexceção12.10Parasabermais:finally12.11Exercícios:Exceções12.12Desafios12.13Discussãoemaula:catchethrowsemException

13Opacotejava.lang13.1Pacotejava.lang13.2UmpoucosobreaclasseSystem13.3java.lang.Object13.4Métodosdojava.lang.Object:equalsetoString13.5Exercícios:java.lang.Object13.6java.lang.String13.7Exercícios:java.lang.String13.8Desafio

CaelumSumário

Page 8: FJ-11 Java e Orientação a Objetos

195

197197198199200201204206

207207208212213214217219221222223225227228229229233233

237237238238240242243244245

13.9Discussãoemaula:OquevocêprecisafazeremJava?

14Umpoucodearrays14.1Oproblema14.2Arraysdereferências14.3Percorrendoumaarray14.4PercorrendoumaarraynoJava5.014.5Exercícios:Arrays14.6Umpoucomais...14.7DesafiosOpcionais

15Collectionsframework15.1Arrayssãotrabalhosos,utilizarestruturadedados15.2Listas:java.util.List15.3ListasnoJava5eJava7comGenerics15.4Aimportânciadasinterfacesnascoleções15.5Ordenação:Collections.sort15.6Exercícios:Ordenação15.7Conjunto:java.util.Set15.8Principaisinterfaces:java.util.Collection15.9PercorrendocoleçõesnoJava515.10Parasabermais:Iterandosobrecoleçõescomjava.util.Iterator15.11Mapas-java.util.Map15.12Parasabermais:Properties15.13Parasabermais:EqualseHashCode15.14Parasabermais:Boaspráticas15.15Exercícios:Collections15.16Desafios15.17Parasabermais:Comparators,classesanônimas,Java8eolambda

16Pacotejava.io16.1ConhecendoumaAPI16.2Orientaçãoaobjetosnojava.io16.3InputStream,InputStreamReadereBufferedReader16.4LendoStringsdoteclado16.5Aanalogiaparaaescrita:OutputStream16.6Umamaneiramaisfácil:ScannerePrintStream16.7Umpoucomais...16.8Integereclasseswrappers(box)

SumárioCaelum

Page 9: FJ-11 Java e Orientação a Objetos

245246247249

251251251252252

254254257259260261

264264264265266267268270271273273274

278278280281282282

285285286

16.9AutoboxingnoJava5.016.10Parasabermais:java.lang.Math16.11Exercícios:JavaI/O16.12Discussãoemaula:DesignPatternseoTemplateMethod

17Eagora?17.1Web17.2PraticandoJavaeusandobibliotecas17.3GruposdeUsuários17.4Próximoscursos

18Apêndice-ProgramaçãoConcorrenteeThreads18.1Threads18.2Escalonadoretrocasdecontexto18.3GarbageCollector18.4Exercícios18.5Easclassesanônimas?

19Apêndice-Sockets19.1Motivação:umaAPIqueusaosconceitosaprendidos19.2Protocolo19.3Porta19.4Socket19.5Servidor19.6Cliente19.7Imagemgeral19.8Exercícios:Sockets19.9Desafio:MúltiplosClientes19.10Desafio:broadcastdasmensagens19.11Soluçãodosistemadechat

20Apêndice-Problemascomconcorrência20.1Threadsacessandodadoscompartilhados20.2Controlandooacessoconcorrente20.3VectoreHashtable20.4Umpoucomais...20.5Exercíciosavançadosdeprogramaçãoconcorrenteelocks

21Apêndice-InstalaçãodoJava21.1InstalandonoUbuntueemoutrosLinux21.2NoMacOSX

CaelumSumário

Page 10: FJ-11 Java e Orientação a Objetos

286

291291291294300309309

21.3InstalaçãodoJDKemambienteWindows

22Apêndice-Debugging22.1Oqueédebugar22.2DebugandonoEclipse22.3Perspectivadedebug22.4Debugavançado22.5Profiling22.6ProfilingnoEclipseTPTP

Versão:21.5.22

SumárioCaelum

Page 11: FJ-11 Java e Orientação a Objetos

.

Page 12: FJ-11 Java e Orientação a Objetos

CAPÍTULO1

"Buscouminstantefelizquejustifiqueminhaexistência"--FiodórDostoiévski

Muitoslivros,aopassardoscapítulos,mencionamtodososdetalhesdalinguagemjuntamentecomseus princípios básicos. Isso acaba criando muita confusão, em especial porque o estudante nãoconseguedistinguirexatamenteoqueéprimordialaprenderno início,daquiloquepodeserestudadomaisadiante.

Seumaclasseabstratadeveounãoteraomenosummétodoabstrato,seoifsóaceitaargumentosbooleanosetodososdetalhessobreclassesinternas,realmentenãodevemsetornarpreocupaçõesparaaquelecujoobjetivoprimárioéaprenderJava.Essetipodeinformaçãoseráadquiridacomotempo,enãoénecessárionoinício.

Nestecurso,separamosessasinformaçõesemquadrosespeciais, jáquesãoinformaçõesextras.Ouentão, apenas citamos num exercício e deixamos para o leitor procurar informações se for de seuinteresse.

Porfim,faltamencionaralgosobreaprática,quedevesertratadaseriamente:todososexercíciossãomuito importantes e os desafios podem ser feitos quando o curso terminar. De qualquer maneirarecomendamosaosalunosestudarememcasa,epraticarembastantecódigoevariações.

OCURSO

ParaaquelesqueestãofazendoocursoJavaeOrientaçãoaObjetos,recomendamosestudarememcasaaquiloquefoivistoduranteaaula,tentandoresolverosexercíciosopcionaiseosdesafiosapresentados.

COMOAPRENDERJAVA

1.1OQUEÉREALMENTEIMPORTANTE?

.

Page 13: FJ-11 Java e Orientação a Objetos

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

Os exercícios do curso variam de práticos até pesquisas na Internet, ou mesmo consultas sobreassuntosavançadosemdeterminadostópicosparaincitaracuriosidadedoaprendiznatecnologia.

Existemtambém,emdeterminadoscapítulos,umasériededesafios.Eles focammaisnoproblemacomputacionalquenalinguagem,porémsãoumaexcelenteformadetreinarasintaxee,principalmente,familiarizar o aluno com a biblioteca padrão Java, alémde proporcionar umganhona velocidade dedesenvolvimento.

Para tirar dúvidas dos exercícios, ou de Java em geral, recomendamos o fórum do GUJ(http://www.guj.com.br/), onde sua dúvida será respondida prontamente. O GUJ foi fundado pordesenvolvedoresdaCaelum,ehojecontacommaisdeummilhãodemensagens.

Foraisso,sinta-seàvontadeparaentraremcontatocomseuinstrutorparatirartodasasdúvidasquesurgiremduranteocurso.

Seoquevocêestábuscandosãolivrosdeapoio,sugerimosconheceraeditoraCasadoCódigo:

http://www.casadocodigo.com.br

ACaelumfornecemuitosoutroscursosJava,comdestaqueparaoFJ-21quetrazaaplicaçãodoJavanaweb.

http://www.caelum.com.br/

Há tambémcursosonlineque vão te ajudar a ir além, commuita interação comos instrutores, a

JáconheceoscursosonlineAlura?

1.2SOBREOSEXERCÍCIOS

1.3TIRANDODÚVIDASEINDOALÉM

.

Page 14: FJ-11 Java e Orientação a Objetos

Alura:

http://www.alura.com.br/

.

Page 15: FJ-11 Java e Orientação a Objetos

CAPÍTULO2

"Computadoressãoinúteis,elesapenasdãorespostas"--Picasso

ChegouahoraderesponderasperguntasmaisbásicassobreJava.Aotérminodessecapítulo,vocêserácapazde:

responderoqueéJava;mostrarasvantagensedesvantagensdoJava;entenderbemoconceitodemáquinavirtual;compilareexecutarumprogramasimples.

Entender um pouco da história da plataforma Java é essencial para enxergar os motivos que alevaramaosucesso.

Quaiseramosseusmaioresproblemasquandoprogramavanadécadade1990?

ponteiros?gerenciamentodememória?organização? falta debibliotecas? ter de reescrever parte docódigoaomudardesistemaoperacional?custofinanceirodeusaratecnologia?

AlinguagemJavaresolvebemessesproblemas,queatéentãoapareciamcomfrequêncianasoutraslinguagens. Alguns desses problemas foram particularmente atacados porque uma das grandesmotivações para a criação da plataforma Java era de que essa linguagem fosse usada em pequenosdispositivos, como tvs, videocassetes, aspiradores, liquidificadores e outros.Apesar disso a linguagemteveseulançamentofocadonousoemclientesweb(browsers)pararodarpequenasaplicações(applets).Hoje emdia essenãoéograndemercadodo Java: apesarde ter sido idealizadocomumpropósito elançadocomoutro,oJavaganhoudestaquenoladodoservidor.

O Java foi criado pela antiga Sun Microsystems e mantida através de um comitê(http://www.jcp.org). Seu site principal era o java.sun.com, e java.com um site mais institucional,voltadoaoconsumidordeprodutoseusuáriosleigos,nãodesenvolvedores.ComacompradaSunpelaOracle em 2009,muitasURLs e nomes tem sido trocados para refletir amarca daOracle. A páginaprincipaldoJavaé:http://www.oracle.com/technetwork/java/

No Brasil, diversos grupos de usuários se formaram para tentar disseminar o conhecimento da

OQUEÉJAVA

2.1JAVA

.

Page 16: FJ-11 Java e Orientação a Objetos

linguagem.UmdeleséoGUJ(http://www.guj.com.br),umacomunidadevirtualcomartigos,tutoriaisefórumparatirardúvidas,omaioremlínguaportuguesacommaisdecemmilusuáriose1milhãodemensagens.

Encorajamostodososalunosausarmuitoosfórunsdomesmo,poiséumadasmelhoresmaneirasparaacharsoluçõesparapequenosproblemasqueacontecemcomgrandefrequência.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

ASuncriouumtime(conhecidocomoGreenTeam)paradesenvolver inovações tecnológicasem1992.EssetimefoilideradoporJamesGosling,consideradoopaidoJava.Otimevoltoucomaideiadecriaruminterpretador(jáeraumamáquinavirtual,veremosoqueéissomaisafrente)parapequenosdispositivos,facilitandoareescritadesoftwareparaaparelhoseletrônicos,comovídeocassete,televisãoeaparelhosdeTVacabo.

Aideianãodeucerto.Tentaramfechardiversoscontratoscomgrandes fabricantesdeeletrônicos,comoPanasonic,masnãohouveêxitodevidoaoconflitode interesses e custos.Hoje, sabemosqueoJavadominaomercadodeaplicaçõesparacelularescommaisde2.5bilhõesdedispositivoscompatíveis,porémem1994aindaeramuitocedoparaisso.

Com o advento da web, a Sun percebeu que poderia utilizar a ideia criada em 1992 para rodarpequenasaplicaçõesdentrodobrowser.Asemelhançaeraquenainternethaviaumagrandequantidadede sistemasoperacionais ebrowsers, e com isso seria grandevantagempoderprogramarnumaúnicalinguagem, independente da plataforma. Foi aí que o Java 1.0 foi lançado: focado em transformar obrowser de apenas um cliente magro (thin client ou terminal burro) em uma aplicação que possa

SaberinglêsémuitoimportanteemTI

2.2UMABREVEHISTÓRIADOJAVA

.

Page 17: FJ-11 Java e Orientação a Objetos

tambémrealizaroperaçõesavançadas,enãoapenasrenderizarhtml.

OsappletsdeixaramdeserofocodaSun,enemaOraclenuncateveinteresse.Écuriosonotarqueatecnologia Java nasceu com um objetivo em mente, foi lançado com outro, mas, no final, decoloumesmonodesenvolvimentodeaplicaçõesdoladodoservidor.Sorte?HáhojeoJavaFX,tentandodarforçaparaoJavanãosónodesktopmascomoaplicaçõesricasnaweb,masmuitosnãoacreditamquehajaespaçoparatal,considerandoodestinodetecnologiascomoAdobeFlexeMicrosoftSilverlight.

VocêpodelerahistóriadalinguagemJavaem:http://www.java.com/en/javahistory/

Eumvídeointeressante:http://tinyurl.com/histjava

Em2009aOraclecomprouaSun,fortalecendoamarca.AOraclesemprefoi,juntocomaIBM,umadasempresasquemaisinvestiramefizeramnegóciosatravésdousodaplataformaJava.Em2014surgeaversãoJava8commudançasinteressantesnalinguagem.

Em uma linguagem de programação como C e Pascal, temos a seguinte situação quando vamoscompilarumprograma:

O código fonte é compilado para código de máquina específico de uma plataforma e sistemaoperacional.Muitasvezesoprópriocódigofonteédesenvolvidovisandoumaúnicaplataforma!

Esse código executável (binário) resultante será executado pelo sistema operacional e, por essemotivo,eledevesaberconversarcomosistemaoperacionalemquestão.

Istoé, temosumcódigoexecutávelparacadasistemaoperacional.Énecessáriocompilarumavez

2.3MÁQUINAVIRTUAL

.

Page 18: FJ-11 Java e Orientação a Objetos

paraWindows,outraparaoLinux,eassimpordiante,casoagentequeiraqueessenossosoftwarepossaserutilizadoemváriasplataformas.EsseéocasodeaplicativoscomooOpenOffice,Firefoxeoutros.

Como foi dito anteriormente, na maioria das vezes, a sua aplicação se utiliza das bibliotecas dosistemaoperacional,como,porexemplo,adeinterfacegráficaparadesenharas"telas".AbibliotecadeinterfacegráficadoWindowsébemdiferentedasdoLinux:comocriarentãoumaaplicaçãoquerodedeformaparecidanosdoissistemasoperacionais?

Precisamosreescreverummesmopedaçodaaplicaçãoparadiferentessistemasoperacionais,jáqueelesnãosãocompatíveis.

Já o Java utiliza do conceito de máquina virtual, onde existe, entre o sistema operacional e aaplicação, uma camada extra responsável por "traduzir" -mas não apenas isso - o que sua aplicaçãodesejafazerparaasrespectivaschamadasdosistemaoperacionalondeelaestárodandonomomento:

Dessaforma,amaneiracomaqualvocêabreumajanelanoLinuxounoWindowséamesma:vocêganhaindependênciadesistemaoperacional.Ou,melhorainda,independênciadeplataformaemgeral:nãoéprecisosepreocuparemqualsistemaoperacionalsuaaplicaçãoestárodando,nememquetipodemáquina,configurações,etc.

Reparequeumamáquinavirtualéumconceitobemmaisamploqueodeuminterpretador.Comoopróprio nome diz, uma máquina virtual é como um "computador de mentira": tem tudo que umcomputador tem. Em outras palavras, ela é responsável por gerenciar memória, threads, a pilha deexecução,etc.

Sua aplicação roda sem nenhum envolvimento com o sistema operacional! Sempre conversandoapenascomaJavaVirtualMachine(JVM).

Essacaracterísticaéinteressante:comotudopassapelaJVM,elapodetirarmétricas,decidirondeémelhoralocaramemória,entreoutros.UmaJVMisolatotalmenteaaplicaçãodosistemaoperacional.SeumaJVMterminaabruptamente,sóasaplicaçõesqueestavamrodandonelairãoterminar:issonãoafetaráoutrasJVMsqueestejamrodandonomesmocomputador,nemafetaráosistemaoperacional.

.

Page 19: FJ-11 Java e Orientação a Objetos

Essacamadadeisolamentotambéméinteressantequandopensamosemumservidorquenãopodesesujeitararodarcódigoquepossainterferirnaboaexecuçãodeoutrasaplicações.

Essa camada, a máquina virtual, não entende código java, ela entende um código de máquinaespecífico.Essecódigodemáquinaégeradoporumcompiladorjava,comoojavac,eéconhecidopor"bytecode",poisexistemmenosde256códigosdeoperaçãodessalinguagem,ecada"opcode"gastaumbyte.OcompiladorJavageraessebytecodeque,diferentedaslinguagenssemmáquinavirtual,vaiservirparadiferentessistemasoperacionais,jáqueelevaiser"traduzido"pelaJVM.

WRITEONCE,RUNANYWHERE

EsseeraumsloganqueaSunusavaparaoJava,jáquevocênãoprecisareescreverpartesdasuaaplicaçãotodavezquequisermudardesistemaoperacional.

HotspotéatecnologiaqueaJVMutilizaparadetectarpontosquentesdasuaaplicação:códigoqueéexecutadomuito,provavelmentedentrodeumoumaisloops.QuandoaJVMjulgarnecessário,elavaicompilar estes códigos para instruções realmente nativas da plataforma, tendo em vista que isso vaiprovavelmentemelhoraraperformancedasuaaplicação.EssecompiladoréoJIT:JustinTimeCompiler,ocompiladorqueaparece"bemnahora"quevocêprecisa.

Você pode pensar então: porque a JVM não compila tudo antes de executar a aplicação? É queteoricamentecompilardinamicamente,amedidadonecessário,podegerarumaperformancemelhor.Omotivoésimples:imagineum.exegeradopeloVisualBasic,pelogccoupeloDelphi;eleéestático.Elejáfoiotimizadobaseadoemheurísticas,ocompiladorpodetertomadoumadecisãonãotãoboa.

Já a JVM, por estar compilando dinamicamente durante a execução, pode perceber que umdeterminadocódigonãoestácomperformanceadequadaeotimizarmaisumpoucoaqueletrecho,ouaindamudaraestratégiadeotimização.ÉporessemotivoqueasJVMsmaisrecentesemalgunscasoschegamaganhardecódigosCcompiladoscomoGCC3.x.

2.4JAVALENTO?HOTSPOTEJIT

.

Page 20: FJ-11 Java e Orientação a Objetos

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

Java1.0e1.1sãoasversõesmuitoantigasdoJava,mas já traziambibliotecas importantescomooJDBCeojava.io.

Com o Java 1.2 houve um aumento grande no tamanho da API, e foi nesse momento em quetrocaramanomenclaturadeJavaparaJava2,comoobjetivodediminuiraconfusãoquehaviaentreJavaeJavascript.Mas lembre-se,nãoháversão"Java2.0",o2 foi incorporadoaonome, tornando-seJava21.2.

DepoisvieramoJava21.3e1.4,eoJava1.5passouasechamarJava5, tantoporumaquestãodemarketingeporquemudançassignificativasnalinguagemforamincluídas.Énessemomentoqueo"2"donomeJavadesaparece.Reparequeparafinsdedesenvolvimento,oJava5aindaéreferidocomoJava1.5.

HojeaúltimaversãodisponíveldoJavaéa8.

OquegostaríamosdebaixarnositedaOracle?

JVM=apenasavirtualmachine,essedownloadnãoexiste,elasemprevemacompanhada.JRE = Java Runtime Environment, ambiente de execução Java, formado pela JVM ebibliotecas, tudoquevocêprecisaparaexecutarumaaplicação Java.Masnósprecisamosdemais.JDK=JavaDevelopmentKit:Nós,desenvolvedores,faremosodownloaddoJDKdoJavaSE

AprendasedivertindonaAluraStart!

2.5VERSÕESDOJAVAEACONFUSÃODOJAVA2

2.6JVM?JRE?JDK?OQUEDEVOBAIXAR?

.

Page 21: FJ-11 Java e Orientação a Objetos

(StandardEdition).EleéformadopelaJREsomadoaferramentas,comoocompilador.

Tanto o JRE e o JDK podem ser baixados do site http://www.oracle.com/technetwork/java/. Paraencontrá-los,acesseolinkJavaSEdentrodostopdownloads.ConsulteoapêndicedeinstalaçãodoJDKparamaioresdetalhes.

Nodecorrerdocurso,vocêpodeacharqueoJavatemmenorprodutividadequandocomparadacomalinguagemquevocêestáacostumado.

ÉprecisoficarclaroqueapremissadoJavanãoéadecriarsistemaspequenos,ondetemosumoudoisdesenvolvedores,maisrapidamentequelinguagenscomophp,perl,eoutras.

Ofocodaplataformaéoutro:aplicaçõesdemédioagrandeporte,ondeotimededesenvolvedorestemváriaspessoasesemprepodeviramudarecrescer.NãotenhadúvidasquecriaraprimeiraversãodeumaaplicaçãousandoJava,mesmoutilizandoIDEseferramentaspoderosas,serámaistrabalhosoquemuitas linguagens script ou de alta produtividade. Porém, comuma linguagemorientada a objetos emaduracomooJava,seráextremamentemaisfácilerápidofazeralteraçõesnosistema,desdequevocêsigaasboaspráticaserecomendaçõessobredesignorientadoaobjetos.

Alémdisso, a quantidade enormede bibliotecas gratuitas para realizar osmais diversos trabalhos(tais como relatórios, gráficos, sistemas de busca, geração de código de barra,manipulação deXML,tocadores de vídeo, manipuladores de texto, persistência transparente, impressão, etc) é um pontofortíssimoparaadoçãodoJava:vocêpodecriarumaaplicaçãosofisticada,usandodiversosrecursos,semprecisarcomprarumcomponenteespecífico,quecostumasercaro.OecossistemadoJavaéenorme.

Cada linguagemtemseuespaçoeseumelhoruso.OusodoJavaé interessanteemaplicaçõesquevirãoacrescer,emquealegibilidadedocódigoéimportante,ondetemosmuitaconectividadeesehámuitas plataformas (ambientes e sistemas operacionais) heterogêneas (Linux,Unix,OSX eWindowsmisturados).

VocêpodeverissopelaquantidadeenormedeofertasdeempregoprocurandodesenvolvedoresJavaparatrabalharcomsistemaswebeaplicaçõesdeintegraçãonoservidor.

Apesardisto,aSunempenhou-seemtentarpopularizarousodoJavaemaplicaçõesdesktop,mesmocom o fracomarketshare do Swing/AWT/SWT em relação às tecnologias concorrentes (em especialMicrosoft.NET).AatualtentativaéoJavaFX,ondeaOracleteminvestidobastante.

2.7ONDEUSAREOSOBJETIVOSDOJAVA

.

Page 22: FJ-11 Java e Orientação a Objetos

Conheça a Casa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Com a curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Outro ponto importante: quando falamos de Java Virtual Machine, estamos falando de umaespecificação.EladizcomoobytecodedeveserinterpretadopelaJVM.QuandofazemosodownloadnositedaOracle,oquevemjuntoéaOracleJVM.Emoutraspalavras,existemoutrasJVMsdisponíveis,comoaJRockitdaBEA(tambémadquiridapelaOracle),aJ9daIBM,entreoutras.

Esseéoutroponto interessanteparaasempresas.CasonãoestejamgostandodealgumdetalhedaJVMdaOracleouprefiramtrabalharcomoutraempresa,pagandoporsuporte,elaspodemtrocardeJVMcomagarantiaabsolutadequetodoosistemacontinuaráfuncionando.IssoporquetodaJVMdeveser certificada pela Oracle, provando a sua compatibilidade. Não há nem necessidade de recompilarnenhumadesuasclasses.

Além de independência de hardware e sistema operacional, você tem a independência de vendor(fabricante):graçasaideiadaJVMserumaespecificaçãoenãoumsoftware.

Javaéumalinguagemsimples:existempoucasregras,muitobemdefinidas.

Porém quebrar o paradigma procedural para mergulhar na orientação a objetos não é simples.QuebraroparadigmaeganharfluênciacomalinguagemeAPIsãoosobjetivosdoFJ-11.

Ocomeçopode serumpouco frustrante: exemplos simples, controlede fluxocomoif,for,whileecriaçãodepequenosprogramasquenemaomenoscaptamdadosdoteclado.Apesardeissotudosernecessário,ésónos20%finaisdocursoqueutilizaremosbibliotecaspara,nofinal,criarmosumchat entre duas máquinas que transferem Strings por TCP/IP. Neste ponto, teremos tudo que énecessárioparaentendercompletamentecomoaAPIfunciona,quemestendequem,eoporquê.

Seuslivrosdetecnologiaparecemdoséculopassado?

2.8ESPECIFICAÇÃOVERSUSIMPLEMENTAÇÃO

2.9COMOOFJ-11ESTÁORGANIZADO

.

Page 23: FJ-11 Java e Orientação a Objetos

Depois desse capítulo no qual o Java, a JVM e primeiros conceitos são passados, veremos oscomandosbásicosdojavaparacontroledefluxoeutilizaçãodevariáveisdotipoprimitivo.Criaremosclassespara testar essepequenoaprendizado, semsaberexatamenteoqueéuma classe. Issodificultaaindamais a curva de aprendizado, porém cada conceito será introduzido nomomento consideradomaisapropriadopelosinstrutores.

Passamos para o capítulo de orientação a objetos básico,mostrando os problemas do paradigmaprocedural e a necessidade de algo diferente para resolvê-los. Atributos, métodos, variáveis do tiporeferênciaeoutros.

Os capítulos de modificadores de acesso, herança, classes abstratas e interfaces demonstram oconceitofundamentalqueocursoquerpassar:encapsule,exponhaomínimodesuasclasses,foquenoque elas fazem, no relacionamento entre elas. Com um bom design, a codificação fica fácil e amodificaçãoeexpansãodosistematambém.

No decorrer desses capítulos, o Eclipse é introduzido de forma natural, evitando-se ao máximowizardsemenus,priorizandomostraroschamadoscodeassistsequickfixes.IssofazcomqueoEclipsetrabalhedeformasimbióticacomodesenvolvedor,semseintrometer,semfazermágica.

Pacotes,javadoc,jarsejava.langapresentamosúltimosconceitosfundamentaisdoJava,dandotodaafundaçãopara,então,passarmosaestudarasprincipaisemaisutilizadasAPIsdoJavaSE.

AsAPIsestudadasserãojava.utilejava.io.Todaselasusameabusamdosconceitosvistosnodecorrerdocurso,ajudandoasedimentá-los.Juntamente,temososconceitosbásicosdousodeThreads,eosproblemaseperigosdaprogramaçãoconcorrentequandodadossãocompartilhados.

Resumindo: o objetivo do curso é apresentar o Java ao mesmo tempo que os fundamentos daorientaçãoaobjetossãointroduzidos.Bateremosmuitonopontodedizerqueoimportanteécomoasclasses se relacionamequal éopapelde cadauma, enão emcomoelas realizamas suasobrigações.Programevoltadoàinterface,enãoàimplementação.

Vamosparaonossoprimeirocódigo!Oprogramaqueimprimeumalinhasimples.

Paramostrarumalinha,podemosfazer:

System.out.println("MinhaprimeiraaplicaçãoJava!");

Masessecódigonãoseráaceitopelocompiladorjava.OJavaéumalinguagembastanteburocrática,eprecisademaisdoqueissoparainiciarumaexecução.Veremososdetalheseosporquêsduranteospróximoscapítulos.Omínimoqueprecisaríamosescreveréalgocomo:

classMeuPrograma{publicstaticvoidmain(String[]args){

2.10COMPILANDOOPRIMEIROPROGRAMA

.

Page 24: FJ-11 Java e Orientação a Objetos

System.out.println("MinhaprimeiraaplicaçãoJava!");}}

NOTAÇÃO

Todososcódigosapresentadosnaapostilaestãoformatadoscomrecursosvisuaisparaauxiliaraleituraecompreensãodosmesmos.Quandofordigitaroscódigosnocomputador,trateoscódigoscomotextosimples.

Anumeraçãodaslinhasnãofazpartedocódigoenãodeveserdigitada;éapenasumrecursodidático.OJavaécasesensitive:tomecuidadocommaiúsculaseminúsculas.

Apósdigitarocódigoacima,grave-ocomoMeuPrograma.javaemalgumdiretório.Paracompilar,você deve pedir para que o compilador de Java da Oracle, chamado javac , gere o bytecodecorrespondenteaoseucódigoJava.

Depoisdecompilar,obytecodefoigerado.Quandoosistemaoperacionallistarosarquivoscontidosnodiretórioatual,vocêpoderáverqueumarquivo.classfoigerado,comomesmonomedasuaclasseJava.

ASSUSTADOCOMOCÓDIGO?

ParaquemjátemumaexperiênciacomJava,esseprimeirocódigoémuitosimples.Mas,seéseu primeiro código em Java, pode ser umpouco traumatizante.Nãodeixe de ler o prefácio docurso, que deixará você mais tranquilo em relação a curva de aprendizado da linguagem,conhecendocomoocursoestáorganizado.

.

Page 25: FJ-11 Java e Orientação a Objetos

PRECISOSEMPREPROGRAMARUSANDOONOTEPADOUSIMILAR?

NãoénecessáriodigitarsempreseuprogramaemumsimplesaplicativocomooNotepad.Vocêpodeusarumeditorquetenhasyntaxhighlightingeoutrosbenefícios.

Mas,nocomeço,éinteressantevocêusaralgoquenãopossuaferramentas,paraquevocêpossaseacostumarcomoserrosdecompilação,sintaxeeoutros.Depoisdocapítulodepolimorfismoeherança sugerimos a utilização do Eclipse (http://www.eclipse.org), a IDE líder no mercado, egratuita.ExisteumcapítuloaparteparaousodoEclipsenestaapostila.

NoLinux,recomendamosousodogedit,kateevi.NoWindows,vocêpodeusaroNotepad++ouoTextPad.NoMac,TextMate,Sublimeoumesmoovi.

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design, Infra,Front-Ende

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Osprocedimentosparaexecutarseuprogramasãomuitosimples.OjavacéocompiladorJava,eojavaéoresponsávelporinvocaramáquinavirtualparainterpretaroseuprograma.

Aoexecutar,podeserqueaacentuaçãoresultantesaiaerradadevidoaalgumasconfiguraçõesquedeixamosdefazer.Semproblemas.

Agoraéamelhorhoraderespirarmaistecnologia!

2.11EXECUTANDOSEUPRIMEIROPROGRAMA

2.12OQUEACONTECEU?

.

Page 26: FJ-11 Java e Orientação a Objetos

classMeuPrograma{publicstaticvoidmain(String[]args){

//miolodoprogramacomeçaaqui!System.out.println("MinhaprimeiraaplicaçãoJava!!");//fimdomiolodoprograma

}}

Omiolodoprogramaéoqueseráexecutadoquandochamamosamáquinavirtual.Porenquanto,todasaslinhasanteriores,ondeháadeclaraçãodeumaclasseeadeummétodo,nãoimportamparanósnessemomento.Masdevemossaberque todaaplicação Javacomeçaporumpontodeentrada,eestepontodeentradaéométodomain.

Aindanãosabemosoqueémétodo,masveremosnocapítulo4.Atélá,nãosepreocupecomessasdeclarações.Semprequeumexercícioforfeito,ocódigoquenosimportasempreestaránessemiolo.

Nocasodonossocódigo,alinhadoSystem.out.printlnfazcomqueoconteúdoentreaspassejacolocadonatela.

OMeuPrograma.classgeradonãoélegívelporsereshumanos(nãoquesejaimpossível).Eleestáescritonoformatoqueavirtualmachinesabeentenderequefoiespecificadoqueelaentendesse.

É como um assembly, escrito para esta máquina em específico. Podemos ler os mnemônicosutilizandoaferramentajavapqueacompanhaoJDK:

javap-cMeuPrograma

Easaída:

MeuPrograma();Code:0:aload_01:invokespecial#1;//Methodjava/lang/Object."<init>":()V4:return

publicstaticvoidmain(java.lang.String[]);Code:0:getstatic#2;//Fieldjava/lang/System.out:Ljava/io/PrintStream;3:ldc#3;//StringMinhaprimeiraaplicaçãoJava!!5:invokevirtual#4;//Methodjava/io/PrintStream.println:(Ljava/lang/String;)V8:return

}

Éocódigoacima,queaJVMsabeler.Éo"códigodemáquina",damáquinavirtual.

Um bytecode pode ser revertido para o .java original (com perda de comentários e nomes de

2.13PARASABERMAIS:COMOÉOBYTECODE?

.

Page 27: FJ-11 Java e Orientação a Objetos

variáveislocais).Casoseusoftwarevávirarumprodutodeprateleira,éfundamentalusarumofuscadorno seu código, que vai embaralhar classes, métodos e um monte de outros recursos (indicamos ohttp://proguard.sf.net).

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelum eobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

1. Altereseuprogramaparaimprimirumamensagemdiferente.2. AltereseuprogramaparaimprimirduaslinhasdetextousandoduaslinhasdecódigoSystem.out.3. Sabendoqueoscaracteres\n representamumaquebrade linhas, imprimaduas linhasde texto

usandoumaúnicalinhadecódigoSystem.out.

Muitos errospodemocorrernomomentoquevocê rodar seuprimeirocódigo.Vamosveralgunsdeles:

Código:

classX{publicstaticvoidmain(String[]args){System.out.println("Faltapontoevírgula")}}

Erro:

X.java:4:';'expected}^1error

Esseéoerrodecompilaçãomaiscomum:aqueleondeumpontoevírgula foraesquecido.Repare

EditoraCasadoCódigocomlivrosdeumaformadiferente

2.14EXERCÍCIOS:MODIFICANDOOHELLOWORLD

2.15OQUEPODEDARERRADO?

.

Page 28: FJ-11 Java e Orientação a Objetos

queocompiladoréexplícitoemdizerquealinha4éacomproblemas.Outroserrosdecompilaçãopodemocorrersevocêescreveupalavraschaves(asquecolocamosemnegrito)emmaiúsculas,esqueceudeabrirefecharas{},etc.

Duranteaexecução,outroserrospodemaparecer:

SevocêdeclararaclassecomoX,compilá-laedepoistentarusá-lacomoxminúsculo(javax),oJavateavisa:

Exceptioninthread"main"java.lang.NoClassDefFoundError:X(wrongname:x)

Se tentar acessar uma classe no diretório ou classpath errado, ou se o nome estiver errado,ocorreráoseguinteerro:

Exceptioninthread"main"java.lang.NoClassDefFoundError:X

SeesquecerdecolocarstaticouoargumentoString[]argsnométodomain:

Exceptioninthread"main"java.lang.NoSuchMethodError:main

Porexemplo:

classX{publicvoidmain(String[]args){System.out.println("Faltouostatic,tenteexecutar!");}}

Senãocolocarométodomaincomopublic:

Mainmethodnotpublic.

Porexemplo:

classX{staticvoidmain(String[]args){System.out.println("Faltouopublic");}}

Procureumcolega,oualgumconhecido,queestejaemumprojetoJava.DescubraporqueJavafoiescolhidocomotecnologia.OqueéimportanteparaesseprojetoeoqueacaboufazendodoJavaamelhorescolha?

2.16UMPOUCOMAIS...

.

Page 29: FJ-11 Java e Orientação a Objetos

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

1. UmarquivofonteJavadevesempreteraextensão.java,ouocompiladororejeitará.Alémdisso,existemalgumasoutras regrasnahoradedar onomedeumarquivo Java.Experimente gravar ocódigodestecapítulocomOutroNome.javaoualgosimilar.

Compileeverifiqueonomedoarquivogerado.Comoexecutarasuaaplicação?

JáconheceoscursosonlineAlura?

2.17EXERCÍCIOSADICIONAIS

.

Page 30: FJ-11 Java e Orientação a Objetos

CAPÍTULO3

"Péssimaideia,adequenãosepodemudar"--Montaigne

AprenderemosatrabalharcomosseguintesrecursosdalinguagemJava:

declaração,atribuiçãodevalores,castingecomparaçãodevariáveis;controledefluxoatravésdeifeelse;instruçõesdelaçoforewhile,controledefluxocombreakecontinue.

Dentrodeumbloco,podemosdeclararvariáveiseusá-las.EmJava,todavariáveltemumtipoquenãopodesermudado,umavezquedeclarado:

tipoDaVariavelnomeDaVariavel;

Porexemplo,épossívelterumaidadequeguardaumnúmerointeiro:

intidade;

Comisso,vocêdeclaraavariávelidade, quepassa a existir apartirdaquela linha.Ela édo tipoint,queguardaumnúmerointeiro.Apartirdaí,vocêpodeusá-la,primeiramenteatribuindovalores.

Alinhaaseguiréatraduçãode:"idadedevevalerquinze".

idade=15;

COMENTÁRIOSEMJAVA

Parafazerumcomentárioemjava,vocêpodeusaro//paracomentaratéofinaldalinha,ouentãousaro/**/paracomentaroqueestiverentreeles.

/*comentáriodaqui,ateaqui*/

//umalinhadecomentáriosobreaidadeintidade;

VARIÁVEISPRIMITIVASECONTROLEDEFLUXO

3.1DECLARANDOEUSANDOVARIÁVEIS

.

Page 31: FJ-11 Java e Orientação a Objetos

Além de atribuir, você pode utilizar esse valor. O código a seguir declara novamente a variávelidadecomvalor15eimprimeseuvalornasaídapadrãoatravésdachamadaaSystem.out.println.

//declaraaidadeintidade;idade=15;

//imprimeaidadeSystem.out.println(idade);

Por fim, podemos utilizar o valor de uma variável para algum outro propósito, como alterar oudefinirumasegundavariável.OcódigoaseguircriaumavariávelchamadaidadeNoAnoQueVem comvalordeidademaisum.

//calculaaidadenoanoseguinteintidadeNoAnoQueVem;idadeNoAnoQueVem=idade+1;

Nomesmomomentoquevocêdeclaraumavariável,tambémépossívelinicializá-laporpraticidade:

intidade=15;

Vocêpodeusarosoperadores+,-,/eparaoperarcomnúmeros,sendoelesresponsáveispelaadição,subtração, divisão e multiplicação, respectivamente. Além desses operadores básicos, há o operador %(módulo)quenadamaiséqueo*restodeumadivisãointeira.Vejaalgunsexemplos:

intquatro=2+2;inttres=5-2;

intoito=4*2;intdezesseis=64/4;

intum=5%2;//5divididopor2dá2etemresto1;//ooperador%pegaorestodadivisãointeira

.

Page 32: FJ-11 Java e Orientação a Objetos

COMORODARESSESCÓDIGOS?

Vocêdevecolocaressestrechosdecódigodentrodoblocomainquevimosnocapítuloanterior.Isto é, isso deve ficar nomiolo doprograma.Use bastanteSystem.out.println, dessa formavocêpodeveralgumresultado,casocontrário,aoexecutaraaplicação,nadaaparecerá.

Porexemplo,paraimprimiraidade eaidadeNoAnoQueVem podemos escrever o seguinteprogramadeexemplo:

classTestaIdade{

publicstaticvoidmain(String[]args){//imprimeaidadeintidade=20;System.out.println(idade);

//geraumaidadenoanoseguinteintidadeNoAnoQueVem;idadeNoAnoQueVem=idade+1;

//imprimeaidadeSystem.out.println(idadeNoAnoQueVem);}}

Representarnúmerosinteiroséfácil,mascomoguardarvaloresreais,taiscomofraçõesdenúmerosinteiroseoutros?Outrotipodevariávelmuitoutilizadoéodouble,quearmazenaumnúmerocompontoflutuante(equetambémpodearmazenarumnúmerointeiro).

doublepi=3.14;doublex=5*10;

O tipo boolean armazena um valor verdadeiro ou falso, e só: nada de números, palavras ouendereços,comoemalgumasoutraslinguagens.

booleanverdade=true;

trueefalse sãopalavras reservadasdo Java.É comumqueumboolean seja determinadoatravés de uma expressãobooleana, isto é, um trecho de código que retorna um booleano, como oexemplo:

intidade=30;booleanmenorDeIdade=idade<18;

Otipocharguardaum,eapenasum,caractere.Essecaracteredeveestarentreaspassimples.Nãoseesqueçadessasduascaracterísticasdeumavariáveldotipochar!Porexemplo,elanãopodeguardarumcódigocomo''poisovazionãoéumcaractere!

charletra='a';System.out.println(letra);

.

Page 33: FJ-11 Java e Orientação a Objetos

Variáveisdotipocharsãopoucousadasnodiaadia.VeremosmaisafrenteousodasStrings,queusamosconstantemente,porémestasnãosãodefinidasporumtipoprimitivo.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

EssestiposdevariáveissãotiposprimitivosdoJava:ovalorqueelasguardamsãoorealconteúdodavariável.Quandovocêutilizarooperadordeatribuição=ovalorserácopiado.

inti=5;//irecebeumacópiadovalor5intj=i;//jrecebeumacópiadovalordeii=i+1;//ivira6,jcontinua5

Aqui,ificacomovalorde6.Masej?Nasegundalinha,jestávalendo5.Quandoipassaavaler6,seráquejtambémmudadevalor?Não,poisovalordeumtipoprimitivosempreécopiado.

Apesardalinha2fazerj=i,apartirdessemomentoessasvariáveisnãotemrelaçãonenhuma:oqueacontececomuma,nãorefleteemnadacomaoutra.

OUTROSTIPOSPRIMITIVOS

Vimos aqui os tipos primitivos que mais aparecem. O Java tem outros, que são o byte,short,longefloat.

Cada tipo possui características especiais que, para um programador avançado, podem fazermuitadiferença.

SaberinglêsémuitoimportanteemTI

3.2TIPOSPRIMITIVOSEVALORES

.

Page 34: FJ-11 Java e Orientação a Objetos

1. Naempresaondetrabalhamos,hátabelascomoquantofoigastoemcadamês.Parafecharobalançodoprimeirotrimestre,precisamossomarogastototal.Sabendoque,emJaneiro,foramgastos15000reais,emFevereiro,23000reaiseemMarço,17000reais,façaumprogramaquecalculeeimprimaogastototalnotrimestre.Sigaessespassos:

Crie uma classe chamada BalancoTrimestral com um bloco main, como nos exemplosanteriores;Dentrodomain(omiolodoprograma),declareumavariávelinteirachamadagastosJaneiroeinicialize-acom15000;Crie também as variáveis gastosFevereiro e gastosMarco, inicializando-as com 23000 e17000,respectivamente,utilizeumalinhaparacadadeclaração;

CrieumavariávelchamadagastosTrimestreeinicialize-acomasomadasoutras3variáveis:

intgastosTrimestre=gastosJaneiro+gastosFevereiro+gastosMarco;

ImprimaavariávelgastosTrimestre.

2. Adicione código (sem alterar as linhas que já existem) na classe anterior para imprimir a médiamensal de gasto, criando uma variável mediaMensal junto com uma mensagem. Para isso,concateneaStringcomovalor,usando"Valordamédiamensal="+mediaMensal.

DiscutacomoinstrutoreseuscolegassobreconvençõesdecódigoJava.Porqueexistem?Porquesãoimportantes?

Discutatambémasvantagensdeseescrevercódigofácildelereseevitarcomentáriosemexcesso.(Dica:procureporjavacodeconventions).

3.3EXERCÍCIOS:VARIÁVEISETIPOSPRIMITIVOS

3.4 DISCUSSÃO EM AULA: CONVENÇÕES DE CÓDIGO E CÓDIGOLEGÍVEL

.

Page 35: FJ-11 Java e Orientação a Objetos

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

Algunsvaloressãoincompatíveissevocêtentarfazerumaatribuiçãodireta.Enquantoumnúmerorealcostumaserrepresentadoemumavariáveldotipodouble,tentaratribuireleaumavariávelintnão funciona porque é um código que diz: "i deve valerd",mas não se sabe sed realmente é umnúmerointeiroounão.

doubled=3.1415;inti=d;//nãocompila

Omesmoocorrenoseguintetrecho:

inti=3.14;

Omaisinteressante,équenemmesmooseguintecódigocompila:

doubled=5;//ok,odoublepodeconterumnúmerointeirointi=d;//nãocompila

Apesarde5serumbomvalorparaumint,ocompiladornãotemcomosaberquevalorestarádentro desse double no momento da execução. Esse valor pode ter sido digitado pelo usuário, eninguémvaigarantirqueessaconversãoocorrasemperdadevalores.

Jánocasoaseguir,éocontrário:

inti=5;doubled2=i;

Ocódigoacimacompilasemproblemas,jáqueumdoublepodeguardarumnúmerocomousempontoflutuante.Todososinteirosrepresentadosporumavariáveldotipointpodemserguardadosemumavariáveldouble,entãonãoexistemproblemasnocódigoacima.

AprendasedivertindonaAluraStart!

3.5CASTINGEPROMOÇÃO

.

Page 36: FJ-11 Java e Orientação a Objetos

Às vezes, precisamos que um número quebrado seja arredondado e armazenado num númerointeiro.Para fazer issosemquehajaoerrodecompilação,éprecisoordenarqueonúmeroquebradosejamoldado(casted)comoumnúmerointeiro.Esseprocessorecebeonomedecasting.

doubled3=3.14;inti=(int)d3;

Ocastingfoifeitoparamoldaravariáveld3comoumint.Ovalordeiagoraé3.

Omesmoocorreentrevaloresintelong.

longx=10000;inti=x;//nãocompila,poispodeestarperdendoinformação

E,sequisermosrealmentefazerisso,fazemosocasting:

longx=10000;inti=(int)x;

CASOSNÃOTÃOCOMUNSDECASTINGEATRIBUIÇÃO

Algunscastingsaparecemtambém:

floatx=0.0;

O código acima não compila pois todos os literais com ponto flutuante são consideradosdoublepeloJava.Efloatnãopodereceberumdoublesemperdadeinformação,parafazerissofuncionarpodemosescreveroseguinte:

floatx=0.0f;

Aletraf,quepodesermaiúsculaouminúscula,indicaqueaqueleliteraldevesertratadocomofloat.

Outrocaso,queémaiscomum:

doubled=5;floatf=3;

floatx=f+(float)d;

VocêprecisadocastingporqueoJavafazascontasevaiarmazenandosemprenomaiortipoqueapareceuduranteasoperações,nocasoodouble.

E,umaobservação:nomínimo,oJavaarmazenaoresultadoemumint,nahoradefazerascontas.

Atécastingcomvariáveisdotipocharpodemocorrer.Oúnicotipoprimitivoquenãopodeseratribuídoanenhumoutrotipoéoboolean.

.

Page 37: FJ-11 Java e Orientação a Objetos

CASTINGSPOSSÍVEIS

Abaixoestãorelacionados todososcastspossíveisna linguagemJava,mostrandoaconversãodeumvalorparaoutro.AindicaçãoImpl.querdizerqueaquelecastéimplícitoeautomático,ouseja, vocênãoprecisa indicaro cast explicitamente (lembrandoqueo tipobooleannãopode serconvertidoparanenhumoutrotipo).

TAMANHODOSTIPOS

Natabelaabaixo,estãoostamanhosdecadatipoprimitivodoJava.

AsintaxedoifnoJavaéaseguinte:

if(condicaoBooleana){codigo;}

3.6OIFEOELSE

.

Page 38: FJ-11 Java e Orientação a Objetos

Umacondiçãobooleanaéqualquerexpressãoqueretornetrueoufalse.Paraisso,vocêpodeusarosoperadores<,>,<=,>=eoutros.Umexemplo:

intidade=15;if(idade<18){System.out.println("Nãopodeentrar");}

Alémdisso,vocêpodeusaracláusulaelseparaindicarocomportamentoquedeveserexecutadonocasodaexpressãobooleanaserfalsa:

intidade=15;if(idade<18){System.out.println("Nãopodeentrar");}else{System.out.println("Podeentrar");}

Você pode concatenar expressões booleanas através dos operadores lógicos "E" e "OU". O "E" érepresentadopelo&&eo"OU"érepresentadopelo||.

Umexemploseriaverificarseeletemmenosde18anoseseelenãoéamigododono:

intidade=15;booleanamigoDoDono=true;if(idade<18&&amigoDoDono==false){System.out.println("Nãopodeentrar");}else{System.out.println("Podeentrar");}

Esse código poderia ficar ainda mais legível, utilizando-se o operador de negação, o ! . Esseoperadortransformaoresultadodeumaexpressãobooleanadefalseparatrueeviceversa.

intidade=15;booleanamigoDoDono=true;if(idade<18&&!amigoDoDono){System.out.println("Nãopodeentrar");}else{System.out.println("Podeentrar");}

Reparenalinha3queotrechoamigoDoDono==falsevirou!amigoDoDono.Elestêmomesmovalor.

Para comparar se uma variável tem o mesmo valor que outra variável ou valor, utilizamos ooperador==.Reparequeutilizarooperador=dentrodeumifvairetornarumerrodecompilação,jáqueooperador=éodeatribuição.

intmes=1;if(mes==1){System.out.println("Vocêdeveriaestardeférias");}

.

Page 39: FJ-11 Java e Orientação a Objetos

Owhile é um comando usado para fazer um laço (loop), isto é, repetir um trecho de códigoalgumasvezes.Aideiaéqueessetrechodecódigosejarepetidoenquantoumadeterminadacondiçãopermanecerverdadeira.

intidade=15;while(idade<18){System.out.println(idade);idade=idade+1;}

Otrechodentrodoblocodowhileseráexecutadoatéomomentoemqueacondiçãoidade<18passeaserfalsa.Eissoocorreráexatamentenomomentoemqueidade==18,oquenãoofaráimprimir18.

inti=0;while(i<10){System.out.println(i);i=i+1;}

Jáowhileacimaimprimede0a9.

Conheça a Casa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Com a curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Outrocomandodeloopextremamenteutilizadoéofor.Aideiaéamesmadowhile:fazerumtrechode código ser repetido enquantouma condição continuar verdadeira.Mas alémdisso, oforisola tambémumespaçopara inicializaçãodevariáveiseomodificadordessasvariáveis. Isso fazcomquefiquemmaislegíveis,asvariáveisquesãorelacionadasaoloop:

for(inicializacao;condicao;incremento){codigo;}

3.7OWHILE

Seuslivrosdetecnologiaparecemdoséculopassado?

3.8OFOR

.

Page 40: FJ-11 Java e Orientação a Objetos

Umexemploéoaseguir:

for(inti=0;i<10;i=i+1){System.out.println("olá!");}

Reparequeesseforpoderiasertrocadopor:

inti=0;while(i<10){System.out.println("olá!");i=i+1;}

Porém,ocódigodofor indicaclaramentequeavariáveli serve,emespecial,paracontrolaraquantidadedelaçosexecutados.Quandousarofor?Quandousarowhile?Dependedogostoedaocasião.

PÓSINCREMENTO++

i=i+1poderealmentesersubstituídopori++quandoisolado,porém,emalgunscasos,temosessainstruçãoenvolvidaem,porexemplo,umaatribuição:

inti=5;intx=i++;

Qualéovalordex?Odei,apósessalinha,é6.

O operador ++, quando vem após a variável, retorna o valor antigo, e incrementa (pósincremento),fazendoxvaler5.

Sevocêtivesseusadoo++antesdavariável(préincremento),oresultadoseria6:

inti=5;intx=++i;//aquixvalera6

Apesardetermoscondiçõesbooleanasnosnossoslaços,emalgummomento,podemosdecidirpararoloopporalgummotivoespecialsemqueorestodolaçosejaexecutado.

for(inti=x;i<y;i++){if(i%19==0){System.out.println("Acheiumnúmerodivisívelpor19entrexey");break;}}

Ocódigoacimavaipercorrerosnúmerosdexayepararquandoencontrarumnúmerodivisívelpor19,umavezquefoiutilizadaapalavrachavebreak.

3.9CONTROLANDOLOOPS

.

Page 41: FJ-11 Java e Orientação a Objetos

Damesmamaneira,épossívelobrigaroloopaexecutaropróximolaço.Paraissousamosapalavrachavecontinue.

for(inti=0;i<100;i++){if(i>50&&i<60){continue;}System.out.println(i);}

Ocódigoacimanãovaiimprimiralgunsnúmeros.(Quaisexatamente?)

No Java, podemos declarar variáveis a qualquer momento. Porém, dependendo de onde você asdeclarou,elavaivalerdeumdeterminadopontoaoutro.

//aquiavariávelinãoexisteinti=5;//apartirdaquielaexiste

Oescopoda variável é onomedado ao trechode código emque aquela variável existe e onde épossívelacessá-la.

Quandoabrimosumnovoblococomaschaves,asvariáveisdeclaradasalidentrosóvalematéofimdaquelebloco.

//aquiavariávelinãoexisteinti=5;//apartirdaquielaexistewhile(condicao){//oiaindavaleaquiintj=7;//ojpassaaexistir}//aquiojnãoexistemais,masoicontinuadentrodoescopo

Noblocoacima,avariáveljpáradeexistirquandoterminaoblocoondeelafoideclarada.Sevocêtentaracessarumavariávelforadeseuescopo,ocorreráumerrodecompilação.

Omesmovaleparaumif:

if(algumBooleano){inti=5;}else{

3.10ESCOPODASVARIÁVEIS

.

Page 42: FJ-11 Java e Orientação a Objetos

inti=10;}System.out.println(i);//cuidado!

Aquiavariávelinãoexisteforadoifedoelse!Sevocêdeclararavariávelantesdoif,vaihaveroutroerrodecompilação:dentrodoifedoelseavariávelestásendoredeclarada!Entãoocódigoparacompilarefazersentidofica:

inti;if(algumBooleano){i=5;}else{i=10;}System.out.println(i);

Umasituaçãoparecidapodeocorrercomofor:

for(inti=0;i<10;i++){System.out.println("olá!");}System.out.println(i);//cuidado!

Nestefor,avariávelimorreaoseutérmino,nãopodendoseracessadadeforadofor,gerandoumerrodecompilação.Sevocêrealmentequeracessarocontadordepoisdoloopterminar,precisadealgocomo:

inti;for(i=0;i<10;i++){System.out.println("olá!");}System.out.println(i);

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design, Infra,Front-Ende

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Umblocotambémpodeserdeclaradodentrodeoutro.Istoé,umifdentrodeumfor,ouumfordentrodeumfor,algocomo:

Agoraéamelhorhoraderespirarmaistecnologia!

3.11UMBLOCODENTRODOOUTRO

.

Page 43: FJ-11 Java e Orientação a Objetos

while(condicao){for(inti=0;i<10;i++){//código}}

Vimos apenas os comandos mais usados para controle de fluxo. O Java ainda possui odo..whileeoswitch.Pesquisesobreelesedigaquandoéinteressanteusarcadaumdeles.

Algumasvezes,temosvárioslaçosencadeados.Podemosutilizarobreakparaquebrarolaçomaisinterno.Mas,sequisermosquebrarumlaçomaisexterno,teremosdeencadeardiversosifs e seu código ficará uma bagunça. O Java possui um artifício chamado labeled loops;pesquisesobreeles.

Oqueacontecesevocêtentardividirumnúmerointeiropor0?Epor0.0?

Existe um caminho entre os tipos primitivos que indicam se há a necessidade ou não decastingentreostipos.Porexemplo,int->long->double(umintpodesertratadocomoumdouble, mas não o contrário). Pesquise (ou teste), e posicione os outros tiposprimitivosnessefluxo.

Alémdosoperadoresde incremento,existemosdedecremento,como--i ei--.Alémdesses,vocêpodeusarinstruçõesdotipoi+=xei-=x,oqueessasinstruçõesfazem?Teste.

Mais exercícios de fixação de sintaxe. Para quem já conhece um pouco de Java, pode ser muitosimples;mas recomendamos fortemente que você faça os exercícios para se acostumar com erros decompilação,mensagensdojavac,convençãodecódigo,etc...

Apesardeextremamentesimples,precisamospraticarasintaxequeestamosaprendendo.Paracadaexercício,crieumnovoarquivocomextensão.java,edeclareaqueleestranhocabeçalho,dandonomeaumaclasseecomumblocomaindentrodele:

classExercicioX{publicstaticvoidmain(String[]args){//seuexercíciovaiaqui}}

Nãocopieecoledeumexercíciojáexistente!Aproveiteparapraticar.

1. Imprimatodososnúmerosde150a300.

3.12PARASABERMAIS

3.13EXERCÍCIOS:FIXAÇÃODESINTAXE

.

Page 44: FJ-11 Java e Orientação a Objetos

2. Imprimaasomade1até1000.

3. Imprimatodososmúltiplosde3,entre1e100.

4. Imprimaosfatoriaisde1a10.

Ofatorialdeumnúmeronén*(n-1)*(n-2)*...*1.Lembre-sedeutilizarosparênteses.

Ofatorialde0é1

Ofatorialde1é(0!)*1=1

Ofatorialde2é(1!)*2=2

Ofatorialde3é(2!)*3=6

Ofatorialde4é(3!)*4=24

Façaumforqueinicieumavariáveln(número)como1efatorial(resultado)como1evariande1até10:

intfatorial=1;for(intn=1;n<=10;n++){

}

5. Nocódigodoexercícioanterior,aumenteaquantidadedenúmerosqueterãoosfatoriaisimpressos,até20,30,40.Emumdeterminadomomento,alémdessecálculodemorar, vai começaramostrarrespostascompletamenteerradas.Porquê?

Mudedeintparalongparaveralgumamudança.

6. (opcional) Imprima os primeiros números da série de Fibonacci até passar de 100. A série deFibonacciéaseguinte:0,1,1,2,3,5,8,13,21,etc...Paracalculá-la,oprimeiroelementovale0,osegundovale1,daípordiante,on-ésimoelementovaleo(n-1)-ésimoelementosomadoao(n-2)-ésimoelemento(ex:8=5+3).

7. (opcional)Escrevaumprogramaque, dadaumavariávelx com algum valor inteiro, temosumnovoxdeacordocomaseguinteregra:

sexépar,x=x/2sexéimpar,x=3*x+1imprimex

Oprogramadevepararquandoxtiverovalorfinalde1.Porexemplo,parax=13,asaídaserá:

40->20->10->5->16->8->4->2->1

.

Page 45: FJ-11 Java e Orientação a Objetos

IMPRIMINDOSEMPULARLINHA

Umdetalhe importanteéqueumaquebrade linhaé impressa todavezquechamamosprintln.Paranãopularumalinha,usamosocódigoaseguir:

System.out.print(variavel);

8. (opcional)Imprimaaseguintetabela,usandoforsencadeados:

124369481216nn*2n*3....n*n

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelum eobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

1. FaçaoexercíciodasériedeFibonacciusandoapenasduasvariáveis.

EditoraCasadoCódigocomlivrosdeumaformadiferente

3.14DESAFIOS:FIBONACCI

.

Page 46: FJ-11 Java e Orientação a Objetos

CAPÍTULO4

"Programação orientada a objetos é uma péssima ideia, que só poderia ter nascido na Califórnia." --EdsgerDijkstra

Aotérminodestecapítulo,vocêserácapazde:

dizeroqueéeparaqueserveorientaçãoaobjetos;conceituarclasses,atributosecomportamentos;entenderosignificadodevariáveiseobjetosnamemória.

Orientação a objetos é uma maneira de programar que ajuda na organização e resolve muitosproblemasenfrentadospelaprogramaçãoprocedural.

ConsideremosoclássicoproblemadavalidaçãodeumCPF.Normalmente, temosumformulário,noqualrecebemosessainformação,edepoistemosqueenviaressescaracteresparaumafunçãoquevaivalidá-lo,comonopseudocódigoabaixo:

cpf=formulario->campo_cpfvalida(cpf)

AlguémteobrigaasemprevalidaresseCPF?Vocêpode, inúmerasvezes,esquecerdechamaressevalidador.Mais: considerequevocê tem50 formulárioseprecisevalidaremtodoselesoCPF.Se suaequipetem3programadorestrabalhandonessesformulários,quemficaresponsávelporessavalidação?Todos!

Asituaçãopodepiorar:naentradadeumnovodesenvolvedor,precisaríamosavisá-loquesempredevemosvalidarocpfdeumformulário.Énessemomentoquenascemaquelesguiasdeprogramaçãopara o desenvolvedor que for entrar nesse projeto - às vezes, é um documento enorme. Em outraspalavras,tododesenvolvedorprecisaficarsabendodeumaquantidadeenormedeinformações,que,namaioriadasvezes,nãoestárealmenterelacionadoàsuapartenosistema,maseleprecisa lertudoisso,resultandoumentravemuitogrande!

Outra situação onde ficam claros os problemas da programação procedural, é quando nosencontramosnanecessidadedelerocódigoquefoiescritoporoutrodesenvolvedoredescobrircomoele funciona internamente.Um sistemabemencapsuladonãodeveria gerar essanecessidade.Emum

ORIENTAÇÃOAOBJETOSBÁSICA

4.1MOTIVAÇÃO:PROBLEMASDOPARADIGMAPROCEDURAL

.

Page 47: FJ-11 Java e Orientação a Objetos

sistemagrande,simplesmentenãotemostempodelertodoocódigoexistente.

Considerandoquevocênãoerrenessepontoequesuaequipetenhaumacomunicaçãomuitoboa(percebaquecomunicaçãoexcessivapodeserprejudicialeatrapalharoandamento),aindatemosoutroproblema:imagineque,emtodoformulário,vocêtambémquerqueaidadedoclientesejavalidada-oclienteprecisatermaisde18anos.Vamosterdecolocarumif...masonde?Espalhadoportodoseucódigo... Mesmo que se crie outra função para validar, precisaremos incluir isso nos nossos 50formuláriosjáexistentes.Qualéachancedeesquecermosemumdeles?Émuitogrande.

Aresponsabilidadedeverificarseoclientetemounãotem18anosficouespalhadaportodooseucódigo.Seriainteressantepoderconcentraressaresponsabilidadeemumlugarsó,paranãoterchancesdeesquecerisso.

Melhor ainda seria se conseguíssemos mudar essa validação e os outros programadores nemprecisassemficarsabendodisso.Emoutraspalavras,elescriariamformulárioseumúnicoprogramadorseriaresponsávelpelavalidação:osoutrosnemsabemdaexistênciadessetrechodecódigo.Impossível?Não,oparadigmadaorientaçãoaobjetosfacilitatudoisso.

Oproblemadoparadigmaprocedural é quenão existeuma forma simplesde criar conexão forteentredadosefuncionalidades.Noparadigmaorientadoaobjetosémuitofácilteressaconexãoatravésdosrecursosdapróprialinguagem.

QUAISASVANTAGENS?

Orientação a objetos vai te ajudar em muito em se organizar e escrever menos, além deconcentrar as responsabilidades nos pontos certos, flexibilizando sua aplicação, encapsulando alógicadenegócios.

Outra enorme vantagem, onde você realmente vai economizar montanhas de código, é opolimorfismodasreferências,queveremosemumposteriorcapítulo.

Nos próximos capítulos, conseguiremos enxergar toda essa vantagem, mas, primeiramente énecessárioconhecerumpoucomaisdasintaxeedacriaçãodetiposereferênciasemJava.

.

Page 48: FJ-11 Java e Orientação a Objetos

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

Considere um programa para um banco, é bem fácil perceber que uma entidade extremamenteimportante para o nosso sistema é a conta. Nossa ideia aqui é generalizarmos alguma informação,juntamentecomfuncionalidadesquetodacontadeveter.

Oquetodacontatemeéimportanteparanós?

númerodacontanomedotitulardacontasaldo

Oquetodacontafazeéimportanteparanós?Istoé,oquegostaríamosde"pediràconta"?

sacaumaquantidadexdepositaumaquantidadeximprimeonomedotitulardacontadevolveosaldoatualtransfereumaquantidadexparaumaoutracontaydevolveotipodeconta

Comisso,temosoprojetodeumacontabancária.Podemospegaresseprojetoeacessarseusaldo?Não.Oquetemosaindaéoprojeto.Antes,precisamosconstruirumaconta,parapoderacessaroqueelatem,epediraelaquefaçaalgo.

JáconheceoscursosonlineAlura?

4.2CRIANDOUMTIPO

.

Page 49: FJ-11 Java e Orientação a Objetos

Reparenafigura:apesardopapeldoladoesquerdoespecificarumaConta,essaespecificaçãoéumaConta?Nósdepositamosesacamosdinheirodessepapel?Não.UtilizamosaespecificaçãodaContaparapodercriarinstânciasquerealmentesãocontas,ondepodemosrealizarasoperaçõesquecriamos.

Apesardedeclararmosquetodacontatemumsaldo,umnúmeroeumaagêncianopedaçodepapel(comoàesquerdanafigura),sãonasinstânciasdesseprojetoquerealmenteháespaçoparaarmazenaressesvalores.

Aoprojetodaconta,istoé,adefiniçãodaconta,damosonomedeclasse.Aoquepodemosconstruirapartirdesseprojeto,ascontasdeverdade,damosonomedeobjetos.

Apalavraclassevemdataxonomiadabiologia.Todososseresvivosdeumamesmaclassebiológicatêm uma série de atributos e comportamentos em comum, mas não são iguais, podem variar nosvaloresdessesatributosecomorealizamessescomportamentos.

HomoSapiensdefineumgrupodeseresquepossuemcaracterísticasemcomum,porémadefinição(a ideia, o conceito)deumHomoSapiens é um serhumano?Não.Tudo está especificadonaclasseHomoSapiens,massequisermosmandaralguémcorrer,comer,pular,precisaremosdeumainstânciadeHomoSapiens,ouentãodeumobjetodotipoHomoSapiens.

Umoutroexemplo:umareceitadebolo.Aperguntaécerteira:vocêcomeumareceitadebolo?Não.

.

Page 50: FJ-11 Java e Orientação a Objetos

Precisamos instanciá-la, criar um objeto bolo a partir dessa especificação (a classe) para utilizá-la.Podemos criar centenas de bolos a partir dessa classe (a receita, no caso), eles podem ser bemsemelhantes,algunsatéidênticos,massãoobjetosdiferentes.

Podemos fazer milhares de analogias semelhantes. A planta de uma casa é uma casa?Definitivamentenão.Nãopodemosmorardentrodaplantadeumacasa,nempodemosabrirsuaportaou pintar suas paredes. Precisamos, antes, construir instâncias a partir dessa planta. Essas instâncias,sim,podemospintar,decoraroumorardentro.

Pode parecer óbvio,mas a dificuldade inicial do paradigma da orientação a objetos é justo saberdistinguiroque é classe eoqueéobjeto.É comumo inicianteutilizar,obviamentede formaerrada,essasduaspalavrascomosinônimos.

Vamoscomeçar apenas comoqueumaConta tem, enão comoque ela faz (veremos logo emseguida).

Umtipodesses,comooespecificadodeContaacima,podeserfacilmentetraduzidoparaJava:

classConta{intnumero;Stringtitular;doublesaldo;

//..}

STRING

StringéumaclasseemJava.Elaguardaumacadeiadecaracteres,umafrasecompleta.Comoestamosaindaaprendendooqueéumaclasse,entenderemoscomdetalhesaclasseStringapenasemcapítulosposteriores.

Porenquanto,declaramosoquetodacontadeveter.Estessãoosatributosquetodaconta,quandocriada,vaiter.Reparequeessasvariáveisforamdeclaradasforadeumbloco,diferentedoquefazíamosquandotinhaaquelemain.Quandoumavariávelédeclaradadiretamentedentrodoescopodaclasse,échamadadevariáveldeobjeto,ouatributo.

JátemosumaclasseemJavaqueespecificaoquetodoobjetodessaclassedeveter.Mascomousá-la?Alémdessaclasse,aindateremosoPrograma.javaeapartirdeleéquevamosutilizaraclasseConta.

4.3UMACLASSEEMJAVA

4.4CRIANDOEUSANDOUMOBJETO

.

Page 51: FJ-11 Java e Orientação a Objetos

Paracriar (construir, instanciar)umaConta, bastausar apalavra chavenew.Devemosutilizartambémosparênteses,quedescobriremosoquefazemexatamenteemumcapítuloposterior:

classPrograma{publicstaticvoidmain(String[]args){newConta();}}

Bem,ocódigoacimacriaumobjetodotipoConta,mascomoacessaresseobjetoquefoicriado?Precisamosteralgumaformadenosreferenciarmosaesseobjeto.Precisamosdeumavariável:

classPrograma{publicstaticvoidmain(String[]args){ContaminhaConta;minhaConta=newConta();}}

PodeparecerestranhoescrevermosduasvezesConta:umaveznadeclaraçãodavariáveleoutraveznousodonew.Masháummotivo,queembreveentenderemos.

AtravésdavariávelminhaConta,podemosacessaroobjetorecémcriadoparaalterarseutitular,seusaldo,etc:

classPrograma{publicstaticvoidmain(String[]args){ContaminhaConta;minhaConta=newConta();

minhaConta.titular="Duke";minhaConta.saldo=1000.0;

System.out.println("Saldoatual:"+minhaConta.saldo);}}

É importante fixarqueoponto foiutilizadopara acessar algo emminhaConta.AminhaContapertenceaoDuke,etemsaldodemilreais.

.

Page 52: FJ-11 Java e Orientação a Objetos

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

Dentro da classe, também declararemos o que cada conta faz e como isto é feito - oscomportamentosquecadaclassetem,istoé,oqueelafaz.Porexemplo,dequemaneiraqueumaContasacadinheiro?EspecificaremosissodentrodaprópriaclasseConta,enãoemumlocaldesatreladodasinformações da própria Conta. É por isso que essas "funções" são chamadas de métodos. Pois é amaneiradefazerumaoperaçãocomumobjeto.

Queremos criar um método que saca uma determinada quantidade e não devolve nenhumainformaçãoparaquemacionaressemétodo:

classConta{doublesalario;//...outrosatributos...

voidsaca(doublequantidade){doublenovoSaldo=this.saldo-quantidade;this.saldo=novoSaldo;}}

A palavra chave void diz que, quando você pedir para a conta sacar uma quantia, nenhumainformaçãoseráenviadadevoltaaquempediu.

Quando alguém pedir para sacar, ele também vai dizer quanto quer sacar. Por isso precisamosdeclararométodocomalgodentrodosparênteses-oquevaiaídentroéchamadodeargumento dométodo(ouparâmetro).Essavariáveléumavariávelcomum,chamadatambémdetemporáriaoulocal,pois,aofinaldaexecuçãodessemétodo,eladeixadeexistir.

SaberinglêsémuitoimportanteemTI

4.5MÉTODOS

.

Page 53: FJ-11 Java e Orientação a Objetos

Dentrodométodo,estamosdeclarandoumanovavariável.Essavariável,assimcomooargumento,vaimorrernofimdométodo,poisesteéseuescopo.Nomomentoquevamosacessarnossoatributo,usamos a palavra chave this para mostrar que esse é um atributo, e não uma simples variável.(veremosdepoisqueéopcional)

Repare que, nesse caso, a conta poderia estourar um limite fixado pelo banco.Mais para frente,evitaremosessasituação,edeumamaneiramuitoelegante.

Damesmaforma,temosométodoparadepositaralgumaquantia:

classConta{//...outrosatributosemétodos...

voiddeposita(doublequantidade){this.saldo+=quantidade;}}

Observequenãousamosumavariávelauxiliare,alémdisso,usamosaabreviação+=paradeixarométodobemsimples.O+= somaquantidade aovalor antigodo saldo e guardanopróprio saldo, ovalorresultante.

Paramandarumamensagemaoobjetoepedirqueeleexecuteummétodo,tambémusamosoponto.Otermousadoparaissoéinvocaçãodemétodo.

Ocódigoaseguirsacadinheiroedepoisdepositaoutraquantiananossaconta:

classTestaAlgunsMetodos{publicstaticvoidmain(String[]args){//criandoacontaContaminhaConta;minhaConta=newConta();

//alterandoosvaloresdeminhaContaminhaConta.titular="Duke";minhaConta.saldo=1000;

//saca200reaisminhaConta.saca(200);

//deposita500reaisminhaConta.deposita(500);System.out.println(minhaConta.saldo);}}

Uma vez que seu saldo inicial é 1000 reais, se sacarmos 200 reais, depositarmos 500 reais eimprimirmosovalordosaldo,oqueseráimpresso?

Ummétodosempretemquedefiniroqueretorna,nemquedefinaquenãoháretorno,comonos

4.6MÉTODOSCOMRETORNO

.

Page 54: FJ-11 Java e Orientação a Objetos

exemplosanterioresondeestávamosusandoovoid.

Ummétodopoderetornarumvalorparaocódigoqueochamou.Nocasodonossométodosaca,podemosdevolverumvalorbooleanoindicandoseaoperaçãofoibemsucedida.

classConta{//...outrosmétodoseatributos...

booleansaca(doublevalor){if(this.saldo<valor){returnfalse;}else{this.saldo=this.saldo-valor;returntrue;}}}

Adeclaraçãodométodomudou!Ométodosacanãotemvoidna frente. Istoquerdizerque,quando é acessado, ele devolve algum tipo de informação.No caso, umboolean. A palavra chavereturnindicaqueométodovaiterminarali,retornandotalinformação.

Exemplodeuso:

minhaConta.saldo=1000;booleanconsegui=minhaConta.saca(2000);if(consegui){System.out.println("Conseguisacar");}else{System.out.println("Nãoconseguisacar");}

Ouentão,possoeliminaravariáveltemporária,sedesejado:

minhaConta.saldo=1000;if(minhaConta.saca(2000)){System.out.println("Conseguisacar");}else{System.out.println("Nãoconseguisacar");}

Maisadiante,veremosquealgumasvezesémaisinteressantelançarumaexceção(exception)nessescasos.

.

Page 55: FJ-11 Java e Orientação a Objetos

Meuprogramapodemanternamemórianãoapenasumaconta,comomaisdeuma:

classTestaDuasContas{publicstaticvoidmain(String[]args){

ContaminhaConta;minhaConta=newConta();minhaConta.saldo=1000;

ContameuSonho;meuSonho=newConta();meuSonho.saldo=1500000;}}

Quandodeclaramosumavariávelparaassociaraumobjeto,naverdade,essavariávelnãoguardaoobjeto,esimumamaneiradeacessá-lo,chamadadereferência.

Épor essemotivoque,diferentedos tipos primitivos comoint elong, precisamosdarnewdepoisdedeclaradaavariável:

publicstaticvoidmain(String[]args){Contac1;c1=newConta();

Contac2;c2=newConta();}

Ocorretoaqui,édizerquec1serefereaumobjeto.Nãoécorretodizerquec1éumobjeto,poisc1éumavariávelreferência,apesarde,depoisdeumtempo,osprogramadoresJavafalarem"TenhoumobjetocdotipoConta",masapenasparaencurtarafrase"TenhoumareferênciacaumobjetodotipoConta".

Basta lembrar que, em Java,umavariávelnunca éumobjeto.Nãohá, no Java, umamaneiradecriarmosoqueéconhecidocomo"objetopilha"ou"objetolocal",poistodoobjetoemJava,semexceção,éacessadoporumavariávelreferência.

Essecódigonosdeixanaseguintesituação:

Contac1;c1=newConta();

Contac2;c2=newConta();

4.7OBJETOSSÃOACESSADOSPORREFERÊNCIAS

.

Page 56: FJ-11 Java e Orientação a Objetos

Internamente,c1ec2vãoguardarumnúmeroqueidentificaemqueposiçãodamemóriaaquelaContaseencontra.Dessamaneira,aoutilizarmoso"."paranavegar,oJavavaiacessaraContaqueseencontranaquelaposiçãodememória,enãoumaoutra.

Para quem conhece, é parecido com um ponteiro, porém você não podemanipulá-lo como umnúmeroenemutilizá-loparaaritmética,elaétipada.

Umoutroexemplo:

classTestaReferencias{publicstaticvoidmain(String[]args){Contac1=newConta();c1.deposita(100);

Contac2=c1;//linhaimportante!c2.deposita(200);

System.out.println(c1.saldo);System.out.println(c2.saldo);}}

Qualéoresultadodocódigoacima?Oqueapareceaorodar?

Oqueaconteceaqui?Ooperador=copiaovalordeumavariável.Masqualéovalordavariávelc1? É o objeto?Não.Na verdade, o valor guardado é a referência (endereço) de onde o objeto seencontranamemóriaprincipal.

Namemória,oqueacontecenessecaso:

Contac1=newConta();Contac2=c1;

.

Page 57: FJ-11 Java e Orientação a Objetos

Quandofizemosc2=c1,c2passaafazerreferênciaparaomesmoobjetoquec1 referencianesseinstante.

Então,nessecódigoemespecífico,quandoutilizamosc1ouc2estamosnosreferindoexatamenteaomesmoobjeto!Elassãoduasreferênciasdistintas,porémapontamparaomesmoobjeto!Compará-lascom"=="vainosretornartrue,poisovalorqueelascarregaméomesmo!

Outraformadeperceber,équedemosapenasumnew,entãosópodehaverumobjetoContanamemória.

Atenção:nãoestamosdiscutindoaquiautilidadedefazerumareferênciaapontarpromesmoobjetoque outra. Essa utilidade ficará mais clara quando passarmos variáveis do tipo referência comoargumentoparamétodos.

NEW

Oqueexatamentefazonew?

Onewexecutaumasériedetarefas,queveremosmaisadiante.

Mas,paramelhorentenderasreferênciasnoJava,saibaqueonew,depoisdealocaramemóriaparaesseobjeto,devolveuma "flecha", istoé,umvalorde referência.Quandovocêatribui issoaumavariável,essavariávelpassaasereferirparaessemesmoobjeto.

Podemosentãoveroutrasituação:

publicstaticvoidmain(String[]args){Contac1=newConta();c1.titular="Duke";c1.saldo=227;

Contac2=newConta();c2.titular="Duke";c2.saldo=227;

if(c1==c2){System.out.println("Contasiguais");}}

Ooperador==comparaoconteúdodasvariáveis,masessasvariáveisnãoguardamoobjeto,esimoendereçoemqueeleseencontra.Comoemcadaumadessasvariáveisguardamosduascontascriadasdiferentemente,elasestãoemespaçosdiferentesdamemória,oquefazotestenoifvalerfalse.Ascontas podem ser equivalentes no nosso critério de igualdade, porém elas não são omesmo objeto.Quandosetratadeobjetos,podeficarmaisfácilpensarqueo==comparaseosobjetos(referências,naverdade)sãoomesmo,enãosesãoiguais.

.

Page 58: FJ-11 Java e Orientação a Objetos

Para saber se dois objetos têm omesmo conteúdo, você precisa comparar atributo por atributo.Veremosumasoluçãomaiseleganteparaissotambém.

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

Esequisermosterummétodoquetransferedinheiroentreduascontas?Podemosficartentadosacriarummétodoquerecebedoisparâmetros:conta1econta2dotipoConta.Mascuidado:assimestamospensandodemaneiraprocedural.

Aideiaéque,quandochamarmosométodotransfere,játeremosumobjetodotipoConta(othis),portantoométodo recebeapenasum parâmetrodo tipoConta, aContadestino (alémdovalor):

classConta{

//atributosemétodos...

voidtransfere(Contadestino,doublevalor){

AprendasedivertindonaAluraStart!

4.8OMÉTODOTRANSFERE()

.

Page 59: FJ-11 Java e Orientação a Objetos

this.saldo=this.saldo-valor;destino.saldo=destino.saldo+valor;}}

Para deixar o código mais robusto, poderíamos verificar se a conta possui a quantidade a sertransferidadisponível.Paraficaraindamais interessante,vocêpodechamarosmétodosdeposita esacajáexistentesparafazeressatarefa:

classConta{

//atributosemétodos...

booleantransfere(Contadestino,doublevalor){booleanretirou=this.saca(valor);if(retirou==false){//nãodeuprasacar!returnfalse;}else{destino.deposita(valor);returntrue;}}}

QuandopassamosumaContacomoargumento,oqueseráqueacontecenamemória?Seráqueoobjetoéclonado?

No Java, a passagem de parâmetro funciona como uma simples atribuição como no uso do "=".Então,esseparâmetrovaicopiarovalordavariáveldotipoContaqueforpassadocomoargumento.Equaléovalordeumavariáveldessas?Seuvaloréumendereço,umareferência,nuncaumobjeto.Porissonãohácópiadeobjetosaqui.

.

Page 60: FJ-11 Java e Orientação a Objetos

Esseúltimocódigopoderiaserescritocomumasintaxemuitomaissucinta.Como?

TRANSFEREPARA

PercebaqueonomedestemétodopoderiasertransfereParaaoinvésdesótransfere.Achamadadométodo ficamuitomaisnatural, épossível lera fraseemportuguêsqueela temumsentido:

conta1.transferePara(conta2,50);

Aleituradestecódigoseria"Conta1transfereparaconta250reais".

As variáveis do tipo atributo, diferentemente das variáveis temporárias (declaradas dentro de ummétodo),recebemumvalorpadrão.Nocasonumérico,valem0,nocasodeboolean,valemfalse.

Vocêtambémpodedarvaloresdefault,comosegue:

classConta{intnumero=1234;Stringtitular="Duke";doublesaldo=1000.0;}

Nesse caso, quando você criar uma conta, seus atributos já estão "populados" com esses valorescolocados.

ImaginequecomecemosaaumentarnossaclasseContaeadicionarnome,sobrenomeecpfdotitulardaconta.Começaríamosatermuitosatributos...e,sevocêpensardireito,umaContanãotemnome,nemsobrenomenemcpf,quemtemessesatributoséumCliente.Entãopodemoscriarumanovaclasseefazerumacomposição

Seus atributos também podem ser referências para outras classes. Suponha a seguinte classeCliente:

classCliente{Stringnome;Stringsobrenome;Stringcpf;}

classConta{intnumero;doublesaldo;Clientetitular;//..}

4.9CONTINUANDOCOMATRIBUTOS

.

Page 61: FJ-11 Java e Orientação a Objetos

Edentrodomaindaclassedeteste:

classTeste{publicstaticvoidmain(String[]args){ContaminhaConta=newConta();Clientec=newCliente();minhaConta.titular=c;//...}}

Aqui,simplesmentehouveumaatribuição.Ovalordavariávelcécopiadoparaoatributotitulardoobjeto aoqualminhaConta se refere. Emoutras palavras,minhaConta tem uma referência aomesmoClientequecserefere,epodeseracessadoatravésdeminhaConta.titular.

Vocêpoderealmentenavegarsobretodaessaestruturadeinformação,sempreusandooponto:

ClienteclienteDaMinhaConta=minhaConta.titular;clienteDaMinhaConta.nome="Duke";

Ouainda,podefazerissodeumaformamaisdiretaeatémaiselegante:

minhaConta.titular.nome="Duke";

Umsistemaorientadoaobjetoséumgrandeconjuntodeclassesquevaisecomunicar,delegandoresponsabilidadesparaquemformaisaptoarealizardeterminadatarefa.AclasseBancousaaclasseContaqueusaaclasseCliente,queusaaclasseEndereco.Dizemosqueessesobjetoscolaboram,trocandomensagensentresi.Porissoacabamostendomuitasclassesemnossosistema,eelascostumamterumtamanhorelativamentecurto.

Mas,esedentrodomeucódigoeunãodessenewemClienteetentasseacessá-lodiretamente?

classTeste{publicstaticvoidmain(String[]args){ContaminhaConta=newConta();

minhaConta.titular.nome="Manoel";//...}}

Quando damos new em um objeto, ele o inicializa com seus valores default, 0 para números,falseparabooleanenullparareferências.nulléumapalavrachaveemjava,queindicaumareferênciaparanenhumobjeto.

Se,emalgumcaso,vocêtentaracessarumatributooumétododealguémqueestásereferenciando

.

Page 62: FJ-11 Java e Orientação a Objetos

paranull,vocêreceberáumerroduranteaexecução(NullPointerException,queveremosmaisàfrente).Daparaperceber,então,queonewnãotrazumefeitocascata,amenosquevocêdêumvalordefault(ouuseconstrutores,quetambémveremosmaisafrente):

classConta{intnumero;doublesaldo;Clientetitular=newCliente();//quandochamaremnewConta,//haveraumnewClienteparaele.}

Comessecódigo,todanovaContacriadajáteráumnovoClienteassociado,semnecessidadedeinstanciá-lologoemseguidadainstanciaçãodeumaConta.Qualalternativavocêdeveusar?Dependedo caso: para todanovaConta você precisa de umnovoCliente? É essa pergunta que deve serrespondida.Nessenossocasoarespostaénão,masdependedonossoproblema.

Atenção:paraquemnãoestáacostumadocomreferências,podeserbastanteconfusopensarsempreem como os objetos estão namemória para poder tirar as conclusões de o que ocorrerá ao executardeterminado código, por mais simples que ele seja. Com tempo, você adquire a habilidade derapidamente saber o efeito de atrelar as referências, sem ter de gastar muito tempo para isso. Éimportante,nessecomeço,vocêestarsemprepensandonoestadodamemória.Erealmentelembrarque,noJava"umavariávelnuncacarregaumobjeto,esimumareferênciaparaele"facilitamuito.

AlémdoBancoqueestamoscriando,vamosvercomoficariamcertasclassesrelacionadasaumafábrica de carros. Vamos criar uma classe Carro , com certos atributos, que descrevem suascaracterísticas,ecomcertosmétodos,quedescrevemseucomportamento.

classCarro{Stringcor;Stringmodelo;doublevelocidadeAtual;doublevelocidadeMaxima;

//ligaocarrovoidliga(){System.out.println("Ocarroestáligado");}

//aceleraumacertaquantidadevoidacelera(doublequantidade){doublevelocidadeNova=this.velocidadeAtual+quantidade;this.velocidadeAtual=velocidadeNova;}

//devolveamarchadocarrointpegaMarcha(){if(this.velocidadeAtual<0){return-1;}if(this.velocidadeAtual>=0&&this.velocidadeAtual<40){

4.10PARASABERMAIS:UMAFÁBRICADECARROS

.

Page 63: FJ-11 Java e Orientação a Objetos

return1;}if(this.velocidadeAtual>=40&&this.velocidadeAtual<80){return2;}return3;}}

VamostestarnossoCarroemumnovoprograma:

classTestaCarro{publicstaticvoidmain(String[]args){CarromeuCarro;meuCarro=newCarro();meuCarro.cor="Verde";meuCarro.modelo="Fusca";meuCarro.velocidadeAtual=0;meuCarro.velocidadeMaxima=80;

//ligaocarromeuCarro.liga();

//aceleraocarromeuCarro.acelera(20);System.out.println(meuCarro.velocidadeAtual);}}

NossocarropodecontertambémumMotor:

classMotor{intpotencia;Stringtipo;}

classCarro{Stringcor;Stringmodelo;doublevelocidadeAtual;doublevelocidadeMaxima;Motormotor;

//..}

Podemos, criar diversos Carros e mexer com seus atributos e métodos, assim como fizemos noexemplodoBanco.

.

Page 64: FJ-11 Java e Orientação a Objetos

Conheça a Casa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Com a curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Quando declaramos uma classe, um método ou um atributo, podemos dar o nome quequisermos,seguindoumaregra.Porexemplo,onomedeummétodonãopodecomeçarcomumnúmero.Pesquisesobreessasregras.

Comovocêpodeterreparado,sempredamosnomesàsvariáveiscomletrasminúsculas.Équeexistemconvençõesdecódigo,dadaspelaOracle,parafacilitaralegibilidadedocódigoentreprogramadores. Essa convenção émuito seguida. Leia sobre ela pesquisando por "java codeconventions".

Énecessáriousar a palavra chavethis quando for acessar um atributo? Para que, então,utilizá-la?

Existe um padrão para representar suas classes em diagramas, que é amplamente utilizado,chamadoUML.Pesquisesobreele.

Omodelodacontaaseguirseráutilizadoparaosexercíciosdospróximoscapítulos.

O objetivo aqui é criar um sistema para gerenciar as contas de umBanco.Os exercícios dessecapítulosãoextremamenteimportantes.

1. Modele uma conta. A ideia aqui é apenas modelar, isto é, só identifique que informações sãoimportantes.DesenhenopapeltudooqueumaContatemetudooqueelafaz.Eladeveteronomedotitular(String),onúmero(int), a agência (String), o saldo (double) e umadatadeabertura (String).Alémdisso, ela deve fazer as seguintes ações: saca, para retirar um valor do

Seuslivrosdetecnologiaparecemdoséculopassado?

4.11UMPOUCOMAIS...

4.12EXERCÍCIOS:ORIENTAÇÃOAOBJETOS

.

Page 65: FJ-11 Java e Orientação a Objetos

saldo;deposita,paraadicionarumvaloraosaldo;calculaRendimento,paradevolverorendimentomensaldessaconta.

2. Transforme o modelo acima em uma classe Java. Teste-a, usando uma outra classe que tenha omain.Vocêdeve criar a classeda conta comonomeConta,maspodenomear comoquiser aclassedetestes,contudo,eladevepossuirométodomain.

AclasseContadeveconterpelomenososseguintesmétodos:

sacaquerecebeumvalorcomoparâmetroeretiraessevalordosaldodacontadepositaquerecebeumvalorcomoparâmetroeadicionaessevaloraosaldodaconta

calculaRendimentoquenãorecebeparâmetroalgumedevolveovalordosaldomultiplicadopor0.1

Umesboçodaclasse:

classConta{

doublesaldo;//seusoutrosatributosemétodos

voidsaca(doublevalor){//oquefazeraquidentro?}

voiddeposita(doublevalor){//oquefazeraquidentro?}

doublecalculaRendimento(){//oquefazeraquidentro?}}

Você pode (e deve) compilar seu arquivo java sem que você ainda tenha terminado sua classeConta.Issoevitaráquevocêrecebadezenasdeerrosdecompilaçãodeumavezsó.CrieaclasseConta, coloqueseusatributose,antesdecolocarqualquermétodo,compileoarquivo java.OarquivoConta.classserágerado,masnãopodemos"executá-lo"jáqueessaclassenãotemummain.Dequalquerforma,avantageméqueassimverificamosquenossaclasseConta jáestátomandoformaeestáescritaemsintaxecorreta.

Esseéumprocessoincremental.Procuredesenvolverassimseusexercícios,paranãodescobrirsónofimdocaminhoquealgoestavamuitoerrado.

Umesboçodaclassequepossuiomain:

classTestaConta{

publicstaticvoidmain(String[]args){Contac1=newConta();

.

Page 66: FJ-11 Java e Orientação a Objetos

c1.titular="Hugo";c1.numero=123;c1.agencia="45678-9";c1.saldo=50.0;c1.dataDeAbertura="04/06/2015";

c1.deposita(100.0);System.out.println("saldoatual:"+c1.saldo);System.out.println("rendimentomensal:"+c1.calculaRendimento());}}

Incremente essa classe. Faça outros testes, imprima outros atributos e invoque osmétodos quevocêcriouamais.

Lembre-se de seguir a convenção java, isso é importantíssimo. Isto é, preste atenção nasmaiúsculas e minúsculas, seguindo o seguinte exemplo: nomeDeAtributo, nomeDeMetodo ,nomeDeVariavel,NomeDeClasse,etc...

TODASASCLASSESNOMESMOARQUIVO?

Vocêatépodecolocartodasasclassesnomesmoarquivoeapenascompilaressearquivo.Elevaigerarum.classparacadaclassepresentenele.

Porém, por umaquestãode organização, é boa prática criar um arquivo.java paracadaclasse.Emcapítulosposteriores, veremos tambémdeterminadoscasosnosquaisvocêseráobrigadoadeclararcadaclasseemumarquivoseparado.

Essa separação não é importante nesse momento do aprendizado, mas se quiser irpraticandosemterquecompilarclasseporclasse,vocêpodedizerparaojavaccompilartodososarquivosjavadeumavez:

javac*.java

3. CrieummétodorecuperaDadosParaImpressao(),quenãorecebeparâmetromasdevolveotextocomtodasasinformaçõesdanossacontaparaefetuarmosaimpressão.

Dessamaneira,vocênãoprecisa ficarcopiandoecolandoummontedeSystem.out.println()paracadamudançaetestequefizercomcadaumdeseusfuncionários,vocêsimplesmentevaifazer:

Contac1=newConta();//brincadeirascomc1....System.out.println(c1.recuperaDadosParaImpressao());

VeremosmaisafrenteométodotoString,queéumasoluçãomuitomaiseleganteparamostrararepresentaçãodeumobjetocomoString,alémdenãojogartudoproSystem.out (sósevocêdesejar).

.

Page 67: FJ-11 Java e Orientação a Objetos

Oesqueletodométodoficariaassim:

classConta{

//seusoutrosatributosemétodos

StringrecuperaDadosParaImpressao(){Stringdados="Titular:"+this.titular;dados+="\nNúmero:"+this.numero;//imprimiraquiosoutrosatributos...//tambémpodeimprimirthis.calculaRendimento()returndados;}}

4. Construaduascontascomonewecompare-oscomo==.Eseelestiveremosmesmosatributos?Paraissovocêvaiprecisarcriaroutrareferência:

Contac1=newConta();c1.titular="Danilo";c1.saldo=100;

Contac2=newConta();c2.titular="Danilo";c2.saldo=100;

if(c1==c2){System.out.println("iguais");}else{System.out.println("diferentes");}

5. Crieduasreferênciasparaamesmaconta,compare-oscomo==.Tiresuasconclusões.Paracriarduasreferênciaspramesmaconta:

Contac1=newConta():c1.titular="Hugo";c1.saldo=100;

Contac2=c1;

Oqueacontececomoifdoexercícioanterior?

6. (opcional)EmvezdeutilizarumaStringpararepresentaradata,crieumaoutraclasse,chamadaData.Elapossui3camposint,paradia,mêseano.Façacomquesuacontapasseausá-la. (éparecidocomoúltimoexemplodaexplicação,emqueaConta passou a ter referênciaparaumCliente).

classConta{DatadataDeAbertura;//qualéovalordefaultaqui?//seusoutrosatributosemétodos}

classData{intdia;intmes;intano;}

.

Page 68: FJ-11 Java e Orientação a Objetos

ModifiquesuaclasseTestaContaparaquevocêcrieumaDataeatribuaelaaConta:

Contac1=newConta();//...Datadata=newData();//ligação!c1.dataDeAbertura=data;

FaçaodesenhodoestadodamemóriaquandocriarmosumConta.

7. (opcional)ModifiqueseumétodorecuperaDadosParaImpressaoparaqueeledevolvaovalordadataDeAberturadaquelaConta:

classConta{

//seusoutrosatributosemétodosDatadataDeAbertura;

StringrecuperaDadosParaImpressao(){Stringdados="\nTitular:"+this.titular;//imprimiraquiosoutrosatributos...

dados+="\nDia:"+this.dataDeAbertura.dia;dados+="\nMês:"+this.dataDeAbertura.mes;dados+="\nAno:"+this.dataDeAbertura.ano;returndados;}}

Teste-o. O que acontece se chamarmos o método recuperaDadosParaImpressao antes deatribuirmosumadataparaestaConta?

8. (opcional) O que acontece se você tentar acessar um atributo diretamente na classe? Como, porexemplo:

Conta.saldo=1234;

Essecódigofazsentido?Eeste:

Conta.calculaRendimento();

FazsentidoperguntarparaoesquemadaContaseuvaloranual?

9. (opcional-avançado)CrieummétodonaclasseDataquedevolvaovalorformatadodadata,istoé,devolvaumaStringcom"dia/mes/ano".IssoparaqueométodorecuperaDadosParaImpressaodaclasseContapossaficarassim:

classConta{//atributosemetodos

StringrecuperaDadosParaImpressao(){//imprimeoutrosatributos...dados+="\nDatadeabertura:"+this.dataDeAbertura.formatada();returndados;}}

.

Page 69: FJ-11 Java e Orientação a Objetos

1. Ummétodopode chamar elemesmo.Chamamos issoderecursão.Vocêpoderesolver a série deFibonacciusandoummétodoquechamaelemesmo.Oobjetivoévocêcriarumaclasse,quepossaserusadadaseguintemaneira:

Fibonaccifibonacci=newFibonacci();for(inti=1;i<=6;i++){intresultado=fibonacci.calculaFibonacci(i);System.out.println(resultado);}

AquiimprimiráasequênciadeFibonacciatéasextaposição,istoé:1,1,2,3,5,8.

EstemétodocalculaFibonacci não pode ter nenhum laço, só pode chamar elemesmo comométodo.Pensenelecomoumafunção,queusaaprópriafunçãoparacalcularoresultado.

2. Porqueomodoacimaéextremamentemaislentoparacalcularasériedoqueomodoiterativo(queseusaumlaço)?

3. Escreva o método recursivo novamente, usando apenas uma linha. Para isso, pesquise sobre ooperadorcondicionalternário.(ternaryoperator)

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design, Infra,Front-Ende

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Oobjetivodosexercíciosaseguiréfixaroconceitodeclasseseobjetos,métodoseatributos.Dadaaestruturadeumaclasse,bastatraduzi-laparaalinguagemJavaefazerusodeumobjetodamesmaemumprogramasimples.

Sevocêestácomdificuldadeemalgumapartedessecapítulo,aproveiteetreinetudooquevimosnospequenosprogramasabaixo:

Programa1

4.13DESAFIOS

Agoraéamelhorhoraderespirarmaistecnologia!

4.14FIXANDOOCONHECIMENTO

.

Page 70: FJ-11 Java e Orientação a Objetos

Classe:PessoaAtributos:nome,idade.Método:voidfazAniversario()

Crieumapessoa,coloqueseunomee idade iniciais, façaalgunsaniversários(aumentandoaidade)eimprimaseunomeesuaidade.

Programa2

Classe:PortaAtributos:aberta,cor,dimensaoX,dimensaoY,dimensaoZMétodos:voidabre()voidfecha()voidpinta(Strings)booleanestaAberta()

Crieumaporta,abraefecheamesma,pinte-adediversascores,alteresuasdimensõeseuseométodoestaAbertaparaverificarseelaestáaberta.

Programa3

Classe:CasaAtributos:cor,porta1,porta2,porta3Método:voidpinta(Strings),intquantasPortasEstaoAbertas()

Crieumacasaepinte-a.Crietrêsportasecoloque-asnacasa;abraefecheasmesmascomodesejar.UtilizeométodoquantasPortasEstaoAbertasparaimprimironúmerodeportasabertas.

.

Page 71: FJ-11 Java e Orientação a Objetos

CAPÍTULO5

"Amarcadohomem imaturo éque ele quermorrernobrementeporuma causa, enquantoamarcadohomemmaduroéquerervivermodestamenteporuma."--J.D.Salinger

Aotérminodessecapítulo,vocêserácapazde:

controlar o acesso aos seus métodos, atributos e construtores através dos modificadoresprivateepublic;escrevermétodosdeacessoaatributosdotipogettersesetters;escreverconstrutoresparasuasclasses;utilizarvariáveisemétodosestáticos.

Um dos problemasmais simples que temos no nosso sistema de contas é que ométodo sacapermite sacar mesmo que o saldo seja insuficiente. A seguir você pode lembrar como está a classeConta:

classConta{Stringtitular;intnumero;doublesaldo;

//..

voidsaca(doublevalor){this.saldo=this.saldo-valor;}}

Aclasseaseguirmostracomoépossívelultrapassarolimitedesaqueusandoométodosaca:

classTestaContaEstouro1{publicstaticvoidmain(String[]args){ContaminhaConta=newConta();minhaConta.saldo=1000.0;minhaConta.saca(50000);//saldoésó1000!!}}

Podemosincluirumifdentrodonossométodosaca()paraevitarasituaçãoqueresultariaem

MODIFICADORESDEACESSOEATRIBUTOSDECLASSE

5.1CONTROLANDOOACESSO

.

Page 72: FJ-11 Java e Orientação a Objetos

umacontaemestadoinconsistente,comseusaldoabaixode0.Fizemosissonocapítulodeorientaçãoaobjetosbásica.

Apesardemelhorarbastante,aindatemosumproblemamaisgrave:ninguémgarantequeousuárioda classe vai sempre utilizar o método para alterar o saldo da conta. O código a seguir faz issodiretamente:

classTestaContaEstouro2{publicstaticvoidmain(String[]args){ContaminhaConta=newConta();minhaConta.saldo=-200;//saldoestáabaixode0}}

Comoevitarisso?Umaideiasimplesseriatestarsenãoestamossacandoumvalormaiorqueosaldotodavezqueformosalterá-lo:

classTestaContaEstouro3{

publicstaticvoidmain(String[]args){//aContaContaminhaConta=newConta();minhaConta.saldo=100;

//queromudarosaldopara-200doublenovoSaldo=-200;

//testaseonovoSaldoéválidoif(novoSaldo<0){//System.out.println("Nãopossomudarparaessesaldo");}else{minhaConta.saldo=novoSaldo;}}}

Essecódigoiriaserepetirao longodetodanossaaplicaçãoe,pior,alguémpodeesquecerdefazeressacomparaçãoemalgummomento,deixandoacontanasituaçãoinconsistente.AmelhorformaderesolverissoseriaforçarquemusaaclasseContaainvocarométodosacaenãopermitiroacessodiretoaoatributo.ÉomesmocasodavalidaçãodeCPF.

Para fazer issono Java,bastadeclararqueos atributosnãopodemser acessadosde forada classeatravésdapalavrachaveprivate:

classConta{privatedoublesaldo;//...}

privateéummodificadordeacesso(tambémchamadodemodificadordevisibilidade).

Marcandoumatributo comoprivado, fechamoso acesso aomesmo em relação a todas as outrasclasses,fazendocomqueoseguintecódigonãocompile:

classTestaAcessoDireto{

.

Page 73: FJ-11 Java e Orientação a Objetos

publicstaticvoidmain(String[]args){ContaminhaConta=newConta();//nãocompila!vocênãopodeacessaroatributoprivadodeoutraclasseminhaConta.saldo=1000;}}

TesteAcessoDireto.java:5saldohasprivateaccessinContaminhaConta.saldo=1000;^1error

Na orientação a objetos, é prática quase que obrigatória proteger seus atributos com private.(discutiremosoutrosmodificadoresdeacessoemoutroscapítulos).

Cadaclasseéresponsávelporcontrolarseusatributos,portantoeladevejulgarseaquelenovovaloréválido ou não! Esta validação não deve ser controlada por quem está usando a classe e sim por elamesma, centralizando essa responsabilidade e facilitando futurasmudançasno sistema.Muitasoutrasvezes nem mesmo queremos que outras classes saibam da existência de determinado atributo,escondendo-oporcompleto,jáqueeledizrespeitoaofuncionamentointernodoobjeto.

Repareque,queminvocaométodosacanãofazamenorideiadequeexisteumaverificaçãoparaovalordosaque.Paraquemforusaressaclasse,bastasaberoqueométodofazenãocomoexatamenteeleofaz(oqueummétodofazésempremaisimportantedoquecomoelefaz:mudaraimplementaçãoéfácil,jámudaraassinaturadeummétodovaigerarproblemas).

A palavra chave private também pode ser usada para modificar o acesso a um método. Talfuncionalidade é utilizada em diversos cenários: quando existe um método que serve apenas paraauxiliar a própria classe e quando há código repetido dentro de doismétodos da classe são osmaiscomuns. Sempre devemos expôr o mínimo possível de funcionalidades, para criar um baixoacoplamentoentreasnossasclasses.

Damesmamaneira que temosoprivate, temosomodificadorpublic, quepermite a todosacessaremumdeterminadoatributooumétodo:

classConta{//...publicvoidsaca(doublevalor){//possosacaratésaldoif(valor>this.saldo){System.out.println("Nãopossosacarumvalormaiorqueosaldo!");}else{this.saldo=this.saldo-valor;}}}

.

Page 74: FJ-11 Java e Orientação a Objetos

EQUANDONÃOHÁMODIFICADORDEACESSO?

Atéagora,tínhamosdeclaradovariáveisemétodossemnenhummodificadorcomoprivateepublic . Quando isto acontece, o seu método ou atributo fica num estado de visibilidadeintermediárioentreoprivateeopublic,queveremosmaisprafrente,nocapítulodepacotes.

Émuitocomum,efaztodosentido,queseusatributossejamprivateequasetodosseusmétodossejampublic(nãoéumaregra!).Destaforma,todaconversadeumobjetocomoutroéfeitaportrocademensagens,istoé,acessandoseusmétodos.Algomuitomaiseducadoquemexerdiretamenteemumatributoquenãoéseu!

Melhorainda!OdiaemqueprecisarmosmudarcomoérealizadoumsaquenanossaclasseConta,adivinhe onde precisaríamosmodificar? Apenas nométodo saca, o que faz pleno sentido. Comoexemplo,imaginecobrarCPMFdecadasaque:bastavocêmodificarali,enenhumoutrocódigo,foraaclasseConta, precisará ser recompilado.Mais: as classes queusamessemétodonemprecisam ficarsabendode talmodificação!Você precisa apenas recompilar aquela classe e substituir aquele arquivo.class.Ganhamosmuitoemesconderofuncionamentodonossométodonahoradedarmanutençãoefazermodificações.

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelum eobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

Oquecomeçamosavernessecapítuloéaideiadeencapsular,istoé,escondertodososmembrosdeumaclasse (comovimosacima), alémde esconder como funcionamas rotinas (no casométodos)donossosistema.

EditoraCasadoCódigocomlivrosdeumaformadiferente

5.2ENCAPSULAMENTO

.

Page 75: FJ-11 Java e Orientação a Objetos

Encapsularéfundamentalparaqueseusistemasejasuscetívelamudanças:nãoprecisaremosmudaruma regra de negócio em vários lugares,mas sim em apenas um único lugar, já que essa regra estáencapsulada.(vejaocasodométodosaca)

Oconjuntodemétodospúblicosdeumaclasseétambémchamadodeinterfacedaclasse,poisestaéaúnicamaneiraaqualvocêsecomunicacomobjetosdessaclasse.

PROGRAMANDOVOLTADOPARAAINTERFACEENÃOPARAAIMPLEMENTAÇÃO

É sempre bomprogramarpensandona interface da sua classe, como seus usuários a estarãoutilizando,enãosomenteemcomoelavaifuncionar.

A implementaçãoemsi, o conteúdodosmétodos,não tem tanta importânciaparaousuáriodessaclasse,umavezqueelesóprecisasaberoquecadamétodopretendefazer,enãocomoelefaz,poisistopodemudarcomotempo.

EssafrasevemdolivroDesignPatterns,deEricGammaetal.Umlivrocultuadonomeiodaorientaçãoaobjetos.

Semprequevamosacessarumobjeto,utilizamossuainterface.Existemdiversasanalogiasfáceisnomundoreal:

Quandovocêdirigeumcarro,oqueteimportasãoospedaiseovolante(interface)enãoomotor que você está usando (implementação). É claro que ummotor diferente pode te darmelhoresresultados,masoqueelefazéomesmoqueummotormenospotente,adiferençaestá em como ele faz. Para trocar um carro a álcool para um a gasolina você não precisareaprender a dirigir! (trocar a implementação dos métodos não precisa mudar a interface,

.

Page 76: FJ-11 Java e Orientação a Objetos

fazendocomqueasoutrasclassescontinuemusandoelesdamesmamaneira).

Todos os celulares fazem a mesma coisa (interface), eles possuem maneiras (métodos) dediscar, ligar, desligar, atender, etc. O que muda é como eles fazem (implementação), masreparequeparaefetuarumaligaçãopoucoimportaseocelularéiPhoneouAndroid,issoficaencapsuladonaimplementação(queaquisãooscircuitos).

JátemosconhecimentossuficientespararesolveraqueleproblemadavalidaçãodeCPF:

classCliente{privateStringnome;privateStringendereco;privateStringcpf;privateintidade;

publicvoidmudaCPF(Stringcpf){validaCPF(cpf);this.cpf=cpf;}

privatevoidvalidaCPF(Stringcpf){//sériederegrasaqui,falhacasonãosejaválido}

//..}

SealguémtentarcriarumClienteenãousaromudaCPFparaalterarumcpfdiretamente,vaireceberumerrodecompilação,jáqueoatributoCPFéprivado.EodiaquevocênãoprecisarverificaroCPFdequemtemmaisde60anos?Seumétodoficaoseguinte:

publicvoidmudaCPF(Stringcpf){if(this.idade<=60){validaCPF(cpf);}this.cpf=cpf;}

OcontrolesobreoCPFestácentralizado:ninguémconsegueacessá-losempassarporaí,aclasseClienteéaúnicaresponsávelpelosseusprópriosatributos!

Omodificadorprivate fazcomqueninguémconsigamodificar,nemmesmoler,oatributoemquestão.Comisso,temosumproblema:comofazerparamostrarosaldodeumaConta,jáquenemmesmopodemosacessá-loparaleitura?

Precisamosentãoarranjarumamaneiradefazeresseacesso.Semprequeprecisamosarrumarumamaneiradefazeralgumacoisacomumobjeto,utilizamosdemétodos!Vamosentãocriarummétodo,digamospegaSaldo,pararealizaressasimplestarefa:

classConta{

5.3GETTERSESETTERS

.

Page 77: FJ-11 Java e Orientação a Objetos

privatedoublesaldo;

//outrosatributosomitidos

publicdoublepegaSaldo(){returnthis.saldo;}

//deposita()esaca()omitidos}

Paraacessarmososaldodeumaconta,podemosfazer:

classTestaAcessoComPegaSaldo{publicstaticvoidmain(String[]args){ContaminhaConta=newConta();minhaConta.deposita(1000);System.out.println("Saldo:"+minhaConta.pegaSaldo());}}

Parapermitiroacessoaosatributos(jáqueelessãoprivate)deumamaneiracontrolada,apráticamaiscomumécriardoismétodos,umqueretornaovaloreoutroquemudaovalor.

Aconvençãoparaessesmétodosédecolocarapalavragetousetantesdonomedoatributo.Porexemplo,anossacontacomsaldo,limiteetitularficaassim,nocasodagentedesejardaracessoaleituraeescritaatodososatributos:

classConta{

privateStringtitular;privatedoublesaldo;

publicdoublegetSaldo(){returnthis.saldo;}

publicvoidsetSaldo(doublesaldo){this.saldo=saldo;}

publicStringgetTitular(){returnthis.titular;}

publicvoidsetTitular(Stringtitular){this.titular=titular;}}

Éumamápráticacriarumaclassee,logoemseguida,criargettersesettersparatodosseusatributos.Vocêsódevecriarumgetterousettersetiverarealnecessidade.ReparequenesseexemplosetSaldonãodeveriatersidocriado,jáquequeremosquetodosusemdeposita()esaca().

Outrodetalheimportante,ummétodogetXnãonecessariamenteretornaovalordeumatributoquechamaX doobjeto emquestão. Isso é interessanteparao encapsulamento. Imagine a situação:

.

Page 78: FJ-11 Java e Orientação a Objetos

queremosqueobancosempremostrecomosaldoovalordo limite somadoao saldo (umapráticacomumdosbancosquecostuma iludir seusclientes).Poderíamos semprechamarc.getLimite()+c.getSaldo(),masissopoderiagerarumasituaçãode"replaceall"quandoprecisássemosmudarcomoo saldo é mostrado. Podemos encapsular isso em um método e, porque não, dentro do própriogetSaldo?Repare:

classConta{

privateStringtitular;privatedoublesaldo;privatedoublelimite;//adicionandoumlimiteaconta

publicdoublegetSaldo(){returnthis.saldo+this.limite;}

//deposita()saca()etransfere()omitidos

publicStringgetTitular(){returnthis.titular;}

publicvoidsetTitular(Stringtitular){this.titular=titular;}}

OcódigoacimanempossibilitaachamadadométodogetLimite(), elenãoexiste.Enemdeveexistir enquanto não houver essa necessidade.OmétodogetSaldo() não devolve simplesmente osaldo...esimoquequeremosquesejamostradocomosefosseosaldo.Utilizargettersesettersnãosóajudavocêaprotegerseusatributos,comotambémpossibilita terdemudaralgoemumsó lugar...chamamosissodeencapsulamento,poisescondeamaneiracomoosobjetosguardamseusdados.Éumapráticamuitoimportante.

Nossaclasseestátotalmentepronta?Istoé,existeachancedelaficarcomsaldomenorque0?Podeparecerquenão,mas,esedepositarmosumvalornegativonaconta?Ficaríamoscommenosdinheiroqueopermitido, jáquenãoesperávamospor isso.Paranosprotegerdissobastamudarmosométododeposita()paraqueeleverifiqueseovalorénecessariamentepositivo.

Depois disso precisaríamos mudar mais algum outro código? A resposta é não, graças aoencapsulamentodosnossosdados.

.

Page 79: FJ-11 Java e Orientação a Objetos

CUIDADOCOMOSGETTERSESETTERS!

Comojádito,nãodevemoscriargettersesetterssemummotivoexplicito.NoblogdaCaelumháumartigoqueilustrabemessescasos:

http://blog.caelum.com.br/2006/09/14/nao-aprender-oo-getters-e-setters/

Quandousamosapalavrachavenew,estamosconstruindoumobjeto.Semprequandoonew échamado,eleexecutaoconstrutordaclasse.Oconstrutordaclasseéumblocodeclaradocomomesmonomequeaclasse:

classConta{Stringtitular;intnumero;doublesaldo;

//construtorConta(){System.out.println("Construindoumaconta.");}

//..}

Então,quandofizermos:

Contac=newConta();

Amensagem"construindoumaconta"aparecerá.Écomoumarotinadeinicializaçãoqueéchamadasemprequeumnovoobjetoécriado.Umconstrutorpodeparecer,masnãoéummétodo.

OCONSTRUTORDEFAULT

Atéagora,asnossasclassesnãopossuíamnenhumconstrutor.Entãocomoéqueerapossíveldarnew,setodonewchamaumconstrutorobrigatoriamente?

Quando você não declara nenhum construtor na sua classe, o Java cria um para você. Esseconstrutoréoconstrutordefault,elenãorecebenenhumargumentoeocorpodeleévazio.

A partir do momento que você declara um construtor, o construtor default não é maisfornecido.

5.4CONSTRUTORES

.

Page 80: FJ-11 Java e Orientação a Objetos

Ointeressanteéqueumconstrutorpodereceberumargumento,podendoassiminicializaralgumtipodeinformação:

classConta{Stringtitular;intnumero;doublesaldo;

//construtorConta(Stringtitular){this.titular=titular;}

//..}

Esse construtor recebe o titular da conta. Assim, quando criarmos uma conta, ela já terá umdeterminadotitular.

Stringcarlos="Carlos";Contac=newConta(carlos);System.out.println(c.titular);

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

Tudoestavafuncionandoatéagora.Paraqueutilizamosumconstrutor?

Aideiaébemsimples.Setodacontaprecisadeumtitular,comoobrigartodososobjetosqueforemcriadosaterumvalordessetipo?BastacriarumúnicoconstrutorquerecebeessaString!

O construtor se resume a isso! Dar possibilidades ou obrigar o usuário de uma classe a passarargumentosparaoobjetoduranteoprocessodecriaçãodomesmo.

Porexemplo,nãopodemosabrirumarquivoparaleiturasemdizerqualéonomedoarquivoquedesejamos ler! Portanto, nadamais natural que passar uma String representando o nome de um

JáconheceoscursosonlineAlura?

5.5ANECESSIDADEDEUMCONSTRUTOR

.

Page 81: FJ-11 Java e Orientação a Objetos

arquivonahoradecriarumobjetodotipodeleituradearquivo,equeissosejaobrigatório.

Vocêpodetermaisdeumconstrutornasuaclassee,nomomentodonew,oconstrutorapropriadoseráescolhido.

CONSTRUTOR:UMMÉTODOESPECIAL?

Umconstrutornão é ummétodo.Algumas pessoas o chamamde ummétodo especial,masdefinitivamentenãoé,jáquenãopossuiretornoesóéchamadoduranteaconstruçãodoobjeto.

CHAMANDOOUTROCONSTRUTOR

Umconstrutor só pode rodar durante a construçãodo objeto, isto é, vocênunca conseguiráchamaroconstrutoremumobjetojáconstruído.Porém,duranteaconstruçãodeumobjeto,vocêpodefazercomqueumconstrutorchameoutro,paranãoterdeficarcopiandoecolando:

classConta{Stringtitular;intnumero;doublesaldo;

//construtorConta(Stringtitular){//fazmaisumasériedeinicializaçõeseconfiguraçõesthis.titular=titular;}

Conta(intnumero,Stringtitular){this(titular);//chamaoconstrutorquefoideclaradoacimathis.numero=numero;}

//..}

Existeumoutromotivo,ooutroladodosconstrutores:facilidade.Àsvezes,criamosumconstrutorquerecebediversosargumentosparanãoobrigarousuáriodeumaclasseachamardiversosmétodosdotipo'set'.

NonossoexemplodoCPF,podemosforçarqueaclasseClienterecebanomínimooCPF,dessamaneiraumClientejáseráconstruídoecomumCPFválido.

.

Page 82: FJ-11 Java e Orientação a Objetos

JAVABEAN

Quando criamos uma classe com todos os atributos privados, seus getters e setters e umconstrutorvazio(padrão),naverdadeestamoscriandoumJavaBean(masnãoconfundacomEJB,queéEnterpriseJavaBeans).

Nosso banco também quer controlar a quantidade de contas existentes no sistema. Comopoderíamosfazeristo?Aideiamaissimples:

Contac=newConta();totalDeContas=totalDeContas+1;

Aqui, voltamos em um problema parecido com o da validação de CPF. Estamos espalhando umcódigo por toda aplicação, e quem garante que vamos conseguir lembrar de incrementar a variáveltotalDeContastodavez?

Tentamosentão,passarparaaseguinteproposta:

classConta{privateinttotalDeContas;//...

Conta(){this.totalDeContas=this.totalDeContas+1;}}

Quandocriarmosduascontas,qualseráovalordototalDeContasdecadaumadelas?Vaiser1.Poiscadaumatemessavariável.Oatributoédecadaobjeto.

Seria interessante então, que essa variável fosse única, compartilhada por todos os objetos dessaclasse.Dessamaneira,quandomudasseatravésdeumobjeto,ooutroenxergariaomesmovalor.Parafazerissoemjava,declaramosavariávelcomostatic.

privatestaticinttotalDeContas;

Quando declaramos um atributo como static, ele passa a não ser mais um atributo de cadaobjeto,esimumatributodaclasse,ainformaçãoficaguardadapelaclasse,nãoémaisindividualparacadaobjeto.

Paraacessarmosumatributoestático,nãousamosapalavrachavethis,massimonomedaclasse:

classConta{privatestaticinttotalDeContas;//...

5.6ATRIBUTOSDECLASSE

.

Page 83: FJ-11 Java e Orientação a Objetos

Conta(){Conta.totalDeContas=Conta.totalDeContas+1;}}

Já que o atributo é privado, como podemos acessar essa informação a partir de outra classe?Precisamosdeumgetterparaele!

classConta{privatestaticinttotalDeContas;//...

Conta(){Conta.totalDeContas=Conta.totalDeContas+1;}

publicintgetTotalDeContas(){returnConta.totalDeContas;}}

Comofazemosentãoparasaberquantascontasforamcriadas?

Contac=newConta();inttotal=c.getTotalDeContas();

Precisamoscriarumacontaantesdechamarométodo!Issonãoélegal,poisgostaríamosdesaberquantascontasexistemsemprecisarteracessoaumobjetoconta.Aideiaaquiéamesma,transformaressemétodoquetodoobjetocontatememummétododetodaaclasse.Usamosapalavrastaticdenovo,mudandoométodoanterior.

publicstaticintgetTotalDeContas(){returnConta.totalDeContas;}

Paraacessaressenovométodo:

inttotal=Conta.getTotalDeContas();

ReparequeestamoschamandoummétodonãocomumareferênciaparaumaConta,esimusandoonomedaclasse.

MÉTODOSEATRIBUTOSESTÁTICOS

Métodoseatributosestáticossópodemacessaroutrosmétodoseatributosestáticosdamesmaclasse,oquefaztodosentidojáquedentrodeummétodoestáticonãotemosacessoàreferênciathis,poisummétodoestáticoéchamadoatravésdaclasse,enãodeumobjeto.

Ostaticrealmentetrazum"cheiro"procedural,porémemmuitasvezesénecessário.

.

Page 84: FJ-11 Java e Orientação a Objetos

Em algumas empresas, o UML é amplamente utilizado. Às vezes, o programador recebe oUML já pronto, completo, e só deve preencher a implementação, devendo seguir à risca oUML.Oquevocêachadessaprática?Quaisasvantagensedesvantagens.

Seumaclassesótematributosemétodosestáticos,queconclusõespodemostirar?Oquelhepareceummétodoestáticoemcasoscomoesses?

Nocasodeatributosbooleanos,pode-seusarnolugardogetosufixois.Dessamaneira,caso tivéssemos um atributo booleano ligado, em vez de getLigado poderíamos terisLigado.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

1. Adicioneomodificadordevisibilidade(private, senecessário)paracadaatributo emétododaclasseConta.TentecriarumaContanomainemodificaroulerumdeseusatributosprivados.Oqueacontece?

2. CrieapenasosgettersesettersnecessáriosdasuaclasseConta.Pensesempreseéprecisocriarcadaumdeles.Porexemplo:

classConta{privateStringtitular;

//...

publicStringgetTitular(){

5.7UMPOUCOMAIS...

SaberinglêsémuitoimportanteemTI

5.8EXERCÍCIOS:ENCAPSULAMENTO,CONSTRUTORESESTATIC

.

Page 85: FJ-11 Java e Orientação a Objetos

returnthis.titular;}

publicvoidsetTitular(Stringtitular){this.titular=titular;}}

Nãocopieecole!Aproveiteparapraticarsintaxe.LogopassaremosausaroEclipseeaísimteremosprocedimentosmaissimplesparaestetipodetarefa.

ReparequeométodocalculaRendimentoparecetambémumgetter.Aliás,seriacomumalguémnomeá-lo de getRendimento . Getters não precisam apenas retornar atributos. Eles podemtrabalharcomessesdados.

3. ModifiquesuasclassesqueacessamemodificamatributosdeumaContaparautilizarosgettersesettersrecémcriados.

Porexemplo,ondevocêencontra:

c.titular="Batman";System.out.println(c.titular);

passapara:

c.setTitular("Batman");System.out.println(c.getTitular());

4. FaçacomquesuaclasseContapossareceber,opcionalmente,onomedotitulardaContaduranteacriaçãodoobjeto.Utilizeconstrutoresparaobteresseresultado.

Dica:utilizeumconstrutorsemargumentos também,paraocasodeapessoanãoquererpassarotitulardaConta.

Seriaalgocomo:

classConta{publicConta(){//construtorsemargumentos}

publicConta(Stringtitular){//construtorquerecebeotitular}}

Porquevocêprecisadoconstrutorsemargumentosparaqueapassagemdonomesejaopcional?

5. (opcional)AdicioneumatributonaclasseContade tipoint que se chama identificador.Esseidentificador deve ter um valor único para cada instância do tipo Conta. A primeira Containstanciada tem identificador 1, a segunda 2, e assim por diante. Você deve utilizar os recursosaprendidosaquipararesolveresseproblema.

.

Page 86: FJ-11 Java e Orientação a Objetos

Crieumgetterparaoidentificador.Devemosterumsetter?

6. (opcional)Comogarantirquedatascomo31/2/2012nãosejamaceitaspelasuaclasseData?

7. (opcional) Suponha que temos a classePessoaFisica que tem um CPF como atributo. Comogarantir que pessoa física alguma tenha CPF invalido, nem seja criada PessoaFisica sem cpfinicial?(Suponhaquejáexisteumalgoritmodevalidaçãodecpf:bastapassarocpfporummétodovalida(Stringx)...)

1. Porqueessecódigonãocompila?

classTeste{intx=37;publicstaticvoidmain(String[]args){System.out.println(x);}}

2. ImaginequetenhaumaclasseFabricaDeCarroequerogarantirquesóexisteumobjetodessetipoemtodaamemória.NãoexisteumapalavrachaveespecialparaistoemJava,entãoteremosdefazernossa classe de tal maneira que ela respeite essa nossa necessidade. Como fazer isso? (pesquise:singletondesignpattern)

5.9DESAFIOS

.

Page 87: FJ-11 Java e Orientação a Objetos

CAPÍTULO6

"Dá-seimportânciaaosantepassadosquandojánãotemosnenhum."--FrançoisChateaubriand

Neste capítulo, você será apresentado aoAmbiente deDesenvolvimento Eclipse e suas principaisfuncionalidades.

OEclipse(http://www.eclipse.org)éumaIDE(integrateddevelopmentenvironment).DiferentedeumaRAD,ondeoobjetivoédesenvolveromaisrápidopossívelatravésdoarrastar-e-soltardomouse,onde montanhas de código são gerados em background, uma IDE te auxilia no desenvolvimento,evitandoseintrometerefazermuitamágica.

OEclipseéaIDElíderdemercado.FormadaporumconsórciolideradopelaIBM,possuiseucódigolivre.

Veremos aqui os principais recursos do Eclipse. Você perceberá que ele evita ao máximo teatrapalhareapenasgeratrechosdecódigosóbvios,sempreaoseucomando.Existemtambémcentenasde plugins gratuitos para gerar diagramasUML, suporte a servidores de aplicação, visualizadores debancodedadosemuitosoutros.

Baixe o Eclipse do site oficial http://www.eclipse.org. Apesar de ser escrito em Java, a bibliotecagráficausadanoEclipse,chamadaSWT,usacomponentesnativosdosistemaoperacional.Porissovocêdevebaixaraversãocorrespondenteaoseusistemaoperacional.

Descompacteoarquivoepronto,bastarodaroexecutável.

OUTRASIDES

UmaoutraIDEopensourcefamosaéoNetbeans,daOracle.(http://www.netbeans.org).

Alémdessas,Oracle,BorlandeaprópriaIBMpossuemIDEscomerciaisealgumasversõesmaisrestritasdeusolivre.

AempresaJetBrainsdesenvolveoIntelliJIDEA,umaIDEpagaquetemganhomuitosadeptos.

ECLIPSEIDE

6.1OECLIPSE

.

Page 88: FJ-11 Java e Orientação a Objetos

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

CliquenoíconedoEclipsenoseuDesktop.

Aprimeiraperguntaqueeletefazéqueworkspacevocêvaiusar.Workspacedefineodiretórioemqueassuasconfiguraçõespessoaiseseusprojetosserãogravados.

Vocêpodedeixarodiretóriopré-definido.

Logoemseguida,uma teladeWelcome seráaberta,ondevocê temdiversos linkspara tutoriais eajuda.CliqueemWorkbench.

AprendasedivertindonaAluraStart!

6.2APRESENTANDOOECLIPSE

.

Page 89: FJ-11 Java e Orientação a Objetos

Feche a tela de Welcome e você verá a tela abaixo. Nesta tela, destacamos as Views (em linhacontínua)easPerspectives(emlinhapontilhada)doEclipse.

6.3VIEWSEPERSPECTIVE

.

Page 90: FJ-11 Java e Orientação a Objetos

Mude para a perspectiva Resource, clicando no ícone ao lado da perspectiva Java, selecionandoOtheredepoisResource.Nestemomento,trabalharemoscomestaperspectiva,antesdadeJava,poiselapossuiumconjuntodeViewsmaissimples.

AViewNavigatormostraaestruturadediretórioassimcomoestánosistemadearquivos.AViewOutlinemostraumresumodasclasses,interfaceseenumeraçõesdeclaradasnoarquivojavaatualmenteeditado(servetambémparaoutrostiposdearquivos).

No menu Window -> Show View -> Other, você pode ver as dezenas de Views que já vem

.

Page 91: FJ-11 Java e Orientação a Objetos

embutidasnoEclipse.Acostume-seasempreprocurarnovasViews,elaspodemteajudaremdiversastarefas.

VáemFile->New->Project.SelecionaJavaProjectecliqueemNext.

6.4CRIANDOUMPROJETONOVO

.

Page 92: FJ-11 Java e Orientação a Objetos

Crieumprojetochamadofj11-contas.

VocêpodechegarnessamesmatelaclicandocomobotãodadiretanoespaçodaViewNavigatoreseguindoomesmomenu.Nestatela,configureseuprojetocomonatelaabaixo:

Isto é, marque "create separate source and output folders", desta maneira seus arquivos java earquivosclassestarãoemdiretóriosdiferentes,paravocêtrabalhardeumamaneiramaisorganizada.

.

Page 93: FJ-11 Java e Orientação a Objetos

CliqueemFinish.OEclipsepediráparatrocaraperspectivaparaJava;escolha"No"parapermaneceremResource.NaViewNavigator,vocêveráonovoprojetoesuaspastasearquivos:

VamosiniciarnossoprojetocriandoaclasseConta.Paraisso,váemFile->New->Other->Class.CliqueemNextecrieaclasseseguindoatelaabaixo:

CliqueemFinish.OEclipsepossuidiversoswizards,masusaremosomínimodeles.Ointeressanteéusarocodeassistequickfixesqueaferramentapossuieveremosemseguida.Nãoseatenteàsmilharesdeopçõesdecadawizard,apartemaisinteressantedoEclipsenãoéessa.

EscrevaométododepositacomoabaixoenotequeoEclipsereclamadeerroemthis.saldopoisesteatributonãoexiste.

.

Page 94: FJ-11 Java e Orientação a Objetos

VamosusarorecursodoEclipsedequickfix.ColoqueocursoremcimadoerroeaperteCtrl+1.

O Eclipse sugerirá possíveis formas de consertar o erro; uma delas é, justamente, criar o camposaldonaclasseConta,queénossoobjetivo.Cliquenestaopção.

Este recurso de quick fixes, acessível pelo Ctrl+1, é uma das grandes facilidades do Eclipse e éextremamentepoderoso.Atravésdele épossível corrigirboapartedos errosnahoradeprogramar e,comofizemos,economizaradigitaçãodecertoscódigosrepetitivos.Nonossoexemplo,nãoprecisamoscriarocampoantes;oEclipsefazissoparanós.Eleatéacertaatipagem,jáqueestamossomandoeleaumdouble.Oprivateécolocadopormotivosquejáestudamos.

VáaomenuFile->Saveparagravar.Control+Stemomesmoefeito.

.

Page 95: FJ-11 Java e Orientação a Objetos

Conheça a Casa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Com a curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

6.5CRIANDOOMAIN

.

Page 96: FJ-11 Java e Orientação a Objetos

CrieumanovaclassechamadaPrincipal.Vamoscolocarummétodomain para testarnossaConta.Emvezdedigitartodoométodomain,vamosusarocodeassistdoEclipse.EscrevasómaineaperteCtrl+Espaçologoemseguida.

OEclipsesugeriráacriaçãodométodomaincompleto;selecioneestaopção.Ocontrol+espaçoéchamadodecodeassist.Assim comoos quick fixes sãode extrema importância.Experimenteusar ocodeassistemdiversoslugares.

Dentrodométodomain,comeceadigitaroseguintecódigo:

Contaconta=newConta();conta.deposita(100.0);

Observe que, na hora de invocar o método sobre o objeto conta, o Eclipse sugere os métodospossíveis.Esterecursoébastanteútil,principalmentequandoestivermosprogramandocomclassesquenãosãoasnossas,comodaAPIdoJava.OEclipseacionaesterecursoquandovocêdigitaopontologoapósumobjeto(evocêpodeusaroCtrl+Espaçoparaacioná-lo).

Vamos imprimir o saldo com System.out.println. Mas, mesmo nesse código, o Eclipse nosajuda.EscrevasysoeaperteCtrl+EspaçoqueoEclipseescreveráSystem.out.println()paravocê.

Paraimprimir,chameoconta.getSaldo():

System.out.println(conta.getSaldo());

NotequeoEclipseacusaráerroemgetSaldo()porqueestemétodonãoexistenaclasseConta.VamosusarCtrl+1emcimadoerroparacorrigiroproblema:

.

Page 97: FJ-11 Java e Orientação a Objetos

OEclipsesugerecriarummétodogetSaldo()naclasseConta.Selecioneestaopçãoeométodoseráinseridoautomaticamente.

publicObjectgetSaldo(){//TODOAuto-generatedmethodstubreturnnull;}

Elegeraummétodonãoexatamentecomoqueríamos,poisnemsemprehácomooEclipse terdeantemãoinformaçõessuficientesparaqueeleacerteaassinaturadoseumétodo.ModifiqueométodogetSaldocomosegue:

publicdoublegetSaldo(){returnthis.saldo;}

EssespequenosrecursosdoEclipsesãodeextremautilidade.Dessamaneira,vocêpodeprogramarsem sepreocupar commétodosque aindanão existem, jáque aqualquermomento elepodegeraroesqueleto(apartedaassinaturadométodo).

Vamosrodarométodomaindessanossaclasse.NoEclipse,cliquecomobotãodireitonoarquivoPrincipal.javaeváemRunas...JavaApplication.

6.6EXECUTANDOOMAIN

.

Page 98: FJ-11 Java e Orientação a Objetos

OEclipseabriráumaViewchamadaConsoleondeseráapresentadaasaídadoseuprograma:

Quando você precisar rodar de novo, basta clicar no ícone verde de play na toolbar, que roda oprogramaanterior.Aoladodesseíconetemumasetinhaondesãolistadosos10últimosexecutados.

OEclipse possuimuitos atalhos úteis para o programador. Semdúvida os 3mais importantes deconheceredepraticarsão:

Ctrl+1Acionaoquickfixescomsugestõesparacorreçãodeerros.

Ctrl+EspaçoCompletacódigos

Ctrl+ 3Acionamododedescobertademenu.ExperimentedigitarCtrl+3 e depois digitarggaseenter.OuentãodeCtrl+3edigitenewclass.

Você pode ler muito mais detalhes sobre esses atalhos no blog da Caelum:http://blog.caelum.com.br/as-tres-principais-teclas-de-atalho-do-eclipse/

6.7PEQUENOSTRUQUES

.

Page 99: FJ-11 Java e Orientação a Objetos

Existemdezenasdeoutros.DentreosmaisutilizadospelosdesenvolvedoresdaCaelum,escolhemososseguintesparacomentar:

Ctrl+F11 roda a última classe que você rodou.É omesmoque clicar no ícone verde quepareceumbotãodeplaynabarradeferramentas.

Ctrl+PgUpeCtrl+PgDownNaveganasabasabertas.Útilquandoestivereditandováriosarquivosaomesmotempo.

Ctrl+Shift+FFormataocódigosegundoasconvençõesdoJava

Ctrl+MExpandeaViewatualparaatelatoda(mesmoefeitodedardoiscliquesnotítulodaView)

Ctrl+Shift+LExibetodososatalhospossíveis.

Ctrl+OExibeumoutlinepararápidanavegação

Alt+Shift+XedepoisJRodaomaindaclasseatual.Péssimoparapressionar!MaisfácilvocêdigitarControl+3edepoisdigitarRun!.AbusedesdejádoControl+3

Veremosmaisnodecorrerdocurso,emespecialquandovirmospacotes.

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design, Infra,Front-Ende

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

1. Crieoprojetofj11-contas.Vocêpodeusaroatalhocontrol+nouentãoirnomenuFile->New->Project...->JavaProject.

2. Dentro do projeto fj11-contas , crie a classe Conta . Uma conta deve ter as seguintesinformações:saldo (double),titular(String),numero (int) eagencia (String).Na classeConta, crie osmétodosdeposita esaca comonos capítulos anteriores.Crie tambémuma

Agoraéamelhorhoraderespirarmaistecnologia!

6.8EXERCÍCIOS:ECLIPSE

.

Page 100: FJ-11 Java e Orientação a Objetos

classeTesteDaConta comomain e instancieuma conta.Desta vez, tente abusardo control+espaçoecontrol+1.

Porexemplo:

publ<ctrlespaco>v<ctrlespaco>deposita(do<ctrlespaço>valor){

Reparequeatémesmonomesdevariáveis,elecriaparavocê!Acompanheasdicasdoinstrutor.

Muitasvezes,aocriarmosumobjeto,nemmesmodeclaramosavariável:

newConta();

Vánessalinhaedêcontrol+1.Elevaisugeriredeclararáavariávelpravocê.

3. Imaginequequeremoscriarumsetterdo titularparaaclasseConta.Dentroda classeConta,digite:

setTit<ctrl+espaco>

OutraformaparacriarosgetterseossettersparaosatributosdaclasseConta,éutilizaroatalhocontrol+3enacaixadeseleçãodigiteggas,iniciaisdeGenerateGettersandSetters!

OBS:Nãocrieumsetterparaoatributosaldo!

4. Váparaaclasseque temomain e segureoCONTROLapertado enquanto vocêpassa omousesobreoseucódigo.Reparequetudovirouhyperlink.CliqueemummétodoquevocêestáinvocandonaclasseConta.

Vocêpodeconseguiromesmoefeito,deabriroarquivonoqualométodo foideclarado, deumamaneira ainda mais prática: sem usar o mouse, quando o cursor estiver sobre o que você queranalisar,simplesmentecliqueF3.

5. Dêumcliquedadireitaemumarquivononavigator.EscolhaCompareWith->LocalHistory.Oqueéestatela?

.

Page 101: FJ-11 Java e Orientação a Objetos

6. UseoControl+Shift+Fparaformataroseucódigo.Dessamaneira,elevaiarrumarabagunçadeespaçamentoeentersdoseucódigo.

7. (opcional)Oquesãoosarquivos.projecte.classpath?Leiaoconteúdodeles.

8. (opcional)Cliquedadireitanoprojeto,propriedades.ÉumadastelasmaisimportantesdoEclipse,onde você pode configurar diversas informações para o seu projeto, como compilador, versões,formatadoreoutros.

.

Page 102: FJ-11 Java e Orientação a Objetos

ExisteummenunoEclipsechamadoRefactor.Eletemopçõesbastanteinteressantesparaauxiliarnaalteraçãodecódigoparamelhorarorganizaçãoouclareza.Porexemplo,umadesuasfuncionalidadesétornarpossívelmudaronomedeumavariável,métodooumesmoclassedeformaqueumaalteração(emumlugarsódosistema)atualizetodasasoutrasvezesqueusavamonomeantigo.

Usar bons nomes no seu código é um excelente começo para mantê-lo legível e fácil de darmanutenção! Mas o assunto "Refatoração" não para por aí: quebrar métodos grandes em menores,dividirclassesgrandesemalgumaspequenasemaisconcisas,melhoraroencapsulamento...todasessassãoformasderefatoração.EessemenudoEclipsenosajudaafazerváriasdelas.

6.9DISCUSSÃOEMAULA:REFACTORING

.

Page 103: FJ-11 Java e Orientação a Objetos

CAPÍTULO7

"Umadiscussãoprolongadasignificaqueambasaspartesestãoerradas"--Voltaire

Aotérminodessecapítulo,vocêserácapazde:

separarsuasclassesempacotes;preparararquivossimplesparadistribuição.

Quando um programador utiliza as classes feitas por outro, surge um problema clássico: comoescreverduasclassescomomesmonome?

Porexemplo:podeserqueaminhaclassedeDatafuncionedeumcertojeito,eaclasseDatadeumcolega,deoutro jeito.Pode serquea classedeData deumabiblioteca funcione aindadeumaterceiramaneiradiferente.

Comopermitirque tudo isso realmente funcione?Comocontrolarquemquerusarqual classedeData?

Pensando um pouco mais, notamos a existência de um outro problema e da própria solução: osistema operacional não permite a existência de dois arquivos com o mesmo nome sob o mesmodiretório,portantoprecisamosorganizarnossasclassesemdiretóriosdiferentes.

Osdiretóriosestãodiretamenterelacionadosaoschamadospacotesecostumamagruparclassesdefuncionalidadessimilaresourelacionadas.

Por exemplo, no pacote java.util temos as classes Date , SimpleDateFormat eGregorianCalendar;todaselastrabalhamcomdatasdeformasdiferentes.

PACOTES-ORGANIZANDOSUASCLASSESEBIBLIOTECAS

7.1ORGANIZAÇÃO

.

Page 104: FJ-11 Java e Orientação a Objetos

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design, Infra,Front-Ende

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

SeaclasseCliente estánopacotecontas, eladeverá estarnodiretório comomesmonome:contas . Se ela se localiza no pacote br.com.caelum.contas , significa que está no diretóriobr/com/caelum/contas.

AclasseCliente,queselocalizanesseúltimodiretóriomencionado,deveserescritadaseguinteforma:

packagebr.com.caelum.contas;

classCliente{//...}

Ficafácilnotarqueapalavrachavepackageindicaqualopacote/diretóriocontémestaclasse.

Umpacotepodeconternenhumoumaissubpacotese/ouclassesdentrodele.

Agoraéamelhorhoraderespirarmaistecnologia!

7.2DIRETÓRIOS

.

Page 105: FJ-11 Java e Orientação a Objetos

PADRÃODANOMENCLATURADOSPACOTES

Opadrãodasunparadarnomeaospacotesérelativoaonomedaempresaquedesenvolveuaclasse:

br.com.nomedaempresa.nomedoprojeto.subpacotebr.com.nomedaempresa.nomedoprojeto.subpacote2br.com.nomedaempresa.nomedoprojeto.subpacote2.subpacote3

Ospacotessópossuemletrasminúsculas,nãoimportaquantaspalavrasestejamcontidasnele.Essepadrãoexisteparaevitaraomáximooconflitodepacotesdeempresasdiferentes.

As classesdopacotepadrãodebibliotecasnão seguemessanomenclatura,que foidadaparabibliotecasdeterceiros.

Para usar uma classe do mesmo pacote, basta fazer referência a ela como foi feito até agorasimplesmenteescrevendoopróprionomedaclasse.SequisermosqueaclasseBancofiquedentrodopacotebr.com.caelum.contas,eladeveserdeclaradaassim:

packagebr.com.caelum.contas;

classBanco{Stringnome;}

ParaaclasseClienteficarnomesmopacote,seguimosamesmafórmula:

packagebr.com.caelum.contas;

classCliente{Stringnome;Stringendereco;}

AnovidadechegaaotentarutilizaraclasseBanco(ouCliente)emumaoutraclassequeestejaforadessepacote,porexemplo,nopacotebr.com.caelum.contas.main:

packagebr.com.caelum.contas.main;

classTesteDoBanco{

publicstaticvoidmain(String[]args){br.com.caelum.contas.BancomeuBanco=newbr.com.caelum.contas.Banco();meuBanco.nome="BancodoBrasil";System.out.println(meuBanco.nome);}

}

7.3IMPORT

.

Page 106: FJ-11 Java e Orientação a Objetos

ReparequeprecisamosreferenciaraclasseBancocomtodoonomedopacotenasuafrente.EsseéoconhecidoFullyQualifiedNamedeumaclasse.Emoutraspalavras,esseéoverdadeironomedeumaclasse,porissoduasclassescomomesmonomeempacotesdiferentesnãoconflitam.

Mesmoassim,aotentarcompilaraclasseanterior,surgeumerroreclamandoqueaclasseBanconãoestávisível.

Acontecequeasclasses só sãovisíveisparaoutrasnomesmopacote e,parapermitirqueaclasseTesteDoBanco veja e acesse a classe Banco em outro pacote, precisamos alterar essa última etransformá-laempública:

packagebr.com.caelum.contas;

publicclassBanco{Stringnome;}

Apalavra chavepublic libera o acesso para classes de outros pacotes. Domesmo jeito que ocompilador reclamou que a classe não estava visível, ele reclama que o atributo/variável membrotambém não está. É fácil deduzir como resolver o problema: utilizando novamente o modificadorpublic:

packagebr.com.caelum.contas;

publicclassBanco{publicStringnome;}

Podemos testar nosso exemplo anterior, lembrando que utilizar atributos como público não trazencapsulamentoeestáaquicomoilustração.

VoltandoaocódigodoTesteDoBanco, é necessário escrever todoopacotepara identificar qualclassequeremosusar?Oexemploqueusamosficoubemcomplicadodeler:

br.com.caelum.contas.BancomeuBanco=newbr.com.caelum.contas.Banco();

Existe umamaneiramais simples de se referenciar a classe Banco: basta importá-la do pacotebr.com.caelum.contas:

packagebr.com.caelum.contas.main;

//parapodermosreferenciar//aBancodiretamenteimportbr.com.caelum.contas.Banco;

publicclassTesteDoBanco{

publicstaticvoidmain(String[]args){BancomeuBanco=newBanco();meuBanco.nome="BancodoBrasil";}

}

.

Page 107: FJ-11 Java e Orientação a Objetos

Issofazcomquenãoprecisemosnosreferenciarutilizandoofullyqualifiedname,podendoutilizarBancodentrodonossocódigoemvezdeescreverolongobr.com.caelum.contas.Banco.

PACKAGE,IMPORT,CLASS

Émuito importantemanteraordem!Primeiro,apareceuma(ounenhuma)vezopackage;depois,podeaparecerumoumaisimports;e,porúltimo,asdeclaraçõesdeclasses.

IMPORTX.Y.Z.*;

É possível "importar um pacote inteiro" (todas as classes do pacote, exceto os subpacotes)atravésdocoringa*:

importjava.util.*;

Importar todas as classes de umpacotenão implica emperdade performance em tempodeexecução,maspodetrazerproblemascomclassesdemesmonome!Alémdisso,importardeumemuméconsideradoboaprática,poisfacilitaaleituraparaoutrosprogramadores.UmaIDEcomooEclipsejávaifazerissoporvocê,assimcomoaorganizaçãoemdiretórios.

Osmodificadoresdeacessoexistentes emJava sãoquatro, e atéomomento jávimos três,mas sóexplicamosdois.

public -Todospodemacessaraquiloque fordefinidocomopublic.Classes, atributos,construtoresemétodospodemserpublic.

protected -Aquiloqueéprotected pode ser acessadopor todas as classesdomesmopacoteeportodasasclassesqueoestendam,mesmoqueessasnãoestejamnomesmopacote.Somenteatributos,construtoresemétodospodemserprotected.

padrão(semnenhummodificador) -Senenhummodificadorforutilizado, todasasclassesdomesmopacotetêmacessoaoatributo,construtor,métodoouclasse.

private-Aúnicaclassecapazdeacessarosatributos,construtoresemétodosprivadoséaprópria classe. Classes, como conhecemos, não podem ser private , mas atributos,construtoresemétodossim.

7.4ACESSOAOSATRIBUTOS,CONSTRUTORESEMÉTODOS

.

Page 108: FJ-11 Java e Orientação a Objetos

CLASSESPÚBLICAS

Paramelhororganizarseucódigo,oJavanãopermitemaisdeumaclassepúblicaporarquivoeoarquivodeveserNomeDaClasse.java.

Umavezqueoutrosprogramadoresirãoutilizaressaclasse,quandoprecisaremolharocódigodamesma,ficamaisfácilencontrá-lasabendoqueelaestánoarquivodemesmonome.

Classesaninhadaspodemserprotectedouprivate,masesseéumtópicoavançadoquenãoseráestudadonessemomento.

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelum eobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

VocêpodeusaraperspectivaJavadoEclipse.AviewprincipaldenavegaçãoéoPackageExplorer,queagrupaclassespelospacotesemvezdediretórios(vocêpodeusá-laemconjuntocomaNavigator,bastatambémabri-lapeloWindow/ShowView/PackageExplorer).

EditoraCasadoCódigocomlivrosdeumaformadiferente

7.5USANDOOECLIPSECOMPACOTES

.

Page 109: FJ-11 Java e Orientação a Objetos

Antes de movermos nossas classes, declare-as como públicas e coloque-as em seus respectivosarquivos:umarquivoparacadaclasse.

Vocêpodemoverumaclassedepacotearrastando-aparaodestinodesejado.ReparequeoEclipsejádeclarapackageseimportsnecessários:

.

Page 110: FJ-11 Java e Orientação a Objetos

NoEclipsenuncaprecisamosdeclararumimport,poiselesemprevaisugeririssoquandousarmosoCtrl+Espaçononomedeumaclasse.

VocêtambémpodeusaroCtrl+1nocasodadeclaraçãodepacotepossuiralgumerro.

Atenção: utilize os recursos do Eclipse para realizar essas mudanças. Use a view package-

explorer,quevaiauxiliarbastanteamanipulaçãodosarquivosediretórios.TambémutilizeosquickfixesquandooEclipsereclamardosdiversosproblemasdecompilaçãoqueaparecerão.Épossívelfazeresse exercício inteiro semmodificar uma linha de códigomanualmente. Aproveite para praticar edescobriroEclipse,eviteusá-loapenascomoumeditordetexto.

Por exemplo, com o Eclipse nunca precisamos nos preocupar com os imports: ao usar o autocomplete,elejájogaoimportláemcima.E,sevocênãofezisso,elesugerecolocaroimport.

1. Selecionandoosrcdoseuprojeto,façactrl+NeescrevaPackageparaoseusistemadeContascomeçar a utilizar pacotes. Na janela de criação de pacotes escreva o nome completo do pacoteseguindoaconvençãodecódigodaSun,desdeobr,eoEclipsetratarádefazeraseparaçãodaspastascorretamente.Cuidado:paraessecurso,osnomesdospacotesprecisamserosseguintes:

br.com.caelum.contas.main:colocaraclassecomométodomainaqui(oTeste)

7.6EXERCÍCIOS:PACOTES

.

Page 111: FJ-11 Java e Orientação a Objetos

br.com.caelum.contas.modelo:colocaraclasseConta

Antesdecorrigirqualquererrodecompilação,primeiromovatodasassuasclasses,semdeixarnenhumanopacotedefault.

2. Sevocêaindanãotiverseparadocadaclasseemumarquivo,essaéahorademudarisso.Coloquecadaclasseemseurespectivoarquivo.java.Façaissoindependentedeelaserpública:éumaboaprática.

3. Casoocódigonãocompileprontamente, reparequepelomenosalgummétodoquedeclaramosépackage-privatequando,naverdade,precisamosqueelesejapublic.Omesmovaleparaasclasses:algumasdelasprecisarãoserpúblicas.

Se houver algum erro de compilação, use o recurso de quick fix do Eclipse aqui: elemesmo vaisugerirqueomodificadordeacessodeveserpúblico.Paraisso,useoctrl+1emcadaumdoserros,escolhendooquickfixmaisadequadoparaseuproblema.

4. (Opcional)AbraaviewNavigatorparavercomoficouosarquivosnosistemadearquivosdoseusistemaoperacional.Paraisso,usectrl+3,comeceadigitarNavigatoreescolhaaopçãodeabriressaview..

.

Page 112: FJ-11 Java e Orientação a Objetos

CAPÍTULO8

"Perder tempo em aprender coisas que não interessam, priva-nos de descobrir coisas interessantes" --CarlosDrummonddeAndrade

Aotérminodessecapítulo,vocêserácapazde:

criaroJARdoseuaplicativo;colocarumJARnobuildpathdoseuprojeto;lerumjavadoc;criarojavadocdoseuaplicativo.

Assimqueumprogramaficapronto,émeiocomplicadoenviardezenasoucentenasdeclassesparacadaclientequequerutilizá-lo.

Ojeitomaissimplesdetrabalharcomumconjuntodeclassesécompactá-losemumarquivosó.OformatodecompactaçãopadrãoéoZIPcomaextensãodoarquivocompactadoJAR.

OARQUIVO.JAR

Oarquivo jarouJavaARchive, possui umconjuntode classes (e arquivosde configurações)compactados, no estilo de um arquivo zip. O arquivo jar pode ser criado com qualquercompactadorzipdisponívelnomercado,inclusiveoprogramajarquevemjuntocomoJDK.

Paracriarumarquivojardonossoprogramadebanco,bastairaodiretórioondeestãocontidasasclasses eusaro comandoa seguirpara criaroarquivobanco.jar com todas as classesdospacotesbr.com.caelum.utilebr.com.caelum.banco:

jar-cvfbanco.jarbr/com/caelum/util/*.classbr/com/caelum/banco/*.class

Parausaressearquivobanco.jarpararodaroTesteDoBancobastarodarojavacomoarquivojarcomoargumento:

java-classpathbanco.jarbr.com.caelum.contas.main.TesteDoBanco

FERRAMENTAS:JAREJAVADOC

8.1ARQUIVOS,BIBLIOTECASEVERSÕES

.

Page 113: FJ-11 Java e Orientação a Objetos

Paraadicionarmaisarquivos.jar,quepodemserbibliotecas,aoprogramabastarodarojavadaseguintemaneira:

java-classpathbiblioteca1.jar;biblioteca2.jarNomeDaClasse

Vale lembrarqueopontoevírgulautilizadosóéválidoemambienteWindows.EmLinux,MaceoutrosUnix,éodoispontos(variadeacordocomosistemaoperacional).

Hátambémumarquivodemanifestoquecontéminformaçõesdoseujarcomo,porexemplo,qualclasseelevairodarquandoojarforchamado.Masnãosepreocupepois,comoEclipse,essearquivoégeradoautomaticamente.

BIBLIOTECAS

Diversas bibliotecas podem ser controladas de acordo com a versão por estarem semprecompactadasemumarquivo.jar.Basta verificaronomedabiblioteca (por exemplolog4j-1.2.13.jar)paradescobriraversãodela.

Então é possível rodar dois programas aomesmo tempo, cadaumutilizandouma versãodabibliotecaatravésdoparâmetro-classpathdojava.

CRIANDOUM.JARAUTOMATICAMENTE

Existemdiversasferramentasqueservemparaautomatizaroprocessodedeploy,queconsisteemcompilar,gerardocumentação,bibliotecasetc.AsduasmaisfamosassãooANTeoMAVEN,ambossãoprojetosdogrupoApache.

OEclipsepodegerarfacilmenteumjar,porém,seoseubuildécomplexoeprecisaprepararecopiar uma série de recursos, as ferramentas indicadas acima possuem sofisticadasmaneiras derodarumscriptbatch.

.

Page 114: FJ-11 Java e Orientação a Objetos

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

Nesteexemplo,vamosgeraroarquivoJARdonossoprojetoapartirdoEclipse:

CliquecomobotãodireitoemcimadonomedoseuprojetoeselecioneaopçãoExport.

Na telaExport (comomostraa figuraabaixo), selecioneaopção "JAR file" e aperteobotão

AprendasedivertindonaAluraStart!

8.2GERANDOOJARPELOECLIPSE

.

Page 115: FJ-11 Java e Orientação a Objetos

"Next".

Naopção"JARfile:",selecioneolocalquevocêdesejasalvaroarquivoJAR.Eaperte"Next".

Napróximatela,simplesmentecliqueemnext,poisnãohánenhumaconfiguraçãoaserfeita.

.

Page 116: FJ-11 Java e Orientação a Objetos

Na tela abaixo,naopção "select theclassof theapplicationentrypoint", vocêdeveescolherqualclasseseráaclassequevairodarautomaticamentequandovocêexecutaroJAR.

Entrenalinhadecomando:java-jarbanco.jar

É comum dar um nome mais significativo aos JARs, incluindo nome da empresa, do projeto eversão,comocaelum-banco-1.0.jar.

ComovamossaberoquecadaclassetemnoJava?Quaissãoseusmétodos,oqueelesfazem?

E, a partir da Internet, você pode acessar através do link:http://download.java.net/jdk8/docs/api/index.html

NositedaOracle,vocêpode(edeve)baixaradocumentaçãodasbibliotecasdoJava,frequentementereferidacomo"javadoc"ouAPI(sendonaverdadeadocumentaçãodaAPI).

8.3JAVADOC

.

Page 117: FJ-11 Java e Orientação a Objetos

Nesta documentação, no quadro superior esquerdo, você encontra os pacotes e, no inferioresquerdo,estáalistagemdasclasseseinterfacesdorespectivopacote(oudetodos,casonenhumtenhasidoespecificado).Clicando-seemumaclasseou interface,oquadrodadireitapassaadetalhar todosatributosemétodos.

Reparequemétodoseatributosprivadosnãoestãoaí.Oimportanteédocumentaroquesuaclassefaz,enãocomoelafaz:detalhesdeimplementação,comoatributosemétodosprivados,nãointeressamaodesenvolvedorqueusaráasuabiblioteca(ou,aomenos,nãodeveriaminteressar).

Vocêtambémconseguegeraressejavadocapartirdalinhadecomando,comocomando:javadoc.

ParageraroJavadocapartirdoEclipseémuitosimples,sigaospassosabaixo:

Na barra demenu, selecione omenuProject, depois a opção "Generate Javadoc...". (apenasdisponívelseestivernaperspectivaJava,masvocêpodeacessaromesmowizardpeloexportdoprojeto).

8.4GERANDOOJAVADOC

.

Page 118: FJ-11 Java e Orientação a Objetos

Emseguida,aparecerãoasopçõesparageraradocumentaçãodoseusistema,selecionetodasas classes do seu sistema e deixe as outras opções como estão. Não esqueça de marcar ocaminhodaopção"Destination",poiséláqueestarásuadocumentação.

.

Page 119: FJ-11 Java e Orientação a Objetos

Abraadocumentaçãoatravésdocaminhoquevocêmarcoueabraoarquivoindex.html,quevaichamarumapáginasemelhanteaessadafiguraabaixo.

Para colocarmos comentários na documentação, devemos adicionar ao código, sob forma decomentário,abrindootextocom/**efechandocom*/e,nasoutraslinhas,apenascolocando*.Tambémpodemosdefiniroutrasinformaçõesnestetexto,como:autor,versão,parâmetros,retorno,etc.Adicionealgunscomentáriosaoseuprojetocomoabaixo:

/***ClasseresponsávelpormoldarasContasdoBanco**@authorManoelSantosdaSilva*/

publicclassConta{...}

Ouadicionealgunscomentáriosemalgummétodoseu:

/***Metodoqueincrementaosaldo.*@paramvalor*/

publicvoiddeposita(doublevalor){...

.

Page 120: FJ-11 Java e Orientação a Objetos

}

Vejacomoficou:

Conheça a Casa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Com a curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

8.5EXERCÍCIOS:JAREJAVADOC

.

Page 121: FJ-11 Java e Orientação a Objetos

1. Gereumjardoseusistemacomoarquivodemanifesto.Execute-ocomjava-jar:

java-jarcaelum-banco-1.0.jar

SeoWindowsouoLinux foi configuradopara trabalhar coma extensão .jar, basta você dar umduplo clique no arquivo, que ele será "executado": o arquivo Manifest será lido para que eledescubraqualéaclassecommainqueoJavadeveprocessar.

2. GereoJavadocdoseusistema.Para isso,váaomenuProject,depoisàopçãoGenerateJavadoc, seestivernaperspectivaJava.Senão,dêumcliquecomobotãodireitonoseuprojeto,escolhaExportedepoisjavadocesigaoprocedimentodescritonaúltimaseçãodestecapítulo.

IndependentedaperspectivaquevocêusanoEclipse,vocêtambémpodeusaroctrl+3ecomeçaraescreverJavaDoc,atéqueaopçãodeexportaroJavaDocapareça.

INTERFACEVERSUSIMPLEMENTAÇÃONOVAMENTE!

Repare que a documentação gerada não mostra o conteúdo dos métodos, nem atributos emétodosprivados!Issofazpartedaimplementação,eoqueimportaparaquemusaumabibliotecaéainterface:oqueelafaz.

Jásabemoscomodocumentarnossoprojetoegerarumjarparadistribuí-lomaselaaindanãotemumainterfacegráficadousuário.Sequisermosrodaronossosistematemosqueexecutá-lopeloterminalcomosvaloreshard-coded.Seriamaisinteressantequetivéssemosumainterfacemaisamigávelparaqueousuáriopudesseinteragircomonossosistema.Aomesmotempo,nãoqueremosnospreocuparnessemomentoemcriartodasasclassespararepresentaressainterfacegráfica,queremosapenasutilizaralgojápronto.

Para isso, vamos importar uma biblioteca externa. O próprio Eclipse já nos dá suporte para aimportaçãodejars.Parafazerisso,bastairnomenuProject->Properties,selecionaraopçãoJavaBuildPath,depois selecionara abaLibraries e, finalmente, clicarnobotãoAddExternal Jars... .Agora é sóselecionar o jar a ser importado e clicar emOpen.Clique emOknovamente para fechar a janela deimportaçãoepronto!Nossabibliotecajáestáprontaparaserutilizada.

1. Vamosimportarumjarquecontémainterfacegráficadousuárioparaonossosistemadecontas.

VánomenuProject->Properties

8.6IMPORTANDOUMJAREXTERNO

8.7EXERCÍCIOS:IMPORTANDOUMJAR

.

Page 122: FJ-11 Java e Orientação a Objetos

SelecioneaopçãoJavaBuildPath

SelecioneaabaLibraries

CliquenobotãoAddExternalJars...

Selecioneoarquivofj11-lib-contas.jarlocalizadonapastadosarquivosdoscursos/11

CliquenobotãoOkparafecharajaneladeimportação

2. Para verificarmosque a importaçãodeu certo, vamos chamaruma classedabiblioteca importadaparaexibirumajaneladeboas-vindas.

CrieumaclasseTestaJarnopacotebr.com.caelum.contas.main.

Crietambémométodomain.

3. Dentrodométodocriado,vamos invocarométodomaindaclasseOlaMundo que existeno jarimportado.Seucódigodeveficardessamaneira:

packagebr.com.caelum.contas.main;

importbr.com.caelum.javafx.api.main.OlaMundo;

publicclassTestaJar{

publicstaticvoidmain(String[]args){OlaMundo.main(args);}}

NãoesqueçadeimportaraclasseOlaMundodopacotebr.com.caelum.javafx.api.main.Useoatalhoctrl+shift+O.

4. Executeasuaaplicaçãoevejaseapareceuumajaneladeboas-vindascomoaseguir:

.

Page 123: FJ-11 Java e Orientação a Objetos

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design, Infra,Front-Ende

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

AgoraquejáimportamosoJarquecontémainterfacegráfica,vamosdarumaolhadanaprimeirateladonossosistema:

Agoraéamelhorhoraderespirarmaistecnologia!

8.8MANIPULANDOACONTAPELAINTERFACEGRÁFICA

.

Page 124: FJ-11 Java e Orientação a Objetos

Nestatela,podemosperceberquetemosbotõesparaasaçõesdecriaçãodeconta,saqueedepósito,quedevemutilizaraimplementaçãoexistenteemnossaclasseConta.

Se quisermos visualizar a tela, podemos criar um main que chamará a classe TelaDeContasresponsávelpelasuaexibição:

packagebr.com.caelum.contas.main;

importbr.com.caelum.javafx.api.main.TelaDeContas;

publicclassTestaContas{

publicstaticvoidmain(String[]args){TelaDeContas.main(args);}}

.

Page 125: FJ-11 Java e Orientação a Objetos

Aoexecutarmosaaplicaçãoocorreráumerro:

Masporqueesteerroocorreu?Acontecequeatelaprecisaconheceralguémquesaibaexecutarasaçõesdesaqueedepósitonaconta,queconsigabuscarosdadosdatelaparapopularaconta.Comonãotemosninguémquesaibafazeristoainda,ocorreuoerro.

VamosentãocriaraclasseManipuladorDeContasqueseráresponsávelporfazeresta"ponte"entreatelaeaclassedeConta:

packagebr.com.caelum.contas;

publicclassManipuladorDeContas{

}

Agora,aoexecutarmosaaplicação,veremosqueatelaaparececomsucesso:

.

Page 126: FJ-11 Java e Orientação a Objetos

Esetentarmosclicarnobotãodecriaçãodeconta?Tambémocorreumerro!

.

Page 127: FJ-11 Java e Orientação a Objetos

DestavezoerroindicaquefaltaométodocriaContadentrodaclasseManipuladorDeContas.Vamosentãocriá-lo:

publicclassManipuladorDeContas{

publicvoidcriaConta(){Contaconta=newConta();conta.setAgencia("1234");conta.setNumero(56789);conta.setTitular("Batman");}}

Paraconseguirmosobterasinformaçõesdatela,todososmétodosquecriaremosprecisamreceberumparâmetrodotipoEventoqueconteráasinformaçõesdigitadas.Mesmoquenãoutilizemosesteparâmetro,precisamosrecebê-lo.

importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeContas{

publicvoidcriaConta(Eventoevento){Contaconta=newConta();conta.setAgencia("1234");conta.setNumero(56789);conta.setTitular("Batman");}}

Se tentarmos executar a aplicação e clicarnobotãocria conta, vemosque agoranãoocorremaisnenhumerromasaomesmotempoosdadosdacontanãosãopopuladosnatela.Istoacontecepoisavariávelconta é apenas local, ou seja, ela só existe dentro dométodocriaConta. Além disso sequiséssemosdepositarumvalornaconta,emqualcontadepositaríamos?Elanãoévisívelparanenhum

.

Page 128: FJ-11 Java e Orientação a Objetos

outrométodo!

PrecisamosqueestavariávelsejaumatributodoManipuladorDeContas.Vamosalterar:

importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeContas{

privateContaconta;

publicvoidcriaConta(Eventoevento){this.conta=newConta();this.conta.setAgencia("1234");this.conta.setNumero(56789);this.conta.setTitular("Batman");}}

Testandoagoraconseguimosverosdadosdacontanatela!

.

Page 129: FJ-11 Java e Orientação a Objetos

Só falta criarmos os métodos saca e deposita. Vamos começar implementando o métododeposita. Nele precisamos do valor digitado pelo usuário na tela e é pra isto que serve a classeEvento. Se quisermos buscar um valor do tipo double, podemos invocar o método doublepassandoonomedocampoquequeremosrecuperarcomoparâmetro.Comovaloremmãos,podemosentãopassá-loparaométododesejado.Nossométodofica:

importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeContas{

//...

publicvoiddeposita(Eventoevento){doublevalorDigitado=evento.getDouble("valor");this.conta.deposita(valorDigitado);}}

Podemosfazeromesmoparaométodosaca:

importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeContas{

//...

publicvoiddeposita(Eventoevento){doublevalorDigitado=evento.getDouble("valor");this.conta.deposita(valorDigitado);}

publicvoidsaca(Eventoevento){doublevalorDigitado=evento.getDouble("valor");this.conta.saca(valorDigitado);}}

Agoraconseguimosrodaraaplicaçãoechamarasaçõesdesaqueedepósitoqueosaldoéatualizadocomsucesso!

.

Page 130: FJ-11 Java e Orientação a Objetos

1. CrieaclasseManipuladorDeContas dentrodopacotebr.com.caelum.contas.Reparequeospacotes br.com.caelum.contas.main e br.com.caelum.contas.modelo são subpacotes dopacotebr.com.caelum.contas,portantoopacotebr.com.caelum.contasjáexiste.Paracriaraclassenestepacote,bastaselecioná-lonajaneladecriaçãodaclasse:

8.9EXERCÍCIOS:MOSTRANDOOSDADOSDACONTANATELA

.

Page 131: FJ-11 Java e Orientação a Objetos

AclasseManipuladorDeContasfaráaligaçãodaContacomatela,porissoprecisaremosdeclararumatributodotipoConta.

2. CrieométodocriaContaquerecebecomoparâmetroumobjetodotipoEvento.Instancieumacontaparaoatributocontaecoloqueosvaloresdenumero,agenciaetitular.Algocomo:

publicvoidcriaConta(Eventoevento){this.conta=newConta();this.conta.setTitular("Batman");//façaomesmoparaosoutrosatributos}

3. Comacontainstanciada,agorapodemosimplementarasfuncionalidadesdesaqueedepósito.CrieométododepositaquerecebeumEvento,queéaclassequeretornaosdadosdatelanostiposqueprecisamos.Porexemplo,sequisermosovaloradepositarsabemosqueeleédotipodoubleequeonomedocamponatelaévalorentãopodemosfazer:

publicvoiddeposita(Eventoevento){doublevalorDigitado=evento.getDouble("valor");this.conta.deposita(valorDigitado);}

4. Crie agora o método saca. Ele também deve receber um Evento nos mesmos moldes do

.

Page 132: FJ-11 Java e Orientação a Objetos

deposita.

5. Precisamos agora testar nossa aplicação, crie a classe TestaContas dentro do pacotebr.com.caelum.contascomummain.NelavamoschamaromaindaclasseTelaDeContasquemostraráateladenossosistema.Nãoseesqueçadefazeroimportdestaclasse!

importbr.com.caelum.javafx.api.main.TelaDeContas;

publicclassTestaContas{

publicstaticvoidmain(String[]args){TelaDeContas.main(args);}}

Rodeaaplicação,crieacontaetentefazerasoperaçõesdesaqueedepósito.Tudodevefuncionarnormalmente.

.

Page 133: FJ-11 Java e Orientação a Objetos

CAPÍTULO9

"Ohomemabsurdoéaquelequenuncamuda."--GeorgesClemenceau

Aotérminodessecapítulo,vocêserácapazde:

dizeroqueéherançaequandoutilizá-la;reutilizarcódigoescritoanteriormente;criarclassesfilhasereescrevermétodos;usartodoopoderqueopolimorfismodá.

Comotodaempresa,nossoBancopossuifuncionários.VamosmodelaraclasseFuncionario:

publicclassFuncionario{privateStringnome;privateStringcpf;privatedoublesalario;//métodosdevemviraqui}

Alémdeumfuncionáriocomum,hátambémoutroscargos,comoosgerentes.Osgerentesguardama mesma informação que um funcionário comum, mas possuem outras informações, além de terfuncionalidadesumpoucodiferentes.Umgerentenonossobancopossuitambémumasenhanuméricaquepermiteoacessoaosistemainternodobanco,alémdonúmerodefuncionáriosqueelegerencia:

publicclassGerente{privateStringnome;privateStringcpf;privatedoublesalario;privateintsenha;privateintnumeroDeFuncionariosGerenciados;

publicbooleanautentica(intsenha){if(this.senha==senha){System.out.println("AcessoPermitido!");returntrue;}else{System.out.println("AcessoNegado!");returnfalse;}}

//outrosmétodos

HERANÇA,REESCRITAEPOLIMORFISMO

9.1REPETINDOCÓDIGO?

.

Page 134: FJ-11 Java e Orientação a Objetos

}

PRECISAMOSMESMODEOUTRACLASSE?

PoderíamosterdeixadoaclasseFuncionariomaisgenérica,mantendonelasenhadeacesso,eonúmerodefuncionáriosgerenciados.Casoofuncionárionãofosseumgerente,deixaríamosestesatributosvazios.

Essaéumapossibilidade,porémpodemoscomeçara termuitoatributosopcionais,eaclasseficariaestranha.Eemrelaçãoaosmétodos?AclasseGerentetemométodoautentica,quenãofazsentidoexistiremumfuncionárioquenãoégerente.

Se tivéssemos um outro tipo de funcionário que tem características diferentes do funcionáriocomum,precisaríamoscriarumaoutraclasseecopiarocódigonovamente!

Além disso, se um dia precisarmos adicionar uma nova informação para todos os funcionários,precisaremospassarportodasasclassesdefuncionárioeadicionaresseatributo.Oproblemaacontecenovamentepornãocentralizarmosasinformaçõesprincipaisdofuncionárioemumúnicolugar!

Existeumjeito,emJava,derelacionarmosumaclassedetalmaneiraqueumadelasherdatudoqueaoutratem.Istoéumarelaçãodeclassemãeeclassefilha.Nonossocaso,gostaríamosdefazercomqueoGerente tivesse tudo que um Funcionario tem, gostaríamos que ela fosse uma extensão deFuncionario.Fazemosistoatravésdapalavrachaveextends.

publicclassGerenteextendsFuncionario{privateintsenha;privateintnumeroDeFuncionariosGerenciados;

publicbooleanautentica(intsenha){if(this.senha==senha){System.out.println("AcessoPermitido!");returntrue;}else{System.out.println("AcessoNegado!");returnfalse;}}

//setterdasenhaomitido}

Em todomomento que criarmos um objeto do tipo Gerente, este objeto possuirá também osatributosdefinidosnaclasseFuncionario,poisumGerenteéumFuncionario:

.

Page 135: FJ-11 Java e Orientação a Objetos

publicclassTestaGerente{publicstaticvoidmain(String[]args){Gerentegerente=newGerente();

//podemoschamarmétodosdoFuncionario:gerente.setNome("JoãodaSilva");

//etambémmétodosdoGerente!gerente.setSenha(4231);}}

DizemosqueaclasseGerenteherdatodososatributosemétodosdaclassemãe,nonossocaso,aFuncionario.Para sermaispreciso, ela tambémherdaosatributosemétodosprivados,porémnãoconsegue acessá-los diretamente. Para acessar um membro privado na filha indiretamente, serianecessárioqueamãeexpusesseumoutrométodovisívelqueinvocasseesseatributooumétodoprivado.

SUPERESUBCLASSE

A nomenclatura mais encontrada é que Funcionario é a superclasse de Gerente , eGerente é a subclasse de Funcionario . Dizemos também que todo Gerente é umFuncionário.OutraformaédizerqueFuncionarioéclassemãedeGerenteeGerenteéclassefilhadeFuncionario.

E se precisamos acessar os atributos que herdamos? Não gostaríamos de deixar os atributos deFuncionario,public,poisdessamaneiraqualquerumpoderiaalterarosatributosdosobjetosdestetipo.Existeumoutromodificadordeacesso,oprotected,queficaentreoprivateeopublic.Umatributoprotected só pode ser acessado (visível) pela própria classe, por suas subclasses, e pelasclassesqueseencontramnomesmopacote.

publicclassFuncionario{protectedStringnome;protectedStringcpf;protecteddoublesalario;//métodosdevemviraqui}

.

Page 136: FJ-11 Java e Orientação a Objetos

SEMPREUSARPROTECTED?

Entãoporqueusarprivate?Depoisdeumtempoprogramandoorientadoaobjetos,vocêvaicomeçarasentirquenemsempreéumaboaideiadeixarqueaclassefilhaacesseosatributosdaclasse mãe, pois isso quebra um pouco a ideia de que só aquela classe deveria manipular seusatributos.Essaéumadiscussãoumpoucomaisavançada.

Alémdisso,nãosóas subclasses,mas tambémasoutrasclassesqueseencontramnomesmopacote, podem acessar os atributos protected. Veja outras alternativas ao protected noexercíciodediscussãoemsaladeaulajuntamentecomoinstrutor.

Da mesma maneira, podemos ter uma classe Diretor que estenda Gerente e a classePresidentepodeestenderdiretamentedeFuncionario.

Fique claro que essa é uma decisão de negócio. Se Diretor vai estender de Gerente ou não, vaidependerse,paravocê,DiretoréumGerente.

Umaclassepodetervárias filhas,maspodeterapenasumamãe,éachamadaherançasimplesdojava.

.

Page 137: FJ-11 Java e Orientação a Objetos

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelum eobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

Todo fim de ano, os funcionários do nosso banco recebem uma bonificação. Os funcionárioscomunsrecebem10%dovalordosalárioeosgerentes,15%.

VamosvercomoficaaclasseFuncionario:

publicclassFuncionario{protectedStringnome;protectedStringcpf;protecteddoublesalario;

publicdoublegetBonificacao(){returnthis.salario*0.10;}//métodos}

SedeixarmosaclasseGerentecomoelaestá,elavaiherdarométodogetBonificacao.

Gerentegerente=newGerente();gerente.setSalario(5000.0);System.out.println(gerente.getBonificacao());

Oresultadoaquiserá500.Nãoqueremosessaresposta,poisogerentedeveriater750debônusnessecaso.Paraconsertarisso,umadasopçõesseriacriarumnovométodonaclasseGerente,chamado,porexemplo, getBonificacaoDoGerente. O problema é que teríamos dois métodos em Gerente ,confundindobastantequemforusaressaclasse,alémdequecadaumdaumarespostadiferente.

NoJava,quandoherdamosummétodo,podemosalterarseucomportamento.Podemosreescrever(reescrever,sobrescrever,override)estemétodo:

publicclassGerenteextendsFuncionario{intsenha;intnumeroDeFuncionariosGerenciados;

EditoraCasadoCódigocomlivrosdeumaformadiferente

9.2REESCRITADEMÉTODO

.

Page 138: FJ-11 Java e Orientação a Objetos

publicdoublegetBonificacao(){returnthis.salario*0.15;}//...}

AgoraométodoestácorretoparaoGerente.Refaçaotesteevejaqueovalorimpressoéocorreto(750):

Gerentegerente=newGerente();gerente.setSalario(5000.0);System.out.println(gerente.getBonificacao());

AANOTAÇÃO@OVERRIDE

Hácomodeixarexplícitonoseucódigoquedeterminadormétodoéareescritadeummétododa sua classemãe. Fazemos isso colocando @Override em cima do método. Isso é chamadoanotação.Existemdiversasanotaçõesecadaumavaiterumefeitodiferentesobreseucódigo.

@OverridepublicdoublegetBonificacao(){returnthis.salario*0.15;}

Repare que, por questões de compatibilidade, isso não é obrigatório. Mas caso ummétodoestejaanotadocom@Override,elenecessariamenteprecisaestarreescrevendoummétododaclassemãe.

Depoisde reescrito,nãopodemosmais chamarométodoantigoque foraherdadoda classemãe:realmente alteramos o seu comportamento. Mas podemos invocá-lo no caso de estarmos dentro daclasse.

Imagine que para calcular a bonificação de umGerente devemos fazer igual ao cálculo de umFuncionarioporémadicionandoR$1000.Poderíamosfazerassim:

publicclassGerenteextendsFuncionario{intsenha;intnumeroDeFuncionariosGerenciados;

publicdoublegetBonificacao(){returnthis.salario*0.10+1000;}//...}

Aquiteríamosumproblema:odiaqueogetBonificacaodoFuncionariomudar,precisaremos

9.3INVOCANDOOMÉTODOREESCRITO

.

Page 139: FJ-11 Java e Orientação a Objetos

mudar o método do Gerente para acompanhar a nova bonificação. Para evitar isso, ogetBonificacaodoGerentepodechamarodoFuncionarioutilizandoapalavrachavesuper.

publicclassGerenteextendsFuncionario{intsenha;intnumeroDeFuncionariosGerenciados;

publicdoublegetBonificacao(){returnsuper.getBonificacao()+1000;}//...}

Essa invocação vai procurar o método com o nome getBonificacao de uma super classe deGerente.NocasoelelogovaiencontraressemétodoemFuncionario.

Essaéumapráticacomum,poismuitoscasosométodoreescritogeralmentefaz"algoamais"queométododaclassemãe.Chamarounãoométododecimaéumadecisãosuaedependedoseuproblema.Algumasvezesnãofazsentidoinvocarométodoquereescrevemos.

OqueguardaumavariáveldotipoFuncionario?UmareferênciaparaumFuncionario,nuncaoobjetoemsi.

Naherança,vimosquetodoGerenteéumFuncionario,poiséumaextensãodeste.Podemosnos referir a um Gerente como sendo um Funcionario . Se alguém precisa falar com umFuncionariodobanco,podefalarcomumGerente!Porque?PoisGerenteéumFuncionario.Essaéasemânticadaherança.

Gerentegerente=newGerente();Funcionariofuncionario=gerente;funcionario.setSalario(5000.0);

Polimorfismo é a capacidade de um objeto poder ser referenciado de várias formas. (cuidado,polimorfismonãoquerdizerqueoobjetoficasetransformando,muitopelocontrário,umobjetonascedeumtipoemorredaqueletipo,oquepodemudaréamaneiracomonosreferimosaele).

Atéaquitudobem,maseseeutentar:

9.4POLIMORFISMO

.

Page 140: FJ-11 Java e Orientação a Objetos

funcionario.getBonificacao();

Qualéoretornodessemétodo?500ou750?NoJava,ainvocaçãodemétodosemprevaiserdecididaemtempodeexecução.OJavavaiprocuraroobjetonamemóriae,aísim,decidirqualmétododeveserchamado, sempre relacionando com sua classe de verdade, e não com a que estamos usando parareferenciá-lo.ApesardeestarmosnosreferenciandoaesseGerentecomosendoumFuncionario,ométodoexecutadoéodoGerente.Oretornoé750.

Parece estranho criar um gerente e referenciá-lo como apenas um funcionário. Por que faríamosisso?Naverdade,asituaçãoquecostumaapareceréaquetemosummétodoquerecebeumargumentodotipoFuncionario:

classControleDeBonificacoes{privatedoubletotalDeBonificacoes=0;

publicvoidregistra(Funcionariofuncionario){this.totalDeBonificacoes+=funcionario.getBonificacao();}

publicdoublegetTotalDeBonificacoes(){returnthis.totalDeBonificacoes;}}

E,emalgumlugardaminhaaplicação(ounomain,seforapenasparatestes):

ControleDeBonificacoescontrole=newControleDeBonificacoes();

Gerentefuncionario1=newGerente();funcionario1.setSalario(5000.0);controle.registra(funcionario1);

Funcionariofuncionario2=newFuncionario();funcionario2.setSalario(1000.0);controle.registra(funcionario2);

System.out.println(controle.getTotalDeBonificacoes());

ReparequeconseguimospassarumGerenteparaummétodoquerecebeumFuncionariocomoargumento. Pense comonuma porta na agência bancária como seguinte aviso: "Permitida a entradaapenas de Funcionários". Um gerente pode passar nessa porta? Sim, pois Gerente é umFuncionario.

Qual será o valor resultante? Não importa que dentro do método registra doControleDeBonificacoesrecebaFuncionario.QuandoelereceberumobjetoquerealmenteéumGerente,oseumétodoreescritoseráinvocado.Reafirmando:nãoimportacomonosreferenciamosaumobjeto,ométodoqueseráinvocadoésempreoqueédele.

No dia em que criarmos uma classe Secretaria, por exemplo, que é filha de Funcionario,precisaremos mudar a classe de ControleDeBonificacoes ? Não. Basta a classe Secretariareescrever os métodos que lhe parecerem necessários. É exatamente esse o poder do polimorfismo,

.

Page 141: FJ-11 Java e Orientação a Objetos

juntamentecomareescritademétodo:diminuiroacoplamentoentreasclasses,paraevitarquenovoscódigosresultememmodificaçõeseminúmeroslugares.

ReparequequemcriouControleDeBonificacoespodenunca ter imaginadoacriaçãodaclasseSecretaria ouEngenheiro. Contudo, não será necessário reimplementar esse controle em cadanovaclasse:reaproveitamosaquelecódigo.

HERANÇAVERSUSACOPLAMENTO

Notequeousodeherançaaumentaoacoplamentoentreasclasses,istoé,oquantoumaclassedependedeoutra.Arelaçãoentreclassemãeefilhaémuitoforteeissoacabafazendocomqueoprogramadordas classes filhas tenhaqueconhecera implementaçãodaclassemãeevice-versa -ficadifícilfazerumamudançapontualnosistema.

Por exemplo, imagine se tivermos quemudar algo na nossa classeFuncionario, mas nãoquiséssemosquetodososfuncionáriossofressemamesmamudança.Precisaríamospassarporcadauma das filhas de Funcionario verificando se ela se comporta como deveria ou se devemossobrescreverotalmétodomodificado.

Esse éumproblemadaherança, enãodopolimorfismo,que resolveremosmais tardecomaajudadeInterfaces.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

Imaginequevamosmodelarumsistemaparaafaculdadequecontroleasdespesascomfuncionárioseprofessores.Nossofuncionárioficaassim:

JáconheceoscursosonlineAlura?

9.5UMOUTROEXEMPLO

.

Page 142: FJ-11 Java e Orientação a Objetos

publicclassEmpregadoDaFaculdade{privateStringnome;privatedoublesalario;publicdoublegetGastos(){returnthis.salario;}publicStringgetInfo(){return"nome:"+this.nome+"comsalário"+this.salario;}//métodosdeget,seteoutros}

Ogastoquetemoscomoprofessornãoéapenasseusalário.Temosdesomarumbônusde10reaisporhora/aula.Oquefazemosentão?Reescrevemosométodo.AssimcomoogetGastosédiferente,ogetInfotambémserá,poistemosdemostrarashoras/aulatambém.

publicclassProfessorDaFaculdadeextendsEmpregadoDaFaculdade{privateinthorasDeAula;publicdoublegetGastos(){returnthis.getSalario()+this.horasDeAula*10;}publicStringgetInfo(){StringinformacaoBasica=super.getInfo();Stringinformacao=informacaoBasica+"horasdeaula:"+this.horasDeAula;returninformacao;}//métodosdeget,seteoutrosqueforemnecessários}

Anovidade,aqui, éapalavrachavesuper.Apesardométodo ter sido reescrito, gostaríamosdeacessar ométodo da classemãe, para não ter de copiar e colocar o conteúdo dessemétodo e depoisconcatenarcomainformaçãodashorasdeaula.

Comotiramosproveitodopolimorfismo?Imaginequetemosumaclassederelatório:

publicclassGeradorDeRelatorio{publicvoidadiciona(EmpregadoDaFaculdadef){System.out.println(f.getInfo());System.out.println(f.getGastos());}}

Podemos passar para nossa classe qualquer EmpregadoDaFaculdade! Vai funcionar tanto paraprofessor,quantoparafuncionáriocomum.

Umcertodia,muitodepoisdeterminaressaclassederelatório,resolvemosaumentarnossosistema,e colocar uma classe nova, que representa o Reitor . Como ele também é umEmpregadoDaFaculdade, seráquevamosprecisaralteraralgonanossaclassedeRelatorio?Não.Essa é a ideia!Quem programou a classe GeradorDeRelatorio nunca imaginou que existiria umaclasseReitore,mesmoassim,osistemafunciona.

publicclassReitorextendsEmpregadoDaFaculdade{//informaçõesextraspublicStringgetInfo(){

.

Page 143: FJ-11 Java e Orientação a Objetos

returnsuper.getInfo()+"eeleéumreitor";}//nãosobrescrevemosogetGastos!!!}

SenãohouvesseherançaemJava,comovocêpoderiareaproveitarocódigodeoutraclasse?

Umadiscussãomuitoatualésobreoabusonousodaherança.Algumaspessoasusamherançaapenasparareaproveitarocódigo,quandopoderiamterfeitoumacomposição.Procuresobreherançaversuscomposição.

Mesmo depois de reescrever ummétodo da classemãe, a classe filha ainda pode acessar ométodoantigo.Istoéfeitoatravésdapalavrachavesuper.método().Algoparecidoocorreentreosconstrutoresdasclasses,oque?

MAISSOBREOMAUUSODAHERANÇA

NoblogdaCaelumexisteumartigointeressanteabordandoessetópico:

http://blog.caelum.com.br/2006/10/14/como-nao-aprender-orientacao-a-objetos-heranca/

JamesGosling,umdoscriadoresdoJava,éumcríticodomauusodaherança.Nestaentrevistaelediscuteapossibilidadedeseutilizarapenasinterfacesecomposição,eliminandoanecessidadedaherança:

http://www.artima.com/intv/gosling3P.html

1. Vamostermaisdeumtipodecontanonossosistemaentãovamosprecisardeumanovatelaparacadastrarosdiferentestiposdeconta.Essatelajáestáprontaeparautilizá-lasóprecisamosalteraraclassequeestamoschamandonométodomain()noTestaContas.java:

packagebr.com.caelum.contas.main;

importbr.com.caelum.javafx.api.main.SistemaBancario;

publicclassTestaContas{

publicstaticvoidmain(String[]args){SistemaBancario.mostraTela(false);//TelaDeContas.main(args);}}

9.6UMPOUCOMAIS...

9.7EXERCÍCIOS:HERANÇAEPOLIMORFISMO

.

Page 144: FJ-11 Java e Orientação a Objetos

2. AorodaraclasseTestaContasagora,teremosatelaabaixo:

Vamosentrarna teladecriaçãodecontasparavermosoqueprecisamos implementarparaqueosistemafuncione.Paraisso,cliquenobotãoNovaConta.Aseguintetelaaparecerá:

Podemos perceber que além das informações que já tínhamos na conta, temos agora o tipo: sequeremos uma conta corrente ou uma conta poupança. Vamos então criar as classescorrespondentes.

CrieaclasseContaCorrentenopacotebr.com.caelum.contas.modelo e faça comque elasejafilhadaclasseContaCrieaclasseContaPoupancanopacotebr.com.caelum.contas.modelo e faça comque elasejafilhadaclasseConta

3. Precisamos pegar os dados da tela para conseguirmos criar a conta correspondente. NoManipuladorDeContas vamos alterar ométodocriaConta. Atualmente, apenas criamosumanovacontacomosdadosdiretonocódigo.Vamosfazercomqueagoraosdadossejamrecuperados

.

Page 145: FJ-11 Java e Orientação a Objetos

datelaparacolocarmosnanovaconta,faremosissoutilizandooobjetoevento:

publicvoidcriaConta(Eventoevento){this.conta=newConta();this.conta.setAgencia(evento.getString("agencia"));this.conta.setNumero(evento.getInt("numero"));this.conta.setTitular(evento.getString("titular"));}

Masprecisamosdizerqual tipode contaquequeremos criar!Devemos então recuperaro tipodacontaescolhidoecriaracontacorrespondente.Paraisso,aoinvésdecriarumobjetodotipo'Conta',vamosusarométodogetSelecionadoNoRadiodoobjetoeventoparapegarotipo,fazerumifparaverificaresse tipoe sódepoiscriaroobjetodo tipocorrespondente.Apósessasmudanças,ométodocriaContaficarácomoabaixo:

publicvoidcriaConta(Eventoevento){Stringtipo=evento.getSelecionadoNoRadio("tipo");if(tipo.equals("ContaCorrente")){this.conta=newContaCorrente();}elseif(tipo.equals("ContaPoupança")){this.conta=newContaPoupanca();}this.conta.setAgencia(evento.getString("agencia"));this.conta.setNumero(evento.getInt("numero"));this.conta.setTitular(evento.getString("titular"));}

4. Apesarde já conseguirmoscriarosdois tiposde contas,nossa listanãoconsegueexibiro tipodecadacontanalistadatelainicial.Pararesolverisso,podemoscriarummétodogetTipoemcadaumadenossascontasfazendocomqueacontacorrentedevolvaastring"ContaCorrente"eacontapoupançadevolvaastring"ContaPoupança":

publicclassContaCorrenteextendsConta{publicStringgetTipo(){return"ContaCorrente";}}

publicclassContaPoupancaextendsConta{publicStringgetTipo(){return"ContaPoupança";}}

5. AltereosmétodossacaedepositaparabuscaremocampovalorOperacaoaoinvésdeapenasvalornaclasseManipuladorDeContas.

6. Vamosmudarocomportamentodaoperaçãodesaquedeacordocomotipodecontaqueestiversendo utilizada.Na classeManipuladorDeContas vamos alterar ométodo saca para tirar 10centavosdecadasaqueemumacontacorrente:

publicvoidsaca(Eventoevento){doublevalor=evento.getDouble("valorOperacao");if(this.conta.getTipo().equals("ContaCorrente")){this.conta.saca(valor+0.10);

.

Page 146: FJ-11 Java e Orientação a Objetos

}else{this.conta.saca(valor);}}

AotentarmoschamarométodogetTipo,oEclipsereclamouqueessemétodonãoexistenaclasseContaapesardeexistirnasclassesfilhas.Comoestamostratandotodasascontasgenericamente,sóconseguimosacessarosmétodosdaclassemãe.Vamosentãocolocá-lonaclasseConta:

publicclassConta{publicStringgetTipo(){return"Conta";}}

7. Agoraocódigocompilamastemosumoutroproblema.AlógicadonossosaquevazouparaaclasseManipuladorDeContas.Sealgumdiaprecisarmosalterarovalorda taxanosaque, teríamosquemudar em todos os lugares onde fazemos uso do método saca . Esta lógica deveria estarencapsuladadentrodométodosacadecadaconta.VamosentãosobrescreverométododentrodaclasseContaCorrente:

publicclassContaCorrenteextendsConta{@Overridepublicvoidsaca(doublevalor){this.saldo-=(valor+0.10);}

//restantedaclasse}

Repare que, para acessar o atributo saldo herdado da classeConta,você vai precisarmudar omodificadordevisibilidadedesaldoparaprotected.

Agora que a lógica está encapsulada, podemos corrigir o método saca da classeManipuladorDeContas:

publicvoidsaca(Eventoevento){doublevalor=evento.getDouble("valorOperacao");this.conta.saca(valor);}

Percebaqueagoratratamosacontadeformagenérica!

8. Rode a classe TestaContas, adicione uma conta de cada tipo e veja se o tipo é apresentadocorretamentenalistadecontasdatelainicial.

Agora,cliquenacontacorrenteapresentadanalistaparaabrirateladedetalhesdecontas.Testeasoperações de saque e depósito e perceba que a conta apresenta o comportamento de uma contacorrenteconformeoesperado.

Esetentarmosrealizarumatransferênciadacontacorrenteparaacontapoupança?Oqueacontece?

.

Page 147: FJ-11 Java e Orientação a Objetos

9. VamoscomeçarimplementandoométodotransferenaclasseConta:

publicvoidtransfere(doublevalor,Contaconta){this.saca(valor);conta.deposita(valor);}

Tambémprecisamos implementarométodotransfere na classeManipuladorDeContas parafazerovínculoentreatelaeaclasseConta:

publicvoidtransfere(Eventoevento){Contadestino=(Conta)evento.getSelecionadoNoCombo("destino");conta.transfere(evento.getDouble("valorTransferencia"),destino);}

Rodedenovoaaplicaçãoetesteaoperaçãodetransferência.

10. Considereocódigoabaixo:

Contac=newConta();ContaCorrentecc=newContaCorrente();ContaPoupancacp=newContaPoupanca();

Semudarmosessecódigopara:

Contac=newConta();Contacc=newContaCorrente();Contacp=newContaPoupanca();

Compila?Roda?Oquemuda?Qualéautilidadedisso?Realmente,essanãoéamaneiramaisútildopolimorfismo.Porémexisteumautilidadededeclararmosumavariáveldeumtipomenosespecíficodoqueoobjetorealmenteé,comofazemosnaclasseManipuladorDeContas.

Éextremamenteimportanteperceberquenãoimportacomonosreferimosaumobjeto,ométodoque será invocado é sempreomesmo!A JVMvaidescobrir em tempodeexecuçãoqualdeve serinvocado,dependendodequetipoéaqueleobjeto,nãoimportandocomonosreferimosaele.

11. (Opcional)AnossaclasseContadevolveapalavra "Conta"nométodogetTipo.Use a palavrachavesupernosmétodosgetTiporeescritosnasclassesfilhas,paranãoterdereescreveapalavra"Conta"aodevolverostipos"ContaCorrente"e"ContaPoupança".

12. (Opcional) Se vocêprecisasse criaruma classeContaInvestimento, e seumétodosaca fossecomplicadíssimo,vocêprecisariaalteraraclasseManipuladorDeContas?

.

Page 148: FJ-11 Java e Orientação a Objetos

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

Discuta com o instrutor e seus colegas alternativas ao uso do atributo protected na herança.Preciso realmente afrouxar o encapsulamento do atributo por causa da herança? Como fazer para oatributocontinuarprivatenamãeeasfilhasconseguiremdealgumaformartrabalharcomele?

SaberinglêsémuitoimportanteemTI

9.8 DISCUSSÕES EM AULA: ALTERNATIVAS AO ATRIBUTOPROTECTED

.

Page 149: FJ-11 Java e Orientação a Objetos

CAPÍTULO10

"Dá-seimportânciaaosantepassadosquandojánãotemosnenhum."--FrançoisChateaubriand

Aotérminodessecapítulo,vocêserácapazdeutilizarclassesabstratas,quandonecessário.

Nestecapítulo,aconselhamosquevocêpasseausaroEclipse.VocêjátemconhecimentosuficientedoserrosdecompilaçãodojavaceagorapodeaprenderasfacilidadesqueoEclipsetetrazaoajudarvocênocódigocomoschamadosquickfixesequickassists.

VamosrecordaremcomopodeestarnossaclasseFuncionario:

publicclassFuncionario{

protectedStringnome;protectedStringcpf;protecteddoublesalario;

publicdoublegetBonificacao(){returnthis.salario*1.2;}

//outrosmétodosaqui

}

ConsidereonossoControleDeBonificacao:

publicclassControleDeBonificacoes{

privatedoubletotalDeBonificacoes=0;

publicvoidregistra(Funcionariof){System.out.println("Adicionandobonificaçãodofuncionario:"+f);this.totalDeBonificacoes+=f.getBonificacao();}

publicdoublegetTotalDeBonificacoes(){returnthis.totalDeBonificacoes;}}

Nossométodo registra recebe qualquer referência do tipo Funcionario, isto é, podem serobjetosdo tipoFuncionario e qualquerde seus subtipos:Gerente,Diretor e, eventualmente,

CLASSESABSTRATAS

10.1REPETINDOMAISCÓDIGO?

.

Page 150: FJ-11 Java e Orientação a Objetos

alguma nova subclasse que venha ser escrita, sem prévio conhecimento do autor daControleDeBonificacao.

EstamosutilizandoaquiaclasseFuncionarioparaopolimorfismo.Senãofosseela,teríamosumgrande prejuízo: precisaríamos criar um método registra para receber cada um dos tipos deFuncionario,umparaGerente,umparaDiretor,etc.Reparequeperderessepoderémuitopiordoqueapequenavantagemqueaherançatrazemherdarcódigo.

Porém,emalgunssistemas,comoéonossocaso,usamosumaclassecomapenasessesintuitos:deeconomizar um pouco código e ganhar polimorfismo para criar métodos mais genéricos, que seencaixemadiversosobjetos.

Faz sentido ter uma referência do tipoFuncionario? Essa pergunta é diferente de saber se fazsentidoterumobjetodotipoFuncionario:nessecaso,fazsimeémuitoútil.

ReferenciandoFuncionariotemosopolimorfismodereferência,jáquepodemosreceberqualquerobjetoquesejaumFuncionario.Porém,darnewemFuncionariopodenãofazersentido,istoé,não queremos receber umobjeto do tipoFuncionario,mas sim que aquela referência seja ou umGerente,ouumDiretor,etc.AlgomaisconcretoqueumFuncionario.

ControleDeBonificacoescdb=newControleDeBonificacoes();Funcionariof=newFuncionario();cdb.adiciona(f);//fazsentido?

Vejamosumoutrocasoemquenãofazsentidoterumobjetodaqueletipo,apesardaclasseexistir:imagineaclassePessoa e duas filhas,PessoaFisica ePessoaJuridica.Quandopuxamosumrelatóriodenossosclientes(umaarraydePessoaporexemplo),queremosquecadaumdelessejaouumaPessoaFisica,ouumaPessoaJuridica.A classePessoa, nesse caso, estaria sendousadaapenasparaganharopolimorfismoeherdaralgumascoisas:nãofazsentidopermitirinstanciá-la.

Pararesolveressesproblemas,temosasclassesabstratas.

.

Page 151: FJ-11 Java e Orientação a Objetos

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelum eobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

Oque,exatamente,vemaseranossaclasseFuncionario?NossaempresatemapenasDiretores,Gerentes, Secretárias, etc. Ela é uma classe que apenas idealiza um tipo, define apenas umrascunho.

Paraonossosistema,éinadmissívelqueumobjetosejaapenasdotipoFuncionario(podeexistirumsistemaemquefaçasentidoterobjetosdotipoFuncionarioouapenasPessoa,mas,nonossocaso,não).

Usamosapalavrachaveabstractparaimpedirqueelapossaserinstanciada.Esseéoefeitodiretodeseusaromodificadorabstractnadeclaraçãodeumaclasse:

publicabstractclassFuncionario{

protecteddoublesalario;

publicdoublegetBonificacao(){returnthis.salario*1.2;}

//outrosatributosemétodoscomunsatodosFuncionarios

}

E,nomeiodeumcódigo:

Funcionariof=newFuncionario();//nãocompila!!!

EditoraCasadoCódigocomlivrosdeumaformadiferente

10.2CLASSEABSTRATA

.

Page 152: FJ-11 Java e Orientação a Objetos

Ocódigoacimanãocompila.Oproblemaé instanciaraclasse-criarreferência,vocêpode.Seelanãopodeserinstanciada,paraqueserve?Serveparaopolimorfismoeherançadosatributosemétodos,quesãorecursosmuitopoderosos,comojávimos.

Vamosentãoherdardessaclasse,reescrevendoométodogetBonificacao:

publicclassGerenteextendsFuncionario{

publicdoublegetBonificacao(){returnthis.salario*1.4+1000;}}

Mas qual é a real vantagem de uma classe abstrata? Poderíamos ter feito isto com uma herançacomum. Por enquanto, a única diferença é que não podemos instanciar um objeto do tipoFuncionario,quejáédegrandevalia,dandomaisconsistênciaaosistema.

FiqueclaroqueanossadecisãodetransformarFuncionarioemumaclasseabstratadependeudonossodomínio.Podeserque,emumsistemacomclassessimilares,façasentidoqueumaclasseanálogaaFuncionariosejaconcreta.

SeométodogetBonificacaonãofossereescrito,eleseriaherdadodaclassemãe,fazendocomquedevolvesseosaláriomais20%.

Levando em consideração que cada funcionário em nosso sistema tem uma regra totalmentediferenteparaserbonificado,fazalgumsentidoteressemétodonaclasseFuncionario?Seráqueexisteumabonificaçãopadrãopara todo tipodeFuncionario?Parecequenão, cada classe filha teráum

10.3MÉTODOSABSTRATOS

.

Page 153: FJ-11 Java e Orientação a Objetos

método diferente de bonificação pois, de acordo com nosso sistema, não existe uma regra geral:queremos que cada pessoa que escreve a classe de um Funcionario diferente (subclasses deFuncionario)reescrevaométodogetBonificacaodeacordocomassuasregras.

Poderíamos,então, jogarforaessemétododaclasseFuncionario?Oproblemaéque, seelenãoexistisse, não poderíamos chamar o método apenas com uma referência a um Funcionario, poisninguém garante que essa referência aponta para um objeto que possui essemétodo. Será que entãodevemosretornarumcódigo,comoumnúmeronegativo?Issonãoresolveoproblema:seesquecermosdereescreveressemétodo,teremosdadoserradossendoutilizadoscomobônus.

ExisteumrecursoemJavaque,emumaclasseabstrata,podemosescreverquedeterminadométodoserásempreescritopelasclassesfilhas.Istoé,ummétodoabstrato.

Ele indicaque todasasclasses filhas (concretas, istoé,quenão foremabstratas)devemreescreveressemétodoounãocompilarão.Écomosevocêherdassearesponsabilidadedeteraquelemétodo.

COMODECLARARUMMÉTODOABSTRATO

Àsvezes,nãoficaclarocomodeclararummétodoabstrato.

Bastaescreverapalavrachaveabstractnaassinaturadomesmoecolocarumpontoevírgulaemvezdeabreefechachaves!

publicabstractclassFuncionario{

publicabstractdoublegetBonificacao();

//outrosatributosemétodos

}

Reparequenãocolocamosocorpodométodoeusamosapalavrachaveabstractparadefiniromesmo. Por que não colocar corpo algum?Porque essemétodo nunca vai ser chamado, sempre quealguémchamarométodogetBonificacao,vaicairemumadassuasfilhas,querealmenteescreveramométodo.

Qualquer classe que estender a classe Funcionario será obrigada a reescrever este método,tornando-o"concreto".Senãoreescreveremessemétodo,umerrodecompilaçãoocorrerá.

OmétododoControleDeBonificacaoestavaassim:

publicvoidregistra(Funcionariof){System.out.println("Adicionandobonificaçãodofuncionario:"+f);this.totalDeBonificacoes+=f.getBonificacao();}

.

Page 154: FJ-11 Java e Orientação a Objetos

ComopossoacessarométodogetBonificacaoseelenãoexistenaclasseFuncionario?

Jáqueométodoéabstrato,comcerteza suas subclasses têmessemétodo,oquegaranteque essainvocação demétodo não vai falhar. Basta pensar que uma referência do tipoFuncionario nuncaapontaparaumobjetoquenão temométodogetBonificacao, poisnão épossível instanciarumaclasse abstrata, apenas as concretas. Ummétodo abstrato obriga a classe em que ele se encontra serabstrata,oquegaranteacoerênciadocódigoacimacompilar.

E se, no nosso exemplo de empresa, tivéssemos o seguinte diagrama de classes com os seguintesmétodos:

Ouseja,tenhoaclasseabstrataFuncionario,comométodoabstratogetBonificacao;asclassesGerenteePresidenteestendendoFuncionarioeimplementandoométodogetBonificacao;e,porfim,aclasseDiretor,queestendeGerente,masnãoimplementaométodogetBonificacao.

Essasclassesvãocompilar?Vãorodar?

Arespostaésim.E,alémdetudo,farãoexatamenteoquenósqueremos,pois,quandoGerenteePresidentepossuemosmétodosperfeitamenteimplementados,aclasseDiretor,quenãopossuiométodoimplementado,vaiusaraimplementaçãoherdadadeGerente.

10.4AUMENTANDOOEXEMPLO

.

Page 155: FJ-11 Java e Orientação a Objetos

E esse diagrama, no qual incluímos uma classe abstrata Secretaria sem o método getBonificacao , que é estendida por mais duas classes ( SecretariaAdministrativa ,SecretariaAgencia)que,porsuavez,implementamométodogetBonificacao,vaicompilar?Vairodar?

Denovo,arespostaésim,poisSecretariaéumaclasseabstratae,porisso,oJavatemcertezadeque ninguém vai conseguir instanciá-la e, muito menos, chamar o método getBonificacao dela.Lembrando que, nesse caso, não precisamos nem ao menos escrever o método abstratogetBonificacaonaclasseSecretaria.

Seeunãoreescreverummétodoabstratodaminhaclassemãe,ocódigonãocompilará.Masposso,emvezdisso,declararaclassecomoabstrata!

JAVA.IO

Classes abstratas nãopossuemnenhum segredono aprendizado,mas quem está aprendendoorientaçãoaobjetospodeterumaenormedificuldadeparasaberquandoutilizá-las,oqueémuitonormal.

Estudaremosopacotejava.io,queusabastantesclassesabstratas,sendoumexemplorealdeusodesserecurso,quevaimelhoraroentendimentodelas.(classeInputStreamesuasfilhas)

.

Page 156: FJ-11 Java e Orientação a Objetos

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

Uma classe que estende uma classe normal também pode ser abstrata! Ela não poderá serinstanciada,massuaclassepaisim!

Umaclasseabstratanãoprecisanecessariamenteterummétodoabstrato.

1. ReparequeanossaclasseContaéumaexcelentecandidataparaumaclasseabstrata.Porquê?Quemétodosseriaminteressantescandidatosaseremabstratos?

TransformeaclasseContaemabstrata:

publicabstractclassConta{//...}

2. ComoaclasseContaagoraéabstrata,nãoconseguimosdarnewnelamais.SenãopodemosdarnewemConta,qualéautilidadedeterummétodoquerecebeumareferênciaaContacomoargumento?Aliás,possoterisso?

3. Apenasparaentendermelhoroabstract,comenteométodogetTipo()daContaPoupanca,dessaformaeleherdaráométododiretamentedeConta.

TransformeométodogetTipo()daclasseContaemabstrato.Repareque,aocolocarapalavrachaveabstract ao ladodométodo,oEclipse rapidamentevai sugerirquevocêdeve removerocorpo(body)dométodocomumquickfix.

SuaclasseContadeveficarparecidacom:

JáconheceoscursosonlineAlura?

10.5PARASABERMAIS...

10.6EXERCÍCIOS:CLASSESABSTRATAS

.

Page 157: FJ-11 Java e Orientação a Objetos

publicabstractclassConta{//atributosemétodosquejáexistiam

publicabstractStringgetTipo();}

QualéoproblemacomaclasseContaPoupanca?

4. DescomenteométodogetTipo na classeContaPoupanca, e se necessário altere-o para que aclassepossacompilarnormalmente.

5. (opcional) Existe outramaneira de a classe ContaPoupanca compilar se você não reescrever ométodoabstrato?

6. (opcional)PraqueterométodogetTiponaclasseContaseelenãofaznada?OqueacontecesesimplesmenteapagarmosessemétododaclasseContaedeixarmosométodogetTiponasfilhas?

7. (opcional) Posso chamar ummétodo abstrato de dentro de um outro método da própria classeabstrata?Porexemplo,imaginequeexistaoseguintemétodonaclasseConta:

publicStringrecuperaDadosParaImpressao(){Stringdados="Titular:"+this.titular;dados+="\nNúmero:"+this.numero;dados+="\nAgência:"+this.agencia;dados+="\nSaldo:R$"+this.saldo;returndados;}

PodemosinvocarogetTipodentrodestemétodo?Algocomo:

dados+="\nTipo:"+this.getTipo();

.

Page 158: FJ-11 Java e Orientação a Objetos

CAPÍTULO11

"Umaimagemvalemilpalavras.Umainterfacevalemilimagens."--BenShneiderman

Aotérminodessecapítulo,vocêserácapazde:

dizeroqueéumainterfaceeasdiferençasentreherançaeimplementação;escreverumainterfaceemJava;utilizá-lascomoumpoderosorecursoparadiminuiracoplamentoentreasclasses.

Imagine que umSistemadeControle doBanco pode ser acessado, alémde pelosGerentes, pelosDiretoresdoBanco.Então,teríamosumaclasseDiretor:

publicclassDiretorextendsFuncionario{

publicbooleanautentica(intsenha){//verificaaquiseasenhaconferecomarecebidacomoparametro}

}

EaclasseGerente:

publicclassGerenteextendsFuncionario{

publicbooleanautentica(intsenha){//verificaaquiseasenhaconferecomarecebidacomoparametro//nocasodogerenteverificatambémseodepartamentodele//temacesso}

}

INTERFACES

11.1AUMENTANDONOSSOEXEMPLO

.

Page 159: FJ-11 Java e Orientação a Objetos

ReparequeométododeautenticaçãodecadatipodeFuncionariopodevariarmuito.Masvamosaosproblemas.Considere oSistemaInterno e seu controle: precisamos receber umDiretor ouGerentecomoargumento,verificarseeleseautenticaecolocá-lodentrodosistema.

publicclassSistemaInterno{

publicvoidlogin(Funcionariofuncionario){//invocarométodoautentica?//nãoda!NemtodoFuncionariotem}}

OSistemaInternoaceitaqualquertipodeFuncionario,tendoeleacessoaosistemaounão,masnote que nem todo Funcionario possui ométodo autentica. Isso nos impede de chamar essemétodo com uma referência apenas aFuncionario (haveria um erro de compilação).O que fazerentão?

publicclassSistemaInterno{

publicvoidlogin(Funcionariofuncionario){funcionario.autentica(...);//nãocompila}}

UmapossibilidadeécriardoismétodosloginnoSistemaInterno:umparareceberDiretoreoutroparareceberGerente.Jávimosqueessanãoéumaboaescolha.Porquê?

publicclassSistemaInterno{

//designproblemáticopublicvoidlogin(Diretorfuncionario){funcionario.autentica(...);}

//designproblemáticopublicvoidlogin(Gerentefuncionario){funcionario.autentica(...);}

}

.

Page 160: FJ-11 Java e Orientação a Objetos

Cada vez que criarmos uma nova classe de Funcionario que é autenticável, precisaríamosadicionarumnovométododeloginnoSistemaInterno.

MÉTODOSCOMMESMONOME

EmJava,métodospodemteromesmonomedesdequenãosejamambíguos,istoé,queexistaumamaneiradedistinguirnomomentodachamada.

Issosechamasobrecargademétodo.(Overloading.Nãoconfundircomoverriding,queéumconceitomuitomaispoderoso).

Uma solução mais interessante seria criar uma classe no meio da árvore de herança,FuncionarioAutenticavel:

publicclassFuncionarioAutenticavelextendsFuncionario{

publicbooleanautentica(intsenha){//fazautenticacaopadrão}

//outrosatributosemétodos

}

As classes Diretor e Gerente passariam a estender de FuncionarioAutenticavel , e oSistemaInternoreceberiareferênciasdessetipo,comoaseguir:

publicclassSistemaInterno{

publicvoidlogin(FuncionarioAutenticavelfa){

intsenha=//pegasenhadeumlugar,oudeumscannerdepolegar

//aquieupossochamaroautentica!//PoistodoFuncionarioAutenticaveltembooleanok=fa.autentica(senha);

}}

.

Page 161: FJ-11 Java e Orientação a Objetos

Repare que FuncionarioAutenticavel é uma forte candidata a classe abstrata. Mais ainda, ométodoautenticapoderiaserummétodoabstrato.

O uso de herança resolve esse caso,mas vamos a uma outra situação um poucomais complexa:precisamosquetodososclientestambémtenhamacessoaoSistemaInterno.Oquefazer?UmaopçãoécriaroutrométodologinemSistemaInterno:masjádescartamosessaanteriormente.

Uma outra, que é comum entre os novatos, é fazer uma herança sem sentido para resolver oproblema, por exemplo, fazerClienteextendsFuncionarioAutenticavel. Realmente, resolve oproblema,mastrarádiversosoutros.ClientedefinitivamentenãoéFuncionarioAutenticavel.Sevocê fizer isso,oCliente terá, por exemplo, ummétodogetBonificacao, umatributo salario eoutrosmembrosquenãofazemomenorsentidoparaestaclasse!Nãofaçaherançaquandoarelaçãonãoéestritamente"éum".

.

Page 162: FJ-11 Java e Orientação a Objetos

Como resolver essa situação? Note que conhecer a sintaxe da linguagem não é o suficiente,precisamosestruturar/desenharbemanossaestruturadeclasses.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

O que precisamos para resolver nosso problema? Arranjar uma forma de poder referenciar

SaberinglêsémuitoimportanteemTI

11.2INTERFACES

.

Page 163: FJ-11 Java e Orientação a Objetos

Diretor,GerenteeClientedeumamesmamaneira,istoé,acharumfatorcomum.

Seexistisseuma formanaqual essas classesgarantissemaexistênciadeumdeterminadométodo,atravésdeumcontrato,resolveríamosoproblema.

Todaclassedefine2itens:

oqueumaclassefaz(asassinaturasdosmétodos)comoumaclassefazessastarefas(ocorpodosmétodoseatributosprivados)

Podemos criar um "contrato" que define tudo o que uma classe deve fazer se quiser ter umdeterminadostatus.Imagine:

contratoAutenticavel:

quemquiserserAutenticavelprecisasaberfazer:1.autenticardadaumasenha,devolvendoumbooleano

Quem quiser, pode "assinar" esse contrato, sendo assim obrigado a explicar como será feita essaautenticação.Avantageméque,seumGerenteassinaressecontrato,podemosnosreferenciaraumGerentecomoumAutenticavel.

PodemoscriaressecontratoemJava!

publicinterfaceAutenticavel{

booleanautentica(intsenha);

}

Chama-seinterfacepoiséamaneirapelaqualpoderemosconversarcomumAutenticavel.Interfaceéamaneiraatravésdaqualconversamoscomumobjeto.

Lemosainterfacedaseguintemaneira:"quemdesejarserautenticávelprecisasaberautenticardadoum inteiro e retornando um booleano". Ela é um contrato onde quem assina se responsabiliza porimplementaressesmétodos(cumprirocontrato).

Uma interfacepodedefinirumasériedemétodos,masnuncaconter implementaçãodeles.Ela sóexpõeoqueoobjetodevefazer,enãocomoelefaz,nemoqueeletem.Comoelefazvaiserdefinidoemumaimplementaçãodessainterface.

EoGerentepode"assinar"ocontrato,ouseja,implementarainterface.Nomomentoemqueeleimplementaessainterface,eleprecisaescreverosmétodospedidospelainterface(muitoparecidocomoefeitodeherdarmétodosabstratos,aliás,métodosdeuma interfacesãopúblicoseabstratos, sempre).Paraimplementarusamosapalavrachaveimplementsnaclasse:

publicclassGerenteextendsFuncionarioimplementsAutenticavel{

privateintsenha;

.

Page 164: FJ-11 Java e Orientação a Objetos

//outrosatributosemétodos

publicbooleanautentica(intsenha){if(this.senha!=senha){returnfalse;}//podefazeroutraspossíveisverificações,comosaberseesse//departamentodogerentetemacessoaoSistema

returntrue;}

}

Oimplementspodeserlidodaseguintemaneira:"AclasseGerentesecomprometeasertratadacomoAutenticavel,sendoobrigadaaterosmétodosnecessários,definidosnestecontrato".

Apartirdeagora,podemostratarumGerentecomosendoumAutenticavel.Ganhamosmaispolimorfismo!TemosmaisumaformadereferenciaraumGerente.QuandocrioumavariáveldotipoAutenticavel, estou criando uma referência paraqualquer objeto de uma classe que implementeAutenticavel,diretaouindiretamente:

Autenticavela=newGerente();//possoaquichamarométodoautentica!

Novamente, a utilização mais comum seria receber por argumento, como no nossoSistemaInterno:

publicclassSistemaInterno{

publicvoidlogin(Autenticavela){intsenha=//pegasenhadeumlugar,oudeumscannerdepolegarbooleanok=a.autentica(senha);

//aquieupossochamaroautentica!//nãonecessariamenteéumFuncionario!//Maisainda,eunãoseiqueobjetoa//referência"a"estáapontandoexatamente!Flexibilidade.

.

Page 165: FJ-11 Java e Orientação a Objetos

}

}

Pronto!EjápodemospassarqualquerAutenticavelparaoSistemaInterno.EntãoprecisamosfazercomqueoDiretortambémimplementeessainterface.

publicclassDiretorextendsFuncionarioimplementsAutenticavel{

//métodoseatributos,alémdeobrigatoriamenteteroautentica

}

PodemospassarumDiretor.Nodiaemquetivermosmaisumfuncionáriocomacessoaosistema,bastaqueeleimplementeessainterface,paraseencaixarnosistema.

QualquerAutenticavelpassadoparaoSistemaInternoestábomparanós.Reparequepoucoimporta quem o objeto referenciado realmente é, pois ele tem um método autentica que é onecessário para nosso SistemaInterno funcionar corretamente. Aliás, qualquer outra classe quefuturamenteimplementeessainterfacepoderáserpassadacomoargumentoaqui.

Autenticaveldiretor=newDiretor();Autenticavelgerente=newGerente();

Ou,seachamosqueoFornecedorprecisateracesso,bastaqueeleimplementeAutenticavel.Olhesóotamanhododesacoplamento:quemescreveuoSistemaInternosóprecisasaberqueeleéAutenticavel.

publicclassSistemaInterno{

publicvoidlogin(Autenticavela){//nãoimportaseeleéumgerenteoudiretor//seráqueéumfornecedor?//Eu,oprogramadordoSistemaInterno,nãomepreocupo//Invocareiométodoautentica}

}

.

Page 166: FJ-11 Java e Orientação a Objetos

NãofazdiferençaseéumDiretor,Gerente,Cliente ouqualquer classe que venhapor aí.Basta seguir o contrato! Mais ainda, cada Autenticavel pode se autenticar de uma maneiracompletamentediferentedeoutro.

Lembre-se: a interface define que todos vão saber se autenticar (o que ele faz), enquanto aimplementaçãodefinecomoexatamentevaiserfeito(comoelefaz).

Amaneiracomoosobjetossecomunicamnumsistemaorientadoaobjetosémuitomaisimportantedoquecomoelesexecutam.Oqueumobjetofazémaisimportantedoquecomoelefaz.Aquelesqueseguemessaregra,terãosistemasmaisfáceisdemanteremodificar.Comovocêjápercebeu,estaéumadasideiasprincipaisquequeremospassare,provavelmente,amaisimportantedetodoessecurso.

MAISSOBREINTERFACES:HERANÇAEMÉTODOSDEFAULT

Diferentementedasclasses,umainterfacepodeherdardemaisdeumainterface.Écomoumcontrato que depende que outros contratos sejam fechados antes deste valer. Você não herdamétodoseatributos,massimresponsabilidades.

Um outro recurso em interfaces são os métodos default a partir do Java 8. Você pode simdeclararummétodoconcreto,utilizandoapalavradefaultaolado,esuasimplementaçõesnãoprecisamnecessariamente reescrevê-lo.Veremos que isso acontece, por exemplo, comométodoList.sort,duranteocapítulodecoleções.Éumtruquemuitoutilizadoparapoderevoluirumainterfacesemquebrarcompatibilidadecomasimplementaçõesanteriores.

Interfaces representamuma barreira no aprendizado do Java: parece que estamos escrevendo umcódigoquenão servepranada, jáque teremosessa linha (a assinaturadométodo) escritanasnossasclassesimplementadoras.Essaéumamaneiraerradadesepensar.Oobjetivodousodeumainterfaceédeixarseucódigomaisflexívelepossibilitaramudançadeimplementaçãosemmaiorestraumas.Nãoéapenasumcódigodeprototipação,umcabeçalho!

Os mais radicais dizem que toda classe deve ser "interfaceada", isto é, só devemos nos referir aobjetos através de suas interfaces. Se determinada classe não tem uma interface, ela deveria ter. Osautoresdestematerialachamtalmedidaradicaldemais,porémousodeinterfacesemvezdeherançaéamplamente aconselhado. Você pode encontrar mais informações sobre o assunto nos livrosDesignPatterns,RefactoringeEffectiveJava.

NolivroDesignPatterns,logonoinício,osautorescitam2regras"deouro".Umaé"eviteherança,prefiracomposição"eaoutra,"programevoltadoainterfaceenãoàimplementação".

11.3DIFICULDADENOAPRENDIZADODEINTERFACES

.

Page 167: FJ-11 Java e Orientação a Objetos

Veremosousodeinterfacesnocapítulodecoleções,oquemelhoraoentendimentodoassunto.OexemplodainterfaceComparabletambémémuitoesclarecedor,ondeenxergamosoreaproveitamentodecódigoatravésdasinterfaces,alémdoencapsulamento.ParaométodoCollections.sort(),poucoimporta quem vai ser passado como argumento. Para ele, basta que a coleção seja de objetoscomparáveis.ElepodeordenarElefante,ConexaoouContaCorrente, desdeque implementemComparable.

Comofazercomquetodasaschamadasparabancosdedadosdiferentesrespeitemamesmaregra?Usandointerfaces!

Imagine uma interfaceConexao contendo todos os métodos necessários para a comunicação etroca de dados com um banco de dados. Cada banco de dados fica encarregado de criar a suaimplementaçãoparaessainterface.

QuemforusarumaConexaonãoprecisaseimportarcomqualobjetoexatamenteestátrabalhando,jáqueelevai cumpriropapelque todaConexao deve ter.Não importa se é uma conexão comumOracleouMySQL.

Apesar do java.sql.Connection não trabalhar bem assim, a ideia é muito similar, porém asconexõesvêmdeumafactorychamadaDriverManager.

Conexãoabancodedadosestáforadoescopodessetreinamento,maséumdosprimeirostópicosabordadosnocursoFJ-21,juntamentecomDAO.

11.4EXEMPLOINTERESSANTE:CONEXÕESCOMOBANCODEDADOS

.

Page 168: FJ-11 Java e Orientação a Objetos

UMPOUCOMAIS...

Possosubstituirtodaminhaherançaporinterfaces?Qualéavantagemeadesvantagem?

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

1. Nossobancoprecisatributardinheirodealgunsbensquenossosclientespossuem.Paraissovamoscriarumainterfacenopacotebr.com.caelum.contas.modelodonossoprojetofj11-contasjáexistente:

publicinterfaceTributavel{publicdoublegetValorImposto();publicStringgetTitular();publicStringgetTipo();}

Lemosessainterfacedaseguintemaneira:"todosquequiseremsertributávelprecisamsaberretornarovalordoimposto,devolvendoumdouble".

Algunsbenssãotributáveiseoutrosnão,ContaPoupancanãoétributável,jáparaContaCorrentevocêprecisapagar1%dacontaeoSeguroDeVidatemumataxafixade42reaismais2%dovalordoseguro.

AproveiteoEclipse!QuandovocêescreverimplementsTributavelnaclasseContaCorrente,oquickfixdoEclipsevaisugerirquevocêreescrevaométodo;escolhaessaopçãoe,depois,preenchaocorpodométodoadequadamente:

AprendasedivertindonaAluraStart!

11.5EXERCÍCIOS:INTERFACES

.

Page 169: FJ-11 Java e Orientação a Objetos

publicclassContaCorrenteextendsContaimplementsTributavel{

//outrosatributosemétodos

publicdoublegetValorImposto(){returnthis.getSaldo()*0.01;}}

CrieaclasseSeguroDeVida,aproveitandonovamentedoEclipse,paraobter:

publicclassSeguroDeVidaimplementsTributavel{privatedoublevalor;privateStringtitular;privateintnumeroApolice;

publicdoublegetValorImposto(){return42+this.valor*0.02;}

//gettersesettersparaosatributos}

2. Vamos criar a classeManipuladorDeSeguroDeVida dentro do pacote br.com.caelum.contaspara vincular a classeSeguroDeVida com a tela de criação de seguros. Esta classe deve ter umatributodotipoSeguroDeVida.

Crie também o método criaSeguro que deve receber um parâmetro do tipo Evento paraconseguirobterosdadosda tela.Vocêdevepegarosparâmetros "numeroApolice"do tipoint,"titular"dotipoStringe"valor"dotipodouble.

Ocódigofinaldeveficarparecidocomocódigoabaixo:

packagebr.com.caelum.contas;

importbr.com.caelum.contas.modelo.SeguroDeVida;importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeSeguroDeVida{

privateSeguroDeVidaseguroDeVida;

publicvoidcriaSeguro(Eventoevento){this.seguroDeVida=newSeguroDeVida();this.seguroDeVida.setNumeroApolice(evento.getInt("numeroApolice"));this.seguroDeVida.setTitular(evento.getString("titular"));this.seguroDeVida.setValor(evento.getDouble("valor"));}}

3. ExecuteaclasseTestaContasetentecadastrarumnovosegurodevida.Osegurocadastradodeveaparecernatabeladesegurosdevida.

4. Queremosagorasaberqualovalortotaldosimpostosdetodosostributáveis.VamosentãocriaraclasseManipuladorDeTributaveis dentrodopacotebr.com.caelum.contas.Crie tambémométodocalculaImpostosquerecebeumparâmetrodotipoEvento:

.

Page 170: FJ-11 Java e Orientação a Objetos

packagebr.com.caelum.contas;

importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeTributaveis{

publicvoidcalculaImpostos(Eventoevento){//aquicalcularemosototal}}

5. Agora que criamos o tributavel, vamos habilitar a última aba de nosso sistema. Altere a classeTestaContasparapassarovalortruenachamadadométodomostraTela.Observequeagoraque temos o seguro de vida funcionando, a tela de relatório já consegue imprimir o valor dosimpostosindividuaisdecadatipodeTributavel.

6. NométodocalculaImpostosprecisamosbuscarosvaloresdeimpostosdecadaTributavel esomá-los. Para saber a quantidade de tributáveis, a classe Evento possui ummétodo chamadogetTamanhoDaListaquedevereceberonomeda listadesejada,nocaso"listaTributaveis".ExistetambémumoutrométodoqueretornaumTributaveldeumadeterminadaposiçãodeumalista,ondeprecisamospassaronomedalistaeoíndicedoelemento.Precisamospercorreralistainteira,passandoporcadaposiçãoentãoutilizaremosumforparaisto.

packagebr.com.caelum.contas;

importbr.com.caelum.contas.modelo.Tributavel;importbr.com.caelum.javafx.api.util.Evento;

publicclassManipuladorDeTributaveis{

privatedoubletotal;

publicvoidcalculaImpostos(Eventoevento){total=0;inttamanho=evento.getTamanhoDaLista("listaTributaveis");for(inti=0;i<tamanho;i++){Tributavelt=evento.getTributavel("listaTributaveis",i);total+=t.getValorImposto();}}

publicdoublegetTotal(){returntotal;}}

Repare que, de dentro do ManipuladorDeTributaveis , você não pode acessar o métodogetSaldo,porexemplo,poisvocênãotemagarantiadequeoTributavelquevaiserpassadocomo argumento tem esse método. A única certeza que você tem é de que esse objeto tem osmétodosdeclaradosnainterfaceTributavel.

Éinteressanteenxergarqueasinterfaces(comoaqui,nocaso,Tributavel)costumamligarclassesmuito distintas, unindo-as por uma característica que elas tem em comum. No nosso exemplo,

.

Page 171: FJ-11 Java e Orientação a Objetos

SeguroDeVidaeContaCorrentesãoentidadescompletamentedistintas,porémambaspossuemacaracterísticadeseremtributáveis.

SeamanhãogovernocomeçaratributaratémesmoPlanoDeCapitalizacao,bastaqueessaclasseimplemente a interface Tributavel! Repare no grau de desacoplamento que temos: a classeGerenciadorDeImpostoDeRendanemimaginaquevaitrabalharcomoPlanoDeCapitalizacao.Para ela, o único fato que importa é que o objeto respeite o contrato de um tributável, isso é, ainterfaceTributavel.Novamente:programevoltadoàinterface,nãoàimplementação.

Quaisosbenefíciosdemanterocódigocombaixoacoplamento?

7. (opcional)CrieaclasseTestaTributavelcomummétodomainparatestaronossoexemplo:

publicclassTestaTributavel{

publicstaticvoidmain(String[]args){ContaCorrentecc=newContaCorrente();cc.deposita(100);System.out.println(cc.getValorImposto());

//testandopolimorfismo:Tributavelt=cc;System.out.println(t.getValorImposto());}}

TentechamarométodogetSaldoatravésdareferênciat,oqueocorre?Porquê?

AlinhaemqueatribuímosccaumTributaveléapenasparavocêenxergarqueépossívelfazê-lo.Nessenossocaso,issonãotemumautilidade.Essapossibilidadefoiútilnoexercícioanterior.

Atenção: caso você faça esse exercício, faça isso num projeto à parte conta-interface já queusaremosaContacomoclasseemexercíciosfuturos.

1. (Opcional)TransformeaclasseContaemumainterface.

publicinterfaceConta{publicdoublegetSaldo();publicvoiddeposita(doublevalor);publicvoidsaca(doublevalor);publicvoidatualiza(doubletaxaSelic);}

AdapteContaCorrenteeContaPoupancaparaessamodificação:

publicclassContaCorrenteimplementsConta{//...}

publicclassContaPoupancaimplementsConta{//...

11.6EXERCÍCIOSAVANÇADOSOPCIONAIS

.

Page 172: FJ-11 Java e Orientação a Objetos

}

Algumcódigovaiterdesercopiadoecolado?Issoétãoruim?

2. (Opcional)Àsvezes,éinteressantecriarmosumainterfacequeherdadeoutrasinterfaces:essas,sãochamadassubinterfaces.Essas,nadamaissãodoqueumagrupamentodeobrigaçõesparaaclassequeaimplementar.

publicinterfaceContaTributavelextendsConta,Tributavel{}

Dessamaneira, quem for implementar essa nova interface precisa implementar todos osmétodosherdadosdassuassuperinterfaces(etalvezaindanovosmétodosdeclaradosdentrodela):

publicclassContaCorrenteimplementsContaTributavel{//métodos}

Contac=newContaCorrente();Tributavelt=newContaCorrente();

Reparequeocódigopodeparecerestranho,poisainterfacenãodeclaramétodoalgum,sóherdaosmétodosabstratosdeclaradosnasoutrasinterfaces.

Aomesmotempoqueumainterfacepodeherdardemaisdeumaoutrainterface,classessópodempossuirumaclassemãe(herançasimples).

Discuta com o instrutor e seus colegas, alternativas à herança. Falaremos de herança versuscomposiçãoeporquêaherançaémuitasvezesconsideradamaléfica.

Numaentrevista,JamesGosling,"paidojava",falasobreumalinguagempuramentededelegaçãoechegaadizer:

Ratherthansubclassing,justusepureinterfaces.It'snotsomuchthatclassinheritanceisparticularlybad.Itjusthasproblems.

(Tradução livre: "Em vez de fazer subclasses, use simplesmente interfaces. Não é que a herança declassessejaparticularmenteruim.Elasótemproblemas.")

http://www.artima.com/intv/gosling3P.html

No blog da Caelum há também um post sobre o assunto:http://blog.caelum.com.br/2006/10/14/como-nao-aprender-orientacao-a-objetos-heranca/

11.7DISCUSSÃO:FAVOREÇACOMPOSIÇÃOEMRELAÇÃOÀHERANÇA

.

Page 173: FJ-11 Java e Orientação a Objetos

Conheça a Casa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Com a curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

.

Page 174: FJ-11 Java e Orientação a Objetos

CAPÍTULO12

"Quempensapouco,erramuito"--LeonardodaVinci

Aotérminodessecapítulo,vocêserácapazde:

controlarerrosetomardecisõesbaseadasnosmesmos;criarnovostiposdeerrosparamelhorarotratamentodelesemsuaaplicaçãooubiblioteca;assegurarqueummétodofuncionoucomodizemseu"contrato".

Voltando às Contas que criamos no capítulo 6, o que aconteceria ao tentar chamar ométodosacacomumvalorforadolimite?Osistemamostrariaumamensagemdeerro,masquemchamouométodosacanãosaberáqueissoaconteceu.

Comoavisaraquelequechamouométododequeelenãoconseguiufazeraquiloquedeveria?

Em Java, os métodos dizem qual o contrato que eles devem seguir. Se, ao tentar sacar, ele nãoconseguefazeroquedeveria,eleprecisa,aomenos,avisaraousuárioqueosaquenãofoifeito.

Vejanoexemploabaixo:estamosforçandoumaContaaterumvalornegativo, istoé,estarnumestadoinconsistentedeacordocomanossamodelagem.

ContaminhaConta=newConta();minhaConta.deposita(100);minhaConta.setLimite(100);minhaConta.saca(1000);//osaldoé-900?É100?É0?Achamadaaométodosacafuncionou?

Em sistemas de verdade, é muito comum que quem saiba tratar o erro é aquele que chamou ométodo e não a própria classe! Portanto, nada mais natural do que a classe sinalizar que um erroocorreu.

A solução mais simples utilizada antigamente é a de marcar o retorno de um método comobooleaneretornartrue,setudoocorreudamaneiraplanejada,oufalse,casocontrário:

booleansaca(doublequantidade){//possosacaratésaldo+limiteif(quantidade>this.saldo+this.limite){System.out.println("Nãopossosacarforadolimite!");returnfalse;

EXCEÇÕESECONTROLEDEERROS

12.1MOTIVAÇÃO

.

Page 175: FJ-11 Java e Orientação a Objetos

}else{this.saldo=this.saldo-quantidade;returntrue;}}

Umnovoexemplodechamadaaométodoacima:

ContaminhaConta=newConta();minhaConta.deposita(100);minhaConta.setLimite(100);if(!minhaConta.saca(1000)){System.out.println("Nãosaquei");}

Reparequetivemosdelembrardetestaroretornodométodo,masnãosomosobrigadosafazerisso.Esquecerdetestaroretornodessemétodoteriaconsequênciasdrásticas:amáquinadeautoatendimentopoderiaviraliberaraquantiadesejadadedinheiro,mesmoqueosistemanãotivesseconseguidoefetuarométodosacacomsucesso,comonoexemploaseguir:

ContaminhaConta=newConta();minhaConta.deposita(100);

//...doublevalor=5000;minhaConta.saca(valor);//vairetornarfalse,masninguémverifica!caixaEletronico.emite(valor);

Mesmo invocando o método e tratando o retorno de maneira correta, o que faríamos se fossenecessáriosinalizarquandoousuáriopassouumvalornegativocomoquantidade?Umasoluçãoseriaalteraroretornodebooleanparainteretornarocódigodoerroqueocorreu.Issoéconsideradoumamáprática(conhecidatambémcomousode"magicnumbers").

Alémdevocêperderoretornodométodo,ovalordevolvidoé"mágico"esólegívelperanteextensadocumentação,alémdenãoobrigaroprogramadoratrataresseretornoe,nocasodeesquecerisso,seuprogramacontinuarárodandojánumestadoinconsistente.

Repareoqueaconteceriasefossenecessárioretornarumoutrovalor.Oexemploabaixomostraumcasoonde, atravésdo retorno,não serápossíveldescobrir seocorreuumerroounão,poisométodoretornaumcliente.

publicClienteprocuraCliente(intid){if(idInvalido){//avisaométodoquechamouestequeocorreuumerro}else{Clientecliente=newCliente();cliente.setId(id);//cliente.setNome("nomedocliente");returncliente;}}

Poresseseoutrosmotivos,utilizamosumcódigodiferenteemJavaparatrataraquiloquechamamosde exceções: os casos onde acontece algo que, normalmente, não iria acontecer. O exemplo do

.

Page 176: FJ-11 Java e Orientação a Objetos

argumentodosaqueinválidooudoidinválidodeumclienteéumaexceçãoàregra.

EXCEÇÃO

Uma exceção representa uma situação que normalmente não ocorre e representa algo deestranhoouinesperadonosistema.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

Antesderesolvermosonossoproblema,vamosvercomoaJavaVirtualMachineageaosedepararcomsituaçõesinesperadas,comodivisãoporzeroouacessoaumíndicedaarrayquenãoexiste.

1. ParaaprendermososconceitosbásicosdasexceptionsdoJava,testeoseguintecódigovocêmesmo:

classTesteErro{publicstaticvoidmain(String[]args){System.out.println("iniciodomain");metodo1();System.out.println("fimdomain");}

staticvoidmetodo1(){System.out.println("iniciodometodo1");metodo2();System.out.println("fimdometodo1");}

staticvoidmetodo2(){System.out.println("iniciodometodo2");ContaCorrentecc=newContaCorrente();for(inti=0;i<=15;i++){cc.deposita(i+1000);System.out.println(cc.getSaldo());

JáconheceoscursosonlineAlura?

12.2EXERCÍCIOPARACOMEÇARCOMOSCONCEITOS

.

Page 177: FJ-11 Java e Orientação a Objetos

if(i==5){cc=null;}}System.out.println("fimdometodo2");}}

Repareométodomainchamandometodo1eesse,porsuavez,chamandoometodo2.Cadaumdessesmétodospodetersuasprópriasvariáveislocais,istoé:ometodo1nãoenxergaasvariáveisdeclaradasdentrodomaineporaíemdiante.

ComooJava(emuitasdasoutraslinguagens)fazisso?Todainvocaçãodemétodoéempilhadaemuma estrutura de dados que isola a área dememória de cada um. Quando ummétodo termina(retorna), ele volta para ométodoque o invocou.Ele descobre isso através dapilhade execução(stack):bastaremoveromarcadorqueestánotopodapilha:

Porém, o nosso metodo2 propositadamente possui um enorme problema: está acessando umareferêncianulaquandooíndiceforiguala6!

Rodeocódigo.Qualéasaída?Oqueissorepresenta?Oqueelaindica?

Essa saída é o conhecido rastro da pilha (stacktrace). É uma saída importantíssima para oprogramador - tanto que, em qualquer fórum ou lista de discussão, é comum os programadoresenviarem,juntamentecomadescriçãodoproblema,essastacktrace.Masporqueissoaconteceu?

O sistema de exceções do Java funciona da seguinte maneira: quando uma exceção é lançada(throw), a JVMentra em estadode alerta e vai ver se ométodo atual toma algumaprecaução aotentarexecutaressetrechodecódigo.Comopodemosver,ometodo2nãotomanenhumamedidadiferentedoquevimosatéagora.

.

Page 178: FJ-11 Java e Orientação a Objetos

Comoometodo2nãoestátratandoesseproblema,aJVMpáraaexecuçãodeleanormalmente,semesperareleterminar,evoltaumstackframeprabaixo,ondeseráfeitanovaverificação:"ometodo1está se precavendo de um problema chamado NullPointerException?" "Não..." Volta para omain, onde tambémnãoháproteção, então a JVMmorre (na verdade, quemmorre é apenas a Thread corrente; se quiser saber mais sobre, há um apêndice de Threads e ProgramaçãoConcorrentenofinaldaapostila).

Obviamente,aquiestamosforçandoessecasoenãofariasentidotomarmoscuidadocomele.Éfácilarrumar um problema desses: basta verificar antes de chamar osmétodos se a variável está comreferêncianula.

Porém,apenasparaentenderocontroledefluxodeumaException,vamoscolocarocódigoquevaitentar(try)executaroblocoperigosoe,casooproblemasejadotipoNullPointerException,eleserápego(caught).ReparequeéinteressantequecadaexceçãonoJavatenhaumtipo...elapodeteratributosemétodos.

2. Adicioneumtry/catchemvoltadofor,pegandoNullPointerException.Oqueo códigoimprime?

try{for(inti=0;i<=15;i++){cc.deposita(i+1000);System.out.println(cc.getSaldo());if(i==5){cc=null;}}}catch(NullPointerExceptione){System.out.println("erro:"+e);}

3. Emvezdefazerotryemtornodoforinteiro,tenteapenascomoblocodedentrodofor:

for(inti=0;i<=15;i++){try{

.

Page 179: FJ-11 Java e Orientação a Objetos

cc.deposita(i+1000);System.out.println(cc.getSaldo());if(i==5){cc=null;}}catch(NullPointerExceptione){System.out.println("erro:"+e);}}

Qualéadiferença?

4. Retireotry/catchecoloqueeleemvoltadachamadadometodo2.

System.out.println("iniciodometodo1");try{metodo2();}catch(NullPointerExceptione){System.out.println("erro:"+e);}System.out.println("fimdometodo1");

.

Page 180: FJ-11 Java e Orientação a Objetos

5. Façaomesmo,retirandootry/catchnovamenteecolocandoemvoltadachamadadometodo1.Rodeoscódigos,oqueacontece?

System.out.println("iniciodomain");try{metodo1();}catch(NullPointerExceptione){System.out.println("erro:"+e);}System.out.println("fimdomain");

Repareque,apartirdomomentoqueumaexceptionfoicatched(pega,tratada,handled),aexecuçãovoltaaonormalapartirdaqueleponto.

12.3EXCEÇÕESDERUNTIMEMAISCOMUNS

.

Page 181: FJ-11 Java e Orientação a Objetos

Quetaltentardividirumnúmeroporzero?SeráqueaJVMconseguefazeraquiloquenósdefinimosquenãoexiste?

publicclassTestandoADivisao{

publicstaticvoidmain(String[]args){inti=5571;i=i/0;System.out.println("Oresultado"+i);}}

Tenteexecutaroprogramaacima.Oqueacontece?

ReparequeumNullPointerExceptionpoderiaserfacilmenteevitadocomumifquechecariaseareferênciaédiferentedenull.

Outrocasoemquetambémocorretaltipodeexceçãoéquandoumcasterradoéfeito(veremosmaisprafrente).Emtodososcasos,taisproblemasprovavelmentepoderiamserevitadospeloprogramador.Époressemotivoqueojavanãoteobrigaadarotry/catchnessasexceptionsechamamosessasexceçõesdeunchecked.Emoutraspalavras,ocompiladornãochecasevocêestátratandoessasexceções.

ERROS

Oserros em Java sãoum tipode exceçãoque tambémpodemser tratados.Eles representamproblemasnamáquinavirtualenãodevemsertratadosem99%doscasos,jáqueprovavelmenteomelhorasefazerédeixaraJVMencerrar(ouapenasaThreademquestão).

Ficaclaro,comosexemplosdecódigoacima,quenãoénecessáriodeclararquevocêestátentandofazeralgoondeumerropossaocorrer.Osdoisexemplos, comousemotry/catch, compilaramerodaram.Emum,oerroterminouoprogramae,nooutro,foipossíveltratá-lo.

MasnãoésóessetipodeexceçãoqueexisteemJava.Umoutrotipo,obrigaaquemchamaométodoou construtor a tratar essa exceção. Chamamos esse tipo de exceção de checked, pois o compiladorchecaráseelaestásendodevidamentetratada,diferentedasanteriores,conhecidascomounchecked.

12.4OUTROTIPODEEXCEÇÃO:CHECKEDEXCEPTIONS

.

Page 182: FJ-11 Java e Orientação a Objetos

Umexemplointeressanteéodeabrirumarquivoparaleitura,ondepodeocorreroerrodoarquivonãoexistir(veremoscomotrabalharcomarquivosemoutrocapítulo,nãosepreocupecomistoagora):

classTeste{publicstaticvoidmetodo(){newjava.io.FileInputStream("arquivo.txt");}}

O código acima não compila e o compilador avisa que é necessário tratar oFileNotFoundExceptionquepodeocorrer:

Paracompilarefazeroprogramafuncionar,temosduasmaneirasquepodemostrataroproblema.O primeiro, é tratá-lo com otry ecatch domesmo jeito que usamos no exemplo anterior, dereferêncianula:

publicstaticvoidmetodo(){

try{newjava.io.FileInputStream("arquivo.txt");}catch(java.io.FileNotFoundExceptione){System.out.println("Naofoipossívelabriroarquivoparaleitura");}

}

Asegundaformadetrataresseerro,édelegareleparaquemchamouonossométodo,istoé,passarparaafrente.

publicstaticvoidmetodo()throwsjava.io.FileNotFoundException{

newjava.io.FileInputStream("arquivo.txt");

}

NoEclipseébemsimplesfazertantoumtry/catchcomoumthrows:

Tentedigitaressecódigonoeclipse:

publicclassTestaException{publicstaticvoidmain(String[]args){newjava.io.FileInputStream("arquivo.txt");}}

OEclipsevaireclamar:

.

Page 183: FJ-11 Java e Orientação a Objetos

Evocêtemduasopções:

Addthrowsdeclaration,quevaigerar:

publicclassTestaException{publicstaticvoidmain(String[]args)throwsFileNotFoundException{newjava.io.FileInputStream("arquivo.txt");}}

Surroundwithtry/catch,quevaigerar:

publicclassTestaException2{publicstaticvoidmain(String[]args){try{newjava.io.FileInputStream("arquivo.txt");}catch(FileNotFoundExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}}}

No início, existe uma grande tentação de sempre passar o problema pra frente para outros otratarem.Podeserquefaçasentido,dependendodocaso,masnãoatéomain,porexemplo.Aconteceque quem tenta abrir um arquivo sabe como lidar com um problema na leitura.Quem chamou ummétodonocomeçodoprogramapodenãosaberou,piorainda,tentarabrircincoarquivosdiferentesenãosaberqualdelesteveumproblema!

Não há uma regra para decidir em que momento do seu programa você vai tratar determinadaexceção. Isso vai depender de em que ponto você tem condições de tomar uma decisão em relaçãoàqueleerro.Enquantonãoforomomento,vocêprovavelmentevaipreferirdelegararesponsabilidadeparaométodoqueteinvocou.

.

Page 184: FJ-11 Java e Orientação a Objetos

BOASPRÁTICASNOTRATAMENTODEEXCEÇÕES

NoblogdaCaelumháumextensoartigodiscutindoasboaspráticasemrelaçãoaotratamentodeexceções.

http://blog.caelum.com.br/2006/10/07/lidando-com-exceptions/

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

UmapequenapartedaFamíliaThrowable:

SaberinglêsémuitoimportanteemTI

12.5UMPOUCODAGRANDEFAMÍLIATHROWABLE

.

Page 185: FJ-11 Java e Orientação a Objetos

Épossíveltratarmaisdeumerroquasequeaomesmotempo:

Comotryecatch:

try{objeto.metodoQuePodeLancarIOeSQLException();}catch(IOExceptione){//..}catch(SQLExceptione){//..}

Comothrows:

publicvoidabre(Stringarquivo)throwsIOException,SQLException{//..}

Vocêpode,também,escolhertrataralgumasexceçõesedeclararasoutrasnothrows:

publicvoidabre(Stringarquivo)throwsIOException{try{objeto.metodoQuePodeLancarIOeSQLException();}catch(SQLExceptione){//..}}

Édesnecessáriodeclararnothrowsasexceptionsquesãounchecked,porémépermitidoeàsvezes,facilitaaleituraeadocumentaçãodoseucódigo.

12.6MAISDEUMERRO

.

Page 186: FJ-11 Java e Orientação a Objetos

Lembre-sedométodosacadanossaclasseConta.Eledevolveumbooleancasoconsigaounãosacar:

publicbooleansaca(doublevalor){if(this.saldo<valor){returnfalse;}else{this.saldo-=valor;returntrue;}}

Podemos,também,lançarumaException,oqueéextremamenteútil.Dessamaneira,resolvemosoproblemadealguémpoderesquecerdefazerumifnoretornodeummétodo.

Apalavra chave throw, que está no imperativo, lança umaException. Isto é bem diferente dethrows,queestánopresentedoindicativo,equeapenasavisadapossibilidadedaquelemétodolançá-la,obrigandoooutrométodoqueváutilizardestedesepreocuparcomessaexceçãoemquestão.

publicvoidsaca(doublevalor){if(this.saldo<valor){thrownewRuntimeException();}else{this.saldo-=valor;}}

Nonossocaso, lançaumado tipounchecked.RuntimeException é a exceptionmãede todas asexceptionsunchecked.Adesvantagem,aqui,équeelaémuitogenérica;quemreceberesseerronãosabedizerexatamentequalfoioproblema.PodemosentãousarumaExceptionmaisespecífica:

publicvoidsaca(doublevalor){if(this.saldo<valor){thrownewIllegalArgumentException();}else{this.saldo-=valor;}}

IllegalArgumentExceptiondizumpoucomais:algofoipassadocomoargumentoeseumétodonão gostou. Ela é uma Exception unchecked pois estende de RuntimeException e já faz parte dabibliotecadojava.(IllegalArgumentExceptionéamelhorescolhaquandoumargumentosempreéinválidocomo,porexemplo,númerosnegativos,referênciasnulas,etc).

Parapegaresseerro,nãousaremosumif/elseesimumtry/catch,porquefazmaissentidojáqueafaltadesaldoéumaexceção:

Contacc=newContaCorrente();cc.deposita(100);

try{cc.saca(100);

12.7LANÇANDOEXCEÇÕES

.

Page 187: FJ-11 Java e Orientação a Objetos

}catch(IllegalArgumentExceptione){System.out.println("SaldoInsuficiente");}

Podíamos melhorar ainda mais e passar para o construtor da IllegalArgumentException omotivodaexceção:

publicvoidsaca(doublevalor){if(this.saldo<valor){thrownewIllegalArgumentException("Saldoinsuficiente");}else{this.saldo-=valor;}}

Ométodo getMessage() definido na classe Throwable (mãe de todos os tipos de erros eexceptions)vairetornaramensagemquepassamosaoconstrutordaIllegalArgumentException.

try{cc.saca(100);}catch(IllegalArgumentExceptione){System.out.println(e.getMessage());}

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

Imaginequevamossacardinheirodediversascontas:

Contacc=newContaCorrente();cc.deposita(100);

Contacp=newContaPoupanca();cp.deposita(100);

//sacandodascontas:

AprendasedivertindonaAluraStart!

12.8OQUECOLOCARDENTRODOTRY?

.

Page 188: FJ-11 Java e Orientação a Objetos

cc.saca(50);System.out.println("conseguisacardacorrente!");

cp.saca(50);System.out.println("conseguisacardapoupança!");

Podemosescolhervárioslugaresparacolocartry/catch:

try{cc.saca(50);}catch(IllegalArgumentExceptione){System.out.println(e.getMessage());}System.out.println("conseguisacardacorrente!");

try{cp.saca(50);}catch(IllegalArgumentExceptione){System.out.println(e.getMessage());}System.out.println("conseguisacardapoupança!");

Essa não parece uma opção boa, pois a mensagem "consegui sacar" será impressa mesmo que ocatchsejaacionado.Semprequetemosalgoquedependedalinhadecimaparasercorreto,devemosagrupá-lonotry:

try{cc.saca(50);System.out.println("conseguisacardacorrente!");}catch(IllegalArgumentExceptione){System.out.println(e.getMessage());}

try{cp.saca(50);System.out.println("conseguisacardapoupança!");}catch(IllegalArgumentExceptione){System.out.println(e.getMessage());}

Mas há ainda uma outra opção: imagine que, para o nosso sistema, uma falha ao sacar da contapoupançadevepararoprocessodesaquesenemtentarsacardacontacorrente.Paraisso,agruparíamosmaisainda:

try{cc.saca(50);System.out.println("conseguisacardacorrente!");cp.saca(50);System.out.println("conseguisacardapoupança!");}catch(IllegalArgumentExceptione){System.out.println(e.getMessage());}

Oquevocêvaicolocardentrodotry influenciamuitoaexecuçãodoprograma!Pensedireitonaslinhasquedependemumadaoutraparaaexecuçãocorretadasualógicadenegócios.

.

Page 189: FJ-11 Java e Orientação a Objetos

Ébemcomumcriarumaprópriaclassedeexceçãoparacontrolarmelhorousode suasexceções.Dessamaneira,podemospassarvaloresespecíficosparaelacarregar,quesejamúteisdealgumaforma.Vamoscriaranossa:

Voltamos para o exemplo das Contas , vamos criar a nossa Exceção deSaldoInsuficienteException:

publicclassSaldoInsuficienteExceptionextendsRuntimeException{

publicSaldoInsuficienteException(Stringmessage){super(message);}}

Emvezde lançarumIllegalArgumentException, vamos lançar nossa própria exception, comumamensagemquedirá"SaldoInsuficiente":

publicvoidsaca(doublevalor){if(this.saldo<valor){thrownewSaldoInsuficienteException("SaldoInsuficiente,"+"tenteumvalormenor");}else{this.saldo-=valor;}}

E,paratestar,crieumaclassequedepositeumvaloretentesacarumvalormaior:

publicstaticvoidmain(String[]args){Contacc=newContaCorrente();cc.deposita(10);

try{cc.saca(100);}catch(SaldoInsuficienteExceptione){System.out.println(e.getMessage());}}

PodemostransformaressaExceptiondeuncheckedparachecked, obrigandoaquemchamaessemétodoadartry-catch,outhrows:

publicclassSaldoInsuficienteExceptionextendsException{

publicSaldoInsuficienteException(Stringmessage){super(message);}}

Osblocostryecatchpodemconterumaterceiracláusulachamadafinallyqueindicaoquedeveserfeitoapósotérminodoblocotryoudeumcatchqualquer.

12.9CRIANDOSEUPRÓPRIOTIPODEEXCEÇÃO

12.10PARASABERMAIS:FINALLY

.

Page 190: FJ-11 Java e Orientação a Objetos

Éinteressantecolocaralgoqueéimprescindíveldeserexecutado,casooquevocêqueriafazertenhadado certo, ou não.O casomais comum é o de liberar um recurso no finally, como um arquivo ouconexãocombancodedados,paraquepossamosteracertezadequeaquelearquivo(ouconexão)váserfechado,mesmoquealgotenhafalhadonodecorrerdocódigo.

Noexemploaseguir,oblocofinallyserásempreexecutado,independentementedetudoocorrerbemoudeaconteceralgumproblema:

try{//blocotry}catch(IOExceptionex){//blococatch1}catch(SQLExceptionsqlex){//blococatch2}finally{//blocoqueserásempreexecutado,independente//sehouveounãoexceptioneseelafoitratadaounão}

Hátambém,noJava7,umrecursopoderosoconhecidocomotry-with-resources,quepermiteutilizarasemânticadofinallydeumamaneirabemmaissimples.

Conheça a Casa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Com a curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

1. Na classe Conta,modifique ométodo deposita(doublex): Ele deve lançar uma exceptionchamadaIllegalArgumentException,quejáfazpartedabibliotecadoJava,semprequeovalorpassadocomoargumentoforinválido(porexemplo,quandofornegativo).

publicvoiddeposita(doublevalor){if(valor<0){thrownewIllegalArgumentException();}else{this.saldo+=valor;}

Seuslivrosdetecnologiaparecemdoséculopassado?

12.11EXERCÍCIOS:EXCEÇÕES

.

Page 191: FJ-11 Java e Orientação a Objetos

}

2. Rodeaaplicação,cadastreumacontaetentedepositarumvalornegativo.Oqueacontece?

3. Ao lançar a IllegalArgumentException, passe via construtor uma mensagem a ser exibida.LembrequeaString recebidacomoparâmetroéacessíveldepoisviaométodogetMessage()herdadoportodasasExceptions.

publicvoiddeposita(doublevalor){if(valor<0){thrownewIllegalArgumentException("Vocêtentoudepositar"+"umvalornegativo");}else{this.saldo+=valor;}}

Rodeaaplicaçãonovamenteevejaqueagoraamensagemaparecenatela.

4. FaçaomesmoparaométodosacadaclasseContaCorrente,afinaloclientetambémnãopodesacarumvalornegativo!

5. Vamosvalidartambémqueoclientenãopodesacarumvalormaiordoqueosaldodisponívelemconta.CriesuaprópriaException,SaldoInsuficienteException.Paraisso,vocêprecisacriarumaclassecomessenomequesejafilhadeRuntimeException.

publicclassSaldoInsuficienteExceptionextendsRuntimeException{

}

NométodosacadaclasseContaCorrentevamosutilizarestanovaException:

@Overridepublicvoidsaca(doublevalor){if(valor<0){thrownewIllegalArgumentException("Vocêtentousacarumvalornegativo");}if(this.saldo<valor){thrownewSaldoInsuficienteException();}this.saldo-=(valor+0.10);}

Atenção:nemsempreéinteressantecriarmosumnovotipodeexception!Dependedocaso.Nesteaqui,seriamelhoraindautilizarmosIllegalArgumentException.AboapráticadizquedevemospreferirusarasjáexistentesdoJavasemprequepossível.

6. (opcional)ColoqueumconstrutornaclasseSaldoInsuficienteExceptionquerecebaovalorqueeletentousacar(istoé,elevaireceberumdoublevalor).

Quandoestendemosumaclasse,nãoherdamosseusconstrutores,maspodemosacessá-losatravésdapalavrachavesuperdedentrodeumconstrutor.Asexceçõesdo Javapossuemumasériedeconstrutores úteis para poder populá-las já com umamensagem de erro. Então vamos criar um

.

Page 192: FJ-11 Java e Orientação a Objetos

construtoremSaldoInsuficienteExceptionquedelegueparaoconstrutordesuamãe.Essavaiguardaressamensagemparapodermostrá-laaoserinvocadoométodogetMessage:

publicclassSaldoInsuficienteExceptionextendsRuntimeException{

publicSaldoInsuficienteException(doublevalor){super("Saldoinsuficienteparasacarovalorde:"+valor);}}

Dessamaneira, na hora de dar o throw new SaldoInsuficienteException você vai precisarpassaressevalorcomoargumento:

if(this.saldo<valor){thrownewSaldoInsuficienteException(valor);}

Atenção: você pode se aproveitar do Eclipse para isso: comece já passando o valor comoargumentoparaoconstrutordaexceptioneoEclipsevaireclamarquenãoexistetalconstrutor.Oquickfix(ctrl+1)vaisugerirqueelesejaconstruindo,poupando-lhetempo!

Eagora,comoficaométodosacadaclasseContaCorrente?

7. (opcional)DeclareaclasseSaldoInsuficienteException comofilhadiretadeException emvezdeRuntimeException.Elapassaaserchecked.Oqueissoresulta?

Vocêvaiprecisaravisarqueoseumétodosaca()throwsSaldoInsuficienteException,poiselaéumacheckedexception.Alémdisso,quemchamaessemétodovaiprecisartomarumadecisãoentretry-catchouthrows.FaçausodoquickfixdoEclipsenovamente!

Depois, retorne a exception para unchecked, isto é, para ser filha de RuntimeException, poisutilizaremoselaassimemexercíciosdoscapítulosposteriores.

1. Oqueaconteceseacabaramemóriadajavavirtualmachine?

ExisteumapéssimapráticadeprogramaçãoemjavaqueéadeescreverocatcheothrowscomException.

ExistemcódigosquesempreusamExceptionpoisissocuidadetodosospossíveiserros.Omaiorproblemadisso é generalizar o erro. Se alguém joga algodo tipoException paraquemo chamou,quemrecebenãosabequalotipoespecíficodeerroocorreuenãovaisabercomotrataromesmo.

Sim,hácasosondeotratamentodemaisdeumaexceptionpodeserfeitodeumamesmamaneira.

12.12DESAFIOS

12.13DISCUSSÃOEMAULA:CATCHETHROWSEMEXCEPTION

.

Page 193: FJ-11 Java e Orientação a Objetos

Por exemplo, se queremos terminar a aplicação tanto no caso de IOException quanto emSQLException.Sefizermoscatch(Exceptione)parapegaressesdoiscasos,teremosumproblema:aaplicaçãovaipararmesmoqueoutraexceçãosejalançada.Asoluçãocorretaseriaterdoiscatches,masaí teríamoscódigorepetido.Paraevitarocódigorepetido,podemosusaromulti-catchdoJava7,quepermite um mesmo catch cuidar de mais de 1 exceção, através da sintaxe catch(IOException |SQLExceptione){...}.

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design, Infra,Front-Ende

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Agoraéamelhorhoraderespirarmaistecnologia!

.

Page 194: FJ-11 Java e Orientação a Objetos

CAPÍTULO13

"Nossascabeçassãoredondasparaqueospensamentospossammudardedireção."--FrancisPiacaba

Aotérminodessecapítulo,vocêserácapazde:

utilizarasprincipaisclassesdopacotejava.lange leradocumentaçãopadrãodeprojetosjava;usaraclasseSystemparaobterinformaçõesdosistema;utilizaraclasseStringdeumamaneiraeficienteeconhecerseusdetalhes;utilizarosmétodosherdadosdeObjectparageneralizarseuconceitodeobjetos.

Jáusamos,pordiversasvezes,asclassesStringeSystem.VimososistemadepacotesdoJavaenunca precisamos dar um import nessas classes. Isso ocorre porque elas estão dentro do pacotejava.lang,queéautomaticamenteimportadoparavocê.Éoúnicopacotecomestacaracterística.

Vamosverumpoucodesuasprincipaisclasses.

Conheça a Casa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Com a curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

OPACOTEJAVA.LANG

13.1PACOTEJAVA.LANG

Seuslivrosdetecnologiaparecemdoséculopassado?

13.2UMPOUCOSOBREACLASSESYSTEM

.

Page 195: FJ-11 Java e Orientação a Objetos

A classe System possui uma série de atributos e métodos estáticos. Já usamos o atributoSystem.out,paraimprimir.

Olhandoadocumentação,vocêvaiperceberqueoatributooutédotipoPrintStreamdopacotejava.io. Veremos sobre essa classemais adiante. Já podemos perceber que poderíamos quebrar oSystem.out.printlnemduaslinhas:

PrintStreamsaida=System.out;saida.println("olamundo!");

OSystemcontatambémcomummétodoquesimplesmentedesligaavirtualmachine,retornandoumcódigodeerroparaosistemaoperacional,éoexit.

System.exit(0);

VeremostambémumpoucomaissobreaclasseSystemnospróximoscapítulosenoapêndicedeThreads.ConsulteadocumentaçãodoJavaevejaoutrosmétodosúteisdaSystem.

Todométodoqueprecisamosreceberalgumparâmetro temosquedeclararo tipodomesmo.Porexemplo,nonossométodosacaprecisamospassar comoparâmetroumvalordo tipodouble. Setentarmospassarqualquercoisadiferentedissoteremosumerrodecompilação.

AgoravamosobservaroseguintemétododopróprioJava:

System.out.println("Olámundo!");

Nestecaso,ométodoprintlnestárecebendoumaString epoderíamospensarqueo tipodeparâmetroqueelerecebeéString.Masaomesmo tempopodemospassarparaessemétodocoisascompletamentediferentescomoint,Conta,Funcionario,SeguroDeVida,etc.Comoessemétodoconseguerecebertantosparâmetrosdetiposdiferentes?

Umapossibilidade seria o uso da sobrecarga, declarandoumprintln para cada tipo de objetodiferente. Mas claramente não é isso que acontece já que conseguimos criar uma classe qualquer einvocarométodoprintlnpassandoessanovaclassecomoparâmetroeelefuncionaria!

Paraentenderoqueestáacontecendo,vamosconsiderarummétodoquerecebeumaConta:

publicvoidimprimeDados(Contaconta){System.out.println(conta.getTitular()+"-"+conta.getSaldo());}

Essemétodo pode ser invocado passando como parâmetro qualquer tipo de conta que temos nonossosistema:ContaCorrenteeContaPoupancapoisambassãofilhasdeConta. Se quiséssemosqueonossométodoconseguissereceberqualquertipodeobjetoteríamosqueterumaclassequefossemãedetodosessesobjetos.ÉparaissoqueexisteaclasseObject!

13.3JAVA.LANG.OBJECT

.

Page 196: FJ-11 Java e Orientação a Objetos

Semprequandodeclaramosumaclasse,essaclasseéobrigada aherdardeoutra. Istoé,para todaclassequedeclararmos,existeumasuperclasse.Porém,criamosdiversasclassessemherdardeninguém:

classMinhaClasse{

}

Quandoo Javanãoencontraapalavrachaveextends, ele consideraque você estáherdandodaclasseObject,quetambémseencontradentrodopacotejava.lang.Vocêatémesmopodeescreveressaherança,queéomesmo:

publicclassMinhaClasseextendsObject{

}

Todasasclasses,semexceção,herdamdeObject,sejadiretaouindiretamente,poiselaéamãe,vó,bisavó,etcdequalquerclasse.

Podemos tambémafirmarquequalquerobjetoemJavaéumObject, podendo ser referenciadocomo tal. Então, qualquer objeto possui todos osmétodos declarados na classe Object e veremosalgunsdeleslogoapósocasting.

A habilidade de poder se referir a qualquer objeto como Object nos traz muitas vantagens.Podemos criar ummétodo que recebe um Object como argumento, isto é, qualquer objeto! Porexemplo,ométodoprintlnpoderiaserimplementadodaseguintemaneira:

publicvoidprintln(Objectobj){write(obj.toString());//ométodowriteescreveumastringnoconsole}

Dessaforma,qualquerobjetoquepassarmoscomoparâmetropoderáserimpressonoconsoledesdequeelepossuaométodotoString.ParagarantirquetodososobjetosdoJavapossuamessemétodo,elefoiimplementadonaclasseObject.

Por padrão, o método toString do Object retorna o nome da classe @ um número deidentidade:

Conta@34f5d74a

Masesequisermosimprimiralgodiferente?Nanossateladedetalhesdeconta,temosumacaixadeseleçãoondenossascontasestãosendoapresentadascomovalordopadrãodotoString.Semprequequeremos modificar o comportamento de um método em relação a implementação herdada dasuperclasse,podemossobrescrevê-lonaclassefilha:

publicabstractclassConta{

13.4MÉTODOSDOJAVA.LANG.OBJECT:EQUALSETOSTRING

toString

.

Page 197: FJ-11 Java e Orientação a Objetos

protecteddoublesaldo;//outrosatributos...

@OverridepublicStringtoString(){return"[titular="+titular+",numero="+numero+",agencia="+agencia+"]";}}

Agorapodemosusaressemétodoassim:

ContaCorrentecc=newContaCorrente();System.out.println(cc.toString());

E o melhor, se for apenas para jogar na tela, você nem precisa chamar o toString! Ele já échamadoparavocê:

ContaCorrentecc=newContaCorrente();System.out.println(cc);//OtoStringéchamadopelaclassePrintStream

Geraomesmoresultado!

VocêaindapodeconcatenarStringsemJavacomooperador+.SeoJavaencontraumobjetonomeiodaconcatenação,eletambémchamaotoStringdele.

ContaCorrentecc=newContaCorrente();System.out.println("Conta:"+cc);

Atéagoraestamosignorandoofatoquepodemosmaisdeumacontademesmonúmeroeagêncianonossosistema.Atualmente,quandoinserimosumanovaconta,osistemaverificaseacontainseridaéigualaalgumaoutracontajácadastrada.Masqualcritériodeigualdadeéutilizadoporpadrãoparafazeressaverificação?

Assim comono casodotoString, todos objetos do Java possuem um outrométodo chamadoequalsqueéutilizadoparacompararobjetosdaqueletipo.Porpadrão,essemétodoapenascomparaasreferênciasdosobjetos.Comotodavezque inserimosumanovacontanosistemaestamosfazendonewemalgumtipodeconta,asreferênciasnuncavãoseriguais,mesmoosdados(númeroeagência)sendoiguais.

Mas,esefosseprecisocompararosatributos?Quaisatributoseledeveriacomparar?OJavaporsisónão faz isso,maspodemossobrescreveroequals da classeObject para criarmos esse critériodecomparação.

OequalsrecebeumObjectcomoargumentoedeveverificarseelemesmoéigualaoObjectrecebidopararetornarumboolean.Sevocênãoreescreveressemétodo,ocomportamentoherdadoéfazerum==comoobjetorecebidocomoargumento.

publicabstractclassConta{

equals

.

Page 198: FJ-11 Java e Orientação a Objetos

protecteddoublesaldo;//outrosatributos...

publicbooleanequals(Objectobject){//primeiroverificaseooutroobjectnãoénuloif(object==null){returnfalse;}

if(this.numero==object.numero&&this.agencia.equals(object.agencia)){returntrue;}returnfalse;}}

NomomentoquerecebemosumareferênciaparaumObject,comovamosacessarosmétodoseatributosdesseobjetoqueimaginamosserumaConta?Se estamos referenciando-ocomoObject,nãopodemosacessá-locomosendoConta.Ocódigoacimanãocompila!

PoderíamosentãoatribuiressareferênciadeObjectparaContaparadepoisacessarosatributosnecessários?Tentemos:

ContaoutraConta=object;

Nós temoscertezadequeesseObject se refereaumaConta, já que anossa lista só imprimecontas.Masocompilador Javanão temgarantias sobre isso!Essa linhaacimanãocompila,poisnemtodoObjectéumaConta.

Pararealizaressaatribuição,paraissodevemos"avisar"ocompiladorJavaquerealmentequeremosfazer isso, sabendo do risco que corremos. Fazemos o castingde referências, parecido com de tiposprimitivos:

ContaoutraConta=(Conta)object;

Ocódigopassaa compilar,mas seráque roda?Essecódigo roda semnenhumproblema,pois emtempodeexecuçãoaJVMverificaráseessareferênciarealmenteéparaumobjetodetipoConta,eestá!Senãoestivesse,umaexceçãodotipoClassCastExceptionserialançada.

Comisso,nossométodoequalsficariaassim:

publicabstractclassConta{protecteddoublesaldo;//outrosatributos...

publicbooleanequals(Objectobject){if(object==null){returnfalse;}

ContaoutraConta=(Conta)object;

Castingdereferências

.

Page 199: FJ-11 Java e Orientação a Objetos

if(this.numero==outraConta.numero&&this.agencia.equals(outraConta.agencia)){returntrue;}returnfalse;}}

VocêpoderiacriarummétodocomoutronomeemvezdereescreverequalsquerecebeObject,mas ele é importante poismuitas bibliotecas o chamam através do polimorfismo, como veremos nocapítulodojava.util.

O método hashCode() anda de mãos dadas com o método equals() e é de fundamentalentendimento no caso de você utilizar suas classes com estruturas de dados que usam tabelas deespalhamento.Tambémfalaremosdelenocapítulodejava.util.

REGRASPARAAREESCRITADOMÉTODOEQUALS

Pelo contrato definido pela classe Object devemos retornar false também no caso doobjetopassadonãoserdetipocompatívelcomasuaclasse.Entãoantesdefazerocastingdevemosverificar isso,eparatalusamosapalavrachaveinstanceof,ou teríamosumaexceptionsendolançada.

Alémdisso,podemosresumirnossoequalsdetalformaanãousarumif:

publicbooleanequals(Objectobject){if(object==null){returnfalse;}if(!(objectinstanceofConta)){returnfalse;}ContaoutraConta=(Conta)object;return(this.numero==outraConta.numero&&this.agencia.equals(outraConta.agencia));}

.

Page 200: FJ-11 Java e Orientação a Objetos

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design, Infra,Front-Ende

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

1. Como verificar se a classeThrowable que é a superclasse deException também reescreve ométodotoString?

AmaioriadasclassesdoJavaquesãomuitoutilizadas terãoseusmétodosequals etoStringreescritosconvenientemente.

2. Utilize-sedadocumentaçãodoJavaedescubradequeclasseéoobjetoreferenciadopeloatributooutdaSystem.

Repareque,comodevidoimport,poderíamosescrever:

//faltaadeclaraçãodasaída________saida=System.out;saida.println("ola");

Avariávelsaida precisa ser declarada de que tipo? É isso que você precisa descobrir. Se vocêdigitaressecódigonoEclipse,elevaitesugerirumquickfixedeclararáavariávelparavocê.

Estudaremosessaclasseemumcapítulofuturo.

3. Rode a aplicação e cadastreduas contas.Na tela dedetalhesde conta, verifiqueoque aparecenacaixadeseleçãodecontaparatransferência.Porqueissoacontece?

4. Reescreva o método toString da sua classe Conta fazendo com que uma mensagemmaisexplicativa seja devolvida. Lembre-se de aproveitar dos recursos do Eclipse para isto: digitandoapenasocomeçodonomedométodoa ser reescritoepressionandoctrl+espaço, elevai sugerirreescrever ométodo, poupando o trabalho de escrever a assinatura dométodo e cometer algumengano.

publicabstractclassConta{

Agoraéamelhorhoraderespirarmaistecnologia!

13.5EXERCÍCIOS:JAVA.LANG.OBJECT

.

Page 201: FJ-11 Java e Orientação a Objetos

protecteddoublesaldo;

@OverridepublicStringtoString(){return"[titular="+titular+",numero="+numero+",agencia="+agencia+"]";}//restantedaclasse

}

Rode a aplicação novamente, cadastre duas contas e verifique novamente a caixa de seleção datransferência.Oqueaconteceu?

5. Reescreva ométodoequals da classeConta para que duas contas com omesmo número eagênciasejamconsideradasiguais.Esboço:

publicabstractclassConta{

publicbooleanequals(Objectobj){if(obj==null){returnfalse;}

ContaoutraConta=(Conta)obj;

returnthis.numero==outraConta.numero&&this.agencia.equals(outraConta.agencia);}}

Você pode usar o ctrl+ espaço do Eclipse para escrever o esqueleto dométodoequals, bastadigitardentrodaclasseequepressionarctrl+espaço.

Rodeaaplicaçãoetenteadicionarduascontascomomesmonúmeroeagência.Oqueacontece?

StringéumaclasseemJava.VariáveisdotipoStringguardamreferênciasaobjetos,enãoumvalor,comoacontececomostiposprimitivos.

Aliás,podemoscriarumaStringutilizandoonew:

Stringx=newString("fj11");Stringy=newString("fj11");

Criamosaqui,doisobjetosdiferentes.Oqueacontecequandocomparamosessasduas referênciasutilizandoo==?

if(x==y){System.out.println("referênciaparaomesmoobjeto");}else{System.out.println("referênciasparaobjetosdiferentes!");}

13.6JAVA.LANG.STRING

.

Page 202: FJ-11 Java e Orientação a Objetos

Temosaquidoisobjetosdiferentes!E,então,comofaríamosparaverificarseoconteúdodoobjetoéomesmo?Utilizamosométodoequals,quefoireescritopelaString,parafazeracomparaçãodecharemchar.

if(x.equals(y)){System.out.println("consideramosiguaisnocritériodeigualdade");}else{System.out.println("consideramosdiferentesnocritériodeigualdade");}

Aqui,acomparaçãoretornaverdadeiro.Porquê?PoisquemimplementouaclasseStringdecidiuqueesteseriaomelhorcritériodecomparação.Vocêpodedescobriroscritériosdeigualdadedecadaclassepeladocumentação.

PodemostambémconcatenarStringsusandoo+.PodemosconcatenarStringscomqualquerobjeto,atémesmonúmeros:

inttotal=5;System.out.println("ototalgastoé:"+total);

O compilador utilizará os métodos apropriados da classe String e possivelmente métodos deoutrasclassespararealizartaltarefa.

SequisermoscompararduasStrings,utilizamosométodocompareTo,que recebeumaStringcomoargumento edevolveum inteiro indicando se aString vemantes, é igual ou vemdepois daStringrecebida.Seforemiguais,édevolvido0;seforanterioràStringdoargumento,devolveuminteironegativo;e,seforposterior,uminteiropositivo.

Fatoimportante:umaStringéimutável.OjavacriaumpooldeStringsparausarcomocachee,seaStringnãofosseimutável,mudandoovalordeumaStringafetariatodasasStrings deoutrasclassesquetivessemomesmovalor.

Reparenocódigoabaixo:

Stringpalavra="fj11";palavra.toUpperCase();System.out.println(palavra);

Pode parecer estranho,mas ele imprime "fj11" emminúsculo. Todométodo que parece alterar ovalordeumaString,naverdade,criaumanovaStringcomasmudançassolicitadasearetorna!Tantoqueessemétodonãoévoid.Ocódigorealmenteútilficariaassim:

Stringpalavra="fj11";Stringoutra=palavra.toUpperCase();System.out.println(outra);

Ouvocêpodeeliminaracriaçãodeoutravariáveltemporária,seacharconveniente:

Stringpalavra="fj11";palavra=palavra.toUpperCase();

.

Page 203: FJ-11 Java e Orientação a Objetos

System.out.println(palavra);

Isso funciona da mesma forma para todos os métodos que parecem alterar o conteúdo de umaString.

Sevocêaindaquisertrocaronúmero1para2,faríamos:

Stringpalavra="fj11";palavra=palavra.toUpperCase();palavra=palavra.replace("1","2");System.out.println(palavra);

Ouaindapodemosconcatenaras invocaçõesdemétodo, jáqueumaString é devolvida a cadainvocação:

Stringpalavra="fj11";palavra=palavra.toUpperCase().replace("1","2");System.out.println(palavra);

O funcionamento do pool interno de Strings do Java tem uma série de detalhes e você podeencontrar mais informações sobre isto na documentação da classe String e no seu métodointern().

OUTROSMÉTODOSDACLASSESTRING

Existem diversos métodos da classe String que são extremamente importantes.Recomendamossempreconsultarojavadocrelativoaessaclasseparaaprendercadavezmaissobreamesma.

Porexemplo,ométodocharAt(i),retornaocaractereexistentenaposiçãoidaString,ométodolengthretornaonúmerodecaracteresnamesmaeométodosubstringquerecebeumintedevolveaSubStringapartirdaposiçãopassadaporaqueleint.

OindexOfrecebeumcharouumaStringedevolveoíndiceemqueaparecepelaprimeiraveznaStringprincipal(hátambémolastIndexOfquedevolveoíndicedaúltimaocorrência).

OtoUpperCaseeotoLowerCasedevolvemumanovaStringtodaemmaiúsculaetodaemminúscula,respectivamente.

ApartirdoJava6,temosaindaométodoisEmpty,quedevolvetrueseaStringforvaziaoufalsecasocontrário.

Algunsmétodosúteisparabuscassãoocontainseomatches.

Hámuitosoutrosmétodos,recomendamosquevocêsempreconsulteojavadocdaclasse.

.

Page 204: FJ-11 Java e Orientação a Objetos

JAVA.LANGSTRINGBUFFERESTRINGBUILDER

ComoaclasseStringéimutável,trabalharcomumamesmaStringdiversasvezespodeterum efeito colateral: gerar inúmeras Strings temporárias. Isto prejudica a performance daaplicaçãoconsideravelmente.

NocasodevocêtrabalharmuitocomamanipulaçãodeumamesmaString (por exemplo,dentrodeumlaço),oidealéutilizaraclasseStringBuffer.AclasseStringBufferrepresentaumasequênciadecaracteres.DiferentementedaString,elaémutável,enãopossuiaquelepool.

AclasseStringBuilder temexatamenteosmesmosmétodos,comadiferençadelanãoserthread-safe.VeremossobreesteconceitonocapítulodeThreads.String.

1. Queremosqueascontasapresentadasnacaixadeseleçãodatransferênciaapareçamcomonomedotitularemmaiúsculas.ParafazerissovamosalterarométodotoStringdaclasseConta.UtilizeométodotoUpperCasedaStringparaisso.

2. ApósalterarmosométodotoString, aconteceu algumamudança comonomedo titular que éapresentadonalistadecontas?Porque?

3. Testeosexemplosdessecapítulo,paraverqueumaStringéimutável.Porexemplo:

publicclassTestaString{

publicstaticvoidmain(String[]args){Strings="fj11";s.replaceAll("1","2");System.out.println(s);}

}

Comofazerparaeleimprimirfj22?

4. Como fazerpara saber seumaString se encontradentrodeoutra?Epara tirar os espaços embrancodaspontasdeumaString?EparasaberseumaStringestávazia?EparasaberquantoscaracterestemumaString?

TomecomohábitosemprepesquisaroJavaDoc!ConheceraAPI,aospoucos,é fundamentalparaquevocênãoprecisereescreveraroda!

5. (opcional) Escreva ummétodo que usa osmétodoscharAt elength de umaString paraimprimiramesmacaractereacaractere,comcadacaractereemumalinhadiferente.

13.7EXERCÍCIOS:JAVA.LANG.STRING

.

Page 205: FJ-11 Java e Orientação a Objetos

6. (opcional) Reescreva o método do exercício anterior, mas modificando ele para que imprima aString de trás para a frente e emuma linha só.Teste-apara "Socorram-me, subi no ônibus emMarrocos"e"anotaramadatadamaratona".

7. (opcional)PesquiseaclasseStringBuilder(ouStringBuffernoJava1.4).Elaémutável.Porqueusá-laemvezdaString?Quandousá-la?

Comovocêpoderia reescrever ométodode escrever aString de trás para a frenteusandoumStringBuilder?

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelum eobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

1. ConvertaumaStringparaumnúmerosemusarasbibliotecasdojavaquejáfazemisso. Issoé,umaStringx="762"devegeraruminti=762.

Paraajudar,saibaqueumcharpodeser"transformado"emintcomomesmovalornuméricofazendo:

charc='3';inti=c-'0';//ivale3!

Aquiestamosnosaproveitandodoconhecimentodatabelaunicode:osnúmerosde0a9estãoemsequência! Você poderia usar o método estático Character.getNumericValue(char) em vezdisso.

QualéasuanecessidadecomoJava?Precisafazeralgoritmosderedesneurais?Gerargráficos3D?Relatórios emPDF?Gerar código de barra?Gerar boletos?ValidarCPF?Mexer comum arquivo do

EditoraCasadoCódigocomlivrosdeumaformadiferente

13.8DESAFIO

13.9DISCUSSÃOEMAULA:OQUEVOCÊPRECISAFAZEREMJAVA?

.

Page 206: FJ-11 Java e Orientação a Objetos

Excel?

O instrutor vai mostrar que para a maioria absoluta das suas necessidades, alguém já fez umabibliotecaeadisponibilizou.

.

Page 207: FJ-11 Java e Orientação a Objetos

CAPÍTULO14

"Ohomemesqueceráantesamortedopaiqueaperdadapropriedade"--Maquiavel

Aotérminodessecapítulo,vocêserácapazde:

declarareinstanciararrays;popularepercorrerarrays.

Dentrodeumbloco,podemosdeclarardiversasvariáveiseusá-las:

doublesaldoDaConta1=conta1.getSaldo();doublesaldoDaConta2=conta2.getSaldo();doublesaldoDaConta3=conta3.getSaldo();doublesaldoDaConta4=conta4.getSaldo();

Isso pode se tornar um problema quando precisamos mudar a quantidade de variáveis a seremdeclaradasdeacordocomumparâmetro.Esseparâmetropodevariar,comoporexemplo,aquantidadedenúmerocontidosnumbilhetedeloteria.Umjogosimplespossui6números,maspodemoscomprarumbilhetemaiscaro,com7númerosoumais.

Parafacilitaressetipodecasopodemosdeclararumvetor(array)dedoubles:

double[]saldosDasContas;

Odouble[]éumtipo.Umaarrayésempreumobjeto,portanto,avariávelsaldosDasContaséumareferência.Vamosprecisarcriarumobjetoparapoderusaraarray.Comocriamosoobjeto-array?

saldosDasContas=newdouble[10];

Oque fizemos foi criaruma arraydedoublede 10posições e atribuir o endereçonoqual ela foicriada.Podemosaindaacessarasposiçõesdoarray:

saldosDasContas[5]=conta5.getSaldo();

Ocódigoacimaalteraasextaposiçãodoarray.NoJava,osíndicesdoarrayvãode0an-1,ondenéotamanhodadonomomentoemquevocêcriouoarray.Sevocêtentaracessarumaposiçãoforadessealcance,umerroocorreráduranteaexecução.

UMPOUCODEARRAYS

14.1OPROBLEMA

.

Page 208: FJ-11 Java e Orientação a Objetos

ARRAYS-UMPROBLEMANOAPRENDIZADODEMUITASLINGUAGENS

Aprender a usar arrays pode ser um problema em qualquer linguagem. Isso porque envolveumasériedeconceitos,sintaxeeoutros.NoJava,muitasvezesutilizamosoutrosrecursosemvezdearrays, em especial os pacotes de coleções do Java, que veremos no capítulo 15. Portanto, fiquetranquilocasonãoconsigadigerirtodasintaxedasarraysnumprimeiromomento.

No caso do bilhete de loteria, podemos utilizar o mesmo recurso. Mais ainda, a quantidade denúmeros do nosso bilhete pode ser definido por uma variável. Considere que n indica quantosnúmerosnossobilheteterá,podemosentãofazer:

int[]numerosDoBilhete=newint[n];

Eassimpodemosacessaremodificarosinteiroscomíndicede0an-1.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

É comum ouvirmos "array de objetos". Porém quando criamos uma array de alguma classe, elapossui referências. O objeto, como sempre, está na memória principal e, na sua array, só ficamguardadasasreferências(endereços).

ContaCorrente[]minhasContas;minhasContas=newContaCorrente[10];

JáconheceoscursosonlineAlura?

14.2ARRAYSDEREFERÊNCIAS

.

Page 209: FJ-11 Java e Orientação a Objetos

Quantascontasforamcriadasaqui?Naverdade,nenhuma.Foramcriados10espaçosquevocêpodeutilizarparaguardarumareferênciaaumaContaCorrente.Porenquanto,elessereferenciamparalugarnenhum(null).Sevocêtentar:

System.out.println(minhasContas[0].getSaldo());

Umerrodurante a execuçãoocorrerá! Pois, na primeira posiçãoda array, nãoháuma referênciaparaumaconta,nemparalugarnenhum.Vocêdevepopularsuaarrayantes.

ContaCorrentecontaNova=newContaCorrente();contaNova.deposita(1000.0);minhasContas[0]=contaNova;

Ouvocêpodefazerissodiretamente:

minhasContas[1]=newContaCorrente();minhasContas[1].deposita(3200.0);

Umaarraydetiposprimitivosguardavalores,umarraydeobjetosguardareferências.

Mas e se agoraquisermos guardar tantoContaCorrente quantoContaPoupança?Um array deContaCorrente só consegue guardar objetos domesmo tipo. Se quisermos guardar os dois tipos deconta,devemoscriarumarraydeConta!

Conta[]minhasContas=newConta[10];minhasContas[0]=newContaCorrente();minhasContas[1]=newContaPoupanca();

Percebaquenão estamos criandoumobjetodo tipoConta, que é abstrata, estamos criando 10espaçosqueguardamreferênciasparaqualquertipodeconta.

14.3PERCORRENDOUMAARRAY

.

Page 210: FJ-11 Java e Orientação a Objetos

Percorrerumarrayémuitosimplesquandofomosnósqueacriamos:

publicstaticvoidmain(String[]args){int[]idades=newint[10];for(inti=0;i<10;i++){idades[i]=i*10;}for(inti=0;i<10;i++){System.out.println(idades[i]);}}

Porém,emmuitoscasos,recebemosumaarraycomoargumentoemummétodo:

publicvoidimprimeArray(int[]array){//nãocompila!!for(inti=0;i<????;i++){System.out.println(array[i]);}}

Atéondeofordeveir?TodaarrayemJavatemumatributoquesechamalength,evocêpodeacessá-loparasaberotamanhodoarrayaoqualvocêestásereferenciandonaquelemomento:

publicvoidimprimeArray(int[]array){for(inti=0;i<array.length;i++){System.out.println(array[i]);}}

ARRAYSNÃOPODEMMUDARDETAMANHO

Apartirdomomentoqueumaarrayfoicriada,elanãopodemudardetamanho.

Sevocêprecisardemaisespaço,seránecessáriocriarumanovaarraye,antesdesereferirela,copieoselementosdaarrayvelha.

OJava5.0trazumanovasintaxeparapercorremosarrays(ecoleções,queveremosmaisafrente).

Nocasodevocênãoternecessidadedemanterumavariávelcomoíndicequeindicaaposiçãodoelementonovetor(queéumagrandepartedoscasos),podemosusaroenhanced-for.

publicclassAlgumaClasse{publicstaticvoidmain(String[]args){int[]idades=newint[10];for(inti=0;i<10;i++){idades[i]=i*10;}

//imprimindotodaaarray

14.4PERCORRENDOUMAARRAYNOJAVA5.0

.

Page 211: FJ-11 Java e Orientação a Objetos

for(intx:idades){System.out.println(x);}}}

Nãoprecisamosmaisdolengthparapercorrermatrizescujotamanhonãoconhecemos:

publicclassAlgumaClasse{publicvoidimprimeArray(int[]array){for(intx:array){System.out.println(x);}}}

Omesmoéválidoparaarraysdereferências.Essefornadamaiséqueumtruquedecompilaçãoparafacilitaressatarefadepercorrerarraysetorná-lamaislegível.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

Paraconsolidarmososconceitossobrearrays,vamosfazeralgunsexercíciosquenãointerferememnossoprojeto.

1. CrieumaclasseTestaArrays enométodomain crie umarrayde contasde tamanho10.Emseguida,façaumlaçoparacriar10contascomsaldosdistintosecolocá-lasnoarray.Porexemplo,vocêpodeutilizaroíndicedolaçoemultiplicá-lopor100paragerarosaldodecadaconta:

Conta[]contas=newConta[10];

for(inti=0;i<contas.length;i++){Contaconta=newContaCorrente();

SaberinglêsémuitoimportanteemTI

14.5EXERCÍCIOS:ARRAYS

.

Page 212: FJ-11 Java e Orientação a Objetos

conta.deposita(i*100.0);//escrevaocódigoparaguardaracontanaposiçãoidoarray}

2. AindanaclasseTestaArrays,façaumoutrolaçoparacalculareimprimiramédiadossaldosdetodasascontasdoarray.

3. (opcional) Crie uma classe TestaSplit que reescreva uma frase com as palavras na ordeminvertida."Socorram-me, subinoônibus emMarrocos"deveretornar "Marrocos emônibusno subiSocorram-me,".Utilize ométodosplit da String para te auxiliar. Essemétodo divide umaStringdeacordocomoseparadorespecificadoedevolveaspartesemumarraydeString,porexemplo:

Stringfrase="Umamensagemqualquer";String[]palavras=frase.split("");

//Agorasóbastapercorreroarraynaordeminversaimprimindoaspalavras

4. (opcional)CrieumaclasseBancodentrodopacotebr.com.caelum.contas.modeloOBancodeve terumnomeeumnúmero (obrigatoriamente) euma referência aumaarraydeConta detamanho10,alémdeoutrosatributosquevocêjulgarnecessário.

publicclassBanco{privateStringnome;privateintnumero;privateConta[]contas;

//outrosatributosquevocêacharnecessário

publicBanco(Stringnome,intnumero){this.nome=nome;this.numero=numero;this.contas=newContaCorrente[10];}

//gettersparanomeenúmero,nãocolocarossetterspoisjárecebemosno//construtor}

5. (opcional)AclasseBancodeveterummétodoadiciona,querecebeumareferênciaaContacomoargumentoeguardaessaconta.

VocêdeveinseriraContaemumaposiçãodaarrayqueestejalivre.Existemváriasmaneirasparavocêfazerisso:guardarumcontadorparaindicarqualapróximaposiçãovaziaouprocurarporumaposiçãovaziatodavez.Oqueseriamaisinteressante?

Sequiserverificarqualaprimeiraposiçãovazia(nula)eadicionarnela,poderiaserfeitoalgocomo:

publicvoidadiciona(Contac){for(inti=0;i<this.contas.length;i++){//verificarseaposiçãoestávazia//adicionarnoarray}}

.

Page 213: FJ-11 Java e Orientação a Objetos

Éimportanterepararqueométodoadicionanãorecebetitular,agencia,saldo,etc.Essaseriaumamaneiranemumpoucoestruturada,muitomenosorientadaaobjetosde se trabalhar.VocêantescriaumaContaejápassaareferênciadela,quedentrodoobjetopossuititular,saldo,etc.

6. (opcional)CrieumaclasseTestaBancoquepossuiráummétodomain.DentrodelecriealgumasinstânciasdeContaepasseparaobancopelométodoadiciona.

Bancobanco=newBanco("CaelumBank",999);//....

Criealgumascontasepassecomoargumentoparaoadicionadobanco:

ContaCorrentec1=newContaCorrente();c1.setTitular("Batman");c1.setNumero(1);c1.setAgencia(1000);c1.deposita(100000);banco.adiciona(c1);

ContaPoupancac2=newContaPoupanca();c2.setTitular("Coringa");c2.setNumero(2);c2.setAgencia(1000);c2.deposita(890000);banco.adiciona(c2);

Você pode criar essas contas dentro de um loop e dar a cada um deles valores diferentes dedepósitos:

for(inti=0;i<5;i++){ContaCorrenteconta=newContaCorrente();conta.setTitular("Titular"+i);conta.setNumero(i);conta.setAgencia(1000);conta.deposita(i*1000);banco.adiciona(conta);}

Repare que temos de instanciar ContaCorrente dentro do laço. Se a instanciação deContaCorrente ficasse acimado laço, estaríamos adicionado cinco vezes amesma instância deContaCorrentenesteBancoeapenasmudandoseudepósitoacadaiteração,quenessecasonãoéoefeitodesejado.

Opcional:ométodoadicionapodegerarumamensagemdeerroindicandoquandooarrayjáestácheio.

7. (opcional)PercorraoatributocontasdasuainstânciadeBancoeimprimaosdadosdetodasassuascontas.Parafazerisso,vocêpodecriarummétodochamadomostraContasdentrodaclasseBanco:

publicvoidmostraContas(){for(inti=0;i<this.contas.length;i++){System.out.println("Contanaposição"+i);//preencherparamostraroutrasinformacoesdaconta

.

Page 214: FJ-11 Java e Orientação a Objetos

}}

Cuidadoaopreencheressemétodo:alguns índicesdoseuarraypodemnãoconterreferênciaparaumaContaconstruída,istoé,aindasereferiremparanull.Sepreferir,useofornovodojava5.0.

Aí,atravésdoseumain,depoisdeadicionaralgumascontas,bastafazer:

banco.mostraContas();

8. (opcional) Em vez de mostrar apenas o salário de cada funcionário, você pode usar o métodotoString()decadaContadoseuarray.

9. (opcional)Crieummétodoparaverificar seumadeterminadaConta se encontraounão comocontadestebanco:

publicbooleancontem(Contaconta){//...}

Vocêvaiprecisar fazerumfor em seu array e verificar se a contapassada comoargumento seencontradentrodoarray.Eviteaomáximousarnúmeroshard-coded,istoé,useo.length.

10. (opcional)Casoo array já esteja cheionomomentode adicionarumaoutra conta, crieumarraynovocomumacapacidademaiorecopieosvaloresdoarrayatual.Istoé,vamosfazerarealocaçãodoselementosdoarrayjáquejavanãotemisso:umarraynasceemorrecomomesmolength.

USANDOOTHISPARAPASSARARGUMENTO

Dentrodeummétodo,vocêpodeusarapalavrathisparareferenciarasimesmoepodepassaressareferênciacomoargumento.

Arrayspodemtermaisdeumadimensão. Istoé,emvezde termosumaarrayde10contas,podemosterumaarrayde10por10contasevocêpodeacessaracontanaposiçãodacolunaxelinhay.Naverdade,umaarraybidimensionalemJavaéumaarraydearrays.Pesquisesobreisso.

14.6UMPOUCOMAIS...

.

Page 215: FJ-11 Java e Orientação a Objetos

Umaarraybidimensionalnãoprecisa ser retangular, istoé, cada linhapode terumnúmerodiferentedecolunas.Como?Porque?

Oqueacontecesecriarmosumaarrayde0elementos?e-1?

Ométodomain recebeumaarraydeStrings comoargumento.Essa array é passadapelousuárioquandoeleinvocaoprograma:

$javaTesteargumento1outromaisoutro

Enossaclasse:

publicclassTeste{publicstaticvoidmain(String[]args){for(Stringargumento:args){

.

Page 216: FJ-11 Java e Orientação a Objetos

System.out.println(argumento);}}}

Issoimprimirá:

argumento1outromaisoutro

1. Nosprimeiroscapítulos,vocêdeveterreparadoqueaversãorecursivaparaoproblemadeFibonacciélentaporquetodahoraestamosrecalculandovalores.Façacomqueaversãorecursivasejatãoboaquantoaversãoiterativa.(Dica:usearraysparaisso)

2. Oobjetivodesteexercícioéfixarosconceitosvistos.Sevocêestácomdificuldadeemalgumapartedessecapítulo,aproveiteetreinetudooquevimosatéagoranopequenoprogramaabaixo:

Programa:

Classe: Casa Atributos: cor, totalDePortas, portas[] Métodos: void pinta(String s), intquantasPortasEstaoAbertas(),voidadicionaPorta(Portap),inttotalDePortas()

Crieumacasa,pinte-a.Crietrêsportasecoloque-asnacasaatravésdométodoadicionaPorta,abraefeche-ascomodesejar.UtilizeométodoquantasPortasEstaoAbertaspara imprimironúmerodeportasabertaseométodototalDePortaspara imprimiro totaldeportasemsuacasa.

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

14.7DESAFIOSOPCIONAIS

AprendasedivertindonaAluraStart!

.

Page 217: FJ-11 Java e Orientação a Objetos

CAPÍTULO15

"Aamizadeéumcontratosegundooqualnoscomprometemosaprestarpequenosfavoresparaqueno-losretribuamcomgrandes."--BarondelaBredeetdeMontesquieu

Aotérminodessecapítulo,vocêserácapazde:

utilizararrays,lists,setsoumapsdependendodanecessidadedoprograma;iterareordenarlistasecoleções;usarmapasparainserçãoebuscadeobjetos.

Comovimosnocapítulodearrays,manipulá-lasébastantetrabalhoso.Essadificuldadeapareceemdiversosmomentos:

nãopodemosredimensionarumarrayemJava;éimpossívelbuscardiretamenteporumdeterminadoelementocujoíndicenãosesabe;não conseguimos saber quantas posições do array já foram populadas sem criar, para isso,métodosauxiliares.

Na figura acima, você pode ver um array que antes estava sendo completamente utilizado e que,depois,teveumdeseuselementosremovidos.

Supondoqueosdadosarmazenadosrepresentemcontas,oqueacontecequandoprecisarmosinseriruma nova conta no banco? Precisaremos procurar por um espaço vazio? Guardaremos em algumaestruturadedadosexterna,asposiçõesvazias?Esenãohouverespaçovazio?Teríamosdecriarumarraymaiorecopiarosdadosdoantigoparaele?

Hámais questões: comoposso saber quantas posições estão sendousadasno array?Vouprecisarsemprepercorreroarrayinteiroparaconseguiressainformação?

COLLECTIONSFRAMEWORK

15.1ARRAYSSÃOTRABALHOSOS,UTILIZARESTRUTURADEDADOS

.

Page 218: FJ-11 Java e Orientação a Objetos

Alémdessasdificuldadesqueosarraysapresentavam, faltavaumconjuntorobustodeclassesparasupriranecessidadedeestruturasdedadosbásicas,comolistasligadasetabelasdeespalhamento.

Comesseseoutrosobjetivosemmente,ocomitêresponsávelpeloJavacriouumconjuntodeclasseseinterfacesconhecidocomoCollectionsFramework,queresidenopacotejava.utildesdeoJava21.2.

COLLECTIONS

AAPIdeCollectionsérobustaepossuidiversasclassesquerepresentamestruturasdedadosavançadas.

Porexemplo,nãoénecessárioreinventararodaecriarumalistaligada,massimutilizaraquelaqueoJavadisponibiliza.

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

Um primeiro recurso que a API de Collections traz são listas. Uma lista é uma coleção quepermiteelementosduplicadosemantémumaordenaçãoespecíficaentreoselementos.

Em outras palavras, você tem a garantia de que, quando percorrer a lista, os elementos serãoencontrados em uma ordem pré-determinada, definida na hora da inserção dosmesmos. Ela resolvetodososproblemasque levantamosemrelaçãoaoarray (busca, remoção, tamanho "infinito",...).Esse

SaberinglêsémuitoimportanteemTI

15.2LISTAS:JAVA.UTIL.LIST

.

Page 219: FJ-11 Java e Orientação a Objetos

códigojáestápronto!

AAPIdeCollectionstrazainterfacejava.util.List,queespecificaoqueumaclassedevesercapazde fazerparaseruma lista.Hádiversas implementaçõesdisponíveis,cadaumacomumaformadiferentederepresentarumalista.

A implementaçãomaisutilizadada interfaceList éaArrayList, que trabalha comumarrayinterno para gerar uma lista. Portanto, ela é mais rápida na pesquisa do que sua concorrente, aLinkedList,queémaisrápidanainserçãoeremoçãodeitensnaspontas.

ARRAYLISTNÃOÉUMARRAY!

É comumconfundiremumaArrayList comum array, porém ela não é um array.O queocorreéque,internamente,elausaumarraycomoestruturaparaarmazenarosdados,porémesteatributoestápropriamenteencapsuladoevocênãotemcomoacessá-lo.Repare,também,quevocênãopodeusar[]comumaArrayList,nemacessaratributolength.Nãohárelação!

ParacriarumArrayList,bastachamaroconstrutor:

ArrayListlista=newArrayList();

ÉsemprepossívelabstrairalistaapartirdainterfaceList:

Listlista=newArrayList();

Paracriarumalistadenomes(String),podemosfazer:

Listlista=newArrayList();lista.add("Manoel");lista.add("Joaquim");lista.add("Maria");

AinterfaceListpossuidoismétodosadd,umquerecebeoobjetoaserinseridoeocolocanofinaldalista,eumsegundoquepermiteadicionaroelementoemqualquerposiçãodamesma.Noteque,em momento algum, dizemos qual é o tamanho da lista; podemos acrescentar quantos elementosquisermos,quealistacresceconformefornecessário.

Todalista(naverdade,todaCollection)trabalhadomodomaisgenéricopossível.Istoé,nãoháuma ArrayList específica para Strings, outra para Números, outra para Datas etc. Todos osmétodostrabalhamcomObject.

Assim,épossívelcriar,porexemplo,umalistadeContasCorrentes:

ContaCorrentec1=newContaCorrente();c1.deposita(100);

ContaCorrentec2=newContaCorrente();

.

Page 220: FJ-11 Java e Orientação a Objetos

c2.deposita(200);

ContaCorrentec3=newContaCorrente();c3.deposita(300);

Listcontas=newArrayList();contas.add(c1);contas.add(c3);contas.add(c2);

Parasaberquantoselementoshánalista,usamosométodosize():

System.out.println(contas.size());

Háaindaummétodoget(int) que recebe comoargumentoo índicedo elementoque se querrecuperar.Atravésdele,podemosfazerumforparaiterarnalistadecontas:

for(inti=0;i<contas.size();i++){contas.get(i);//códigonãomuitoútil....}

Mascomofazerparaimprimirosaldodessascontas?PodemosacessarogetSaldo()diretamenteapósfazercontas.get(i)?Nãopodemos; lembre-se que toda lista trabalha sempre comObject.Assim, a referência devolvida pelo get(i) é do tipo Object , sendo necessário o cast paraContaCorrentesequisermosacessarogetSaldo():

for(inti=0;i<contas.size();i++){ContaCorrentecc=(ContaCorrente)contas.get(i);System.out.println(cc.getSaldo());}//notequeaordemdoselementosnãoéalterada

Háaindaoutrosmétodos,comoremove()querecebeumobjetoquesedesejaremoverdalista;econtains(), que recebe umobjeto como argumento e devolvetrue oufalse, indicando se oelementoestáounãonalista.

AinterfaceListealgumasclassesqueaimplementampodemservistasnodiagramaaseguir:

.

Page 221: FJ-11 Java e Orientação a Objetos

ACESSOALEATÓRIOEPERCORRENDOLISTASCOMGET

Algumaslistas,comoaArrayList,têmacessoaleatórioaosseuselementos:abuscaporumelemento em uma determinada posição é feita demaneira imediata, sem que a lista inteira sejapercorrida(quechamamosdeacessosequencial).

Nestecaso,oacessoatravésdométodoget(int)émuitorápido.Casocontrário,percorrerumalistausandoumforcomoessequeacabamosdever,podeserdesastroso.Aopercorrermosumalista,devemosusarsempreumIteratorouenhancedfor,comoveremos.

Umalistaéumaexcelentealternativaaumarraycomum,jáquetemostodososbenefíciosdearrays,semanecessidadedetomarcuidadocomremoções,faltadeespaçoetc.

A outra implementação muito usada, a LinkedList, fornece métodos adicionais para obter eremoveroprimeiroeúltimoelementodalista.Elatambémtemofuncionamentointernodiferente,oquepodeimpactarperformance,comoveremosduranteosexercíciosnofinaldocapítulo.

.

Page 222: FJ-11 Java e Orientação a Objetos

VECTOR

Outra implementação é a tradicional classe Vector , presente desde o Java 1.0, que foiadaptadaparausocomoframeworkdeCollections,comainclusãodenovosmétodos.

Ela deve ser escolhida com cuidado, pois lida de uma maneira diferente com processoscorrendo em paralelo e terá um custo adicional em relação a ArrayList quando não houveracessosimultâneoaosdados.

Emqualquerlista,épossívelcolocarqualquerObject.Comisso,épossívelmisturarobjetos:

ContaCorrentecc=newContaCorrente();

Listlista=newArrayList();lista.add("Umastring");lista.add(cc);...

Mas e depois, na hora de recuperar esses objetos?Como ométodoget devolve umObject,precisamosfazerocast.Mascomumalistacomváriosobjetosdetiposdiferentes,issopodenãosertãosimples...

Geralmente, não nos interessa uma lista com vários tipos de objetos misturados; no dia-a-dia,usamoslistascomoaqueladecontascorrentes.NoJava5.0,podemosusarorecursodeGenericspararestringiraslistasaumdeterminadotipodeobjetos(enãoqualquerObject):

List<ContaCorrente>contas=newArrayList<ContaCorrente>();contas.add(c1);contas.add(c3);contas.add(c2);

ReparenousodeumparâmetroaoladodeListeArrayList:eleindicaquenossalistafoicriadaparatrabalharexclusivamentecomobjetosdotipoContaCorrente. Issonostrazumasegurançaemtempodecompilação:

contas.add("umastring");//issonãocompilamais!!

OusodeGenericstambémeliminaanecessidadedecasting,jáque,seguramente,todososobjetosinseridosnalistaserãodotipoContaCorrente:

for(inti=0;i<contas.size();i++){ContaCorrentecc=contas.get(i);//semcasting!System.out.println(cc.getSaldo());}

A partir do Java 7, se você instancia um tipo genérico namesma linha de sua declaração, não é

15.3LISTASNOJAVA5EJAVA7COMGENERICS

.

Page 223: FJ-11 Java e Orientação a Objetos

necessáriopassar os tiposnovamente, bastausarnewArrayList<>(). É conhecido comooperadordiamante:

List<ContaCorrente>contas=newArrayList<>();

ValeressaltaraimportânciadousodainterfaceList:quandodesenvolvemos,procuramossemprenosreferiraela,enãoàsimplementaçõesespecíficas.Porexemplo,setemosummétodoquevaibuscarumasériedecontasnobancodedados,poderíamosfazerassim:

classAgencia{publicArrayList<Conta>buscaTodasContas(){ArrayList<Conta>contas=newArrayList<>();

//paracadacontadobancodedados,contas.add

returncontas;}}

Porém,paraqueprecisamosretornarareferênciaespecíficaaumaArrayList?Paraque ser tãoespecífico?Dessamaneira,odiaqueoptarmospordevolverumaLinkedListemvezdeArrayList,as pessoas que estão usando o método buscaTodasContas poderão ter problemas, pois estavamfazendo referência a uma ArrayList. O ideal é sempre trabalhar com a interface mais genéricapossível:

classAgencia{

//modificaçãoapenasnoretorno:publicList<Conta>buscaTodasContas(){ArrayList<Conta>contas=newArrayList<>();

//paracadacontadobancodedados,contas.add

returncontas;}}

ÉomesmocasodepreferirreferenciaraosobjetoscomInputStream como fizemosnocapítulopassado.

Assim como no retorno, é boa prática trabalhar com a interface em todos os lugares possíveis:métodos que precisam receber uma lista de objetos têm List como parâmetro em vez de umaimplementaçãoemespecíficocomoArrayList,deixandoométodomaisflexível:

classAgencia{

publicvoidatualizaContas(List<Conta>contas){//...}}

15.4AIMPORTÂNCIADASINTERFACESNASCOLEÇÕES

.

Page 224: FJ-11 Java e Orientação a Objetos

Também declaramos atributos como List em vez de nos comprometer como uma ou outraimplementação.Dessaformaobtemosumbaixoacoplamento:podemostrocaraimplementação,jáqueestamosprogramandoparaainterface!Porexemplo:

classEmpresa{

privateList<Funcionario>empregados=newArrayList<>();

//...}

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

Vimos anteriormente que as listas são percorridas demaneira pré-determinada de acordo com ainclusãodositens.Mas,muitasvezes,queremospercorreranossalistademaneiraordenada.

AclasseCollectionstrazummétodoestáticosortquerecebeumListcomoargumentoeoordenaporordemcrescente.Porexemplo:

List<String>lista=newArrayList<>();lista.add("Sérgio");lista.add("Paulo");lista.add("Guilherme");

//reparequeotoStringdeArrayListfoisobrescrito:System.out.println(lista);

Collections.sort(lista);

System.out.println(lista);

Aotestaroexemploacima,vocêobservaráque,primeiro,alistaéimpressanaordemdeinserçãoe,depoisdeinvocarosort,elaéimpressaemordemalfabética.

AprendasedivertindonaAluraStart!

15.5ORDENAÇÃO:COLLECTIONS.SORT

.

Page 225: FJ-11 Java e Orientação a Objetos

Mas toda lista em Javapode serdequalquer tipodeobjeto, por exemplo,ContaCorrente. E sequisermosordenaruma listadeContaCorrente?Emqueordema classeCollections ordenará?Pelosaldo?Pelonomedocorrentista?

ContaCorrentec1=newContaCorrente();c1.deposita(500);

ContaCorrentec2=newContaCorrente();c2.deposita(200);

ContaCorrentec3=newContaCorrente();c3.deposita(150);

List<ContaCorrente>contas=newArrayList<>();contas.add(c1);contas.add(c3);contas.add(c2);

Collections.sort(contas);//qualseriaocritérioparaestaordenação?

Semprequefalamosemordenação,precisamospensaremumcritériodeordenação,umaformadedeterminar qual elemento vem antes de qual. É necessário instruir o sort sobre como compararnossasContaCorrenteafimdedeterminarumaordemnalista.Paraisto,ométodosortnecessitaque todos seusobjetosda lista sejamcomparáveis epossuamummétodoque se comparacomoutraContaCorrente.Comoéqueométodosortteráagarantiadequeasuaclassepossuiessemétodo?Issoseráfeito,novamente,atravésdeumcontrato,deumainterface!

Vamos fazer com que os elementos da nossa coleção implementem a interfacejava.lang.Comparable,quedefineométodointcompareTo(Object).Estemétododeveretornarzero,seoobjetocomparadoforigualaesteobjeto,umnúmeronegativo,seesteobjetoformenorqueoobjetodado,eumnúmeropositivo,seesteobjetoformaiorqueoobjetodado.

ParaordenarasContaCorrentesporsaldo,bastaimplementaroComparable:

publicclassContaCorrenteextendsContaimplementsComparable<ContaCorrente>{

//...todoocódigoanteriorficaaqui

publicintcompareTo(ContaCorrenteoutra){if(this.saldo<outra.saldo){return-1;}

if(this.saldo>outra.saldo){return1;}

return0;}}

Com o código anterior, nossa classe tornou-se "comparável": dados dois objetos da classe,conseguimos dizer se um objeto émaior,menor ou igual ao outro, segundo algum critério por nós

.

Page 226: FJ-11 Java e Orientação a Objetos

definido.Nonossocaso,acomparaçãoseráfeitabaseando-senosaldodaconta.

Reparequeocritériodeordenaçãoé totalmenteaberto,definidopeloprogramador.Sequisermosordenarporoutroatributo(ouatéporumacombinaçãodeatributos),bastamodificaraimplementaçãodométodocompareTonaclasse.

QuandochamarmosométodosortdeCollections,elesaberácomofazeraordenaçãodalista;eleusaráocritérioquedefinimosnométodocompareTo.

OUTRAIMPLEMENTAÇÃO...

Oqueachadaimplementaçãoabaixo?

publicintcompareTo(Contaoutra){returnInteger.compare(this.getNumero(),outra.getNumero());}

Mas,eoexemploanterior,comumalistadeStrings?Porqueaordenaçãofuncionou,naquelecaso,semprecisarmos fazernada? Simples: quemescreveu a classeString (lembre que ela é uma classecomoqualqueroutra)implementouainterfaceComparableeométodocompareToparaStrings,fazendocomparaçãoemordemalfabética.(ConsulteadocumentaçãodaclasseStringevejaométodocompareTo lá).OmesmoacontececomoutrasclassescomoInteger,BigDecimal,Date, entreoutras.

.

Page 227: FJ-11 Java e Orientação a Objetos

OUTROSMÉTODOSDACLASSECOLLECTIONS

AclasseCollectionstrazumagrandequantidadedemétodosestáticosúteisnamanipulaçãodecoleções.

binarySearch(List,Object):Realizaumabuscabináriapordeterminadoelementonalistaordenadaeretornasuaposiçãoouumnúmeronegativo,casonãoencontrado.

max(Collection):Retornaomaiorelementodacoleção.

min(Collection):Retornaomenorelementodacoleção.

reverse(List):Invertealista.

...emuitosoutros.Consulteadocumentaçãoparaveroutrosmétodos.

No Java 8 muitas dessas funcionalidades da Collections podem ser feitas através doschamadosStreams,queficaumpoucoforadoescopodeumcursoinicialdeJava.

Existeumaclasseanáloga,ajava.util.Arrays,quefazoperaçõessimilarescomarrays.

Éimportanteconhecê-lasparaevitarescrevercódigojáexistente.

Vamosordenarocampodedestinoda teladedetalhesdacontaparaqueascontasapareçamemordemalfabéticadetitular.

1. FaçasuaclasseContaimplementarainterfaceComparable<Conta>.Utilizeocritériodeordenarpelotitulardaconta.

publicclassContaimplementsComparable<Conta>{...}

DeixeoseumétodocompareToparecidocomeste:

publicclassContaimplementsComparable<Conta>{

//...todoocódigoanteriorficaaqui

publicintcompareTo(ContaoutraConta){returnthis.titular.compareTo(outraConta.titular);}}

2. Queremosqueascontasapareçamnocampodedestinoordenadaspelotitular.Vamosentãocriaro

15.6EXERCÍCIOS:ORDENAÇÃO

.

Page 228: FJ-11 Java e Orientação a Objetos

método ordenaLista na classe ManipuladorDeContas. Use o Collections.sort() paraordenaralistarecuperadadoEvento:

publicclassManipuladorDeContas{

//outrosmétodos

publicvoidordenaLista(Eventoevento){List<Conta>contas=evento.getLista("destino");Collections.sort(contas);}}

Rodeaaplicação,adicionealgumascontaseverifiqueseascontasaparecemordenadaspelonomedotitularnateladedetalhesdeconta.

Atençãoespecial:reparequeescrevemosummétodocompareToemnossaclasseenossocódigonunca o invoca!! Isto émuito comum.Reescrevemos (ou implementamos)ummétodo e quemoinvocará seráumoutro conjuntode classes (nesse caso, quemestá chamandoocompareTo é oCollections.sort, queousa comobaseparao algoritmodeordenação). Isso criaum sistemaextremamente coeso e, aomesmo tempo, combaixo acoplamento: a classeCollections nuncaimaginouqueordenariaobjetosdotipoConta,mas jáqueelessãoComparable, o seumétodosortestásatisfeito.

3. OqueteriaacontecidoseaclasseContanãoimplementasseComparable<Conta>mas tivesseométodocompareTo?

Façaumteste:removatemporariamenteasentençaimplementsComparable<Conta>,nãoremovaométodocompareToevejaoqueacontece.Bastaterométodo,semassinarainterface?

4. Comoposso inverter a ordemdeuma lista?Comoposso embaralhar todosos elementosdeumalista?Comopossorotacionaroselementosdeumalista?

InvestigueadocumentaçãodaclasseCollectionsdentrodopacotejava.util.

5. (opcional)CrieumanovaclasseTestaListaquecriaumaArrayListeinserenovascontascomsaldosaleatóriosusandoumlaço(for).Adivinheonomedaclasseparacolocarsaldosaleatórios?Random. Do pacote java.util . Consulte sua documentação para usá-la (utilize o métodonextInt()passandoonúmeromáximoasersorteado).

6. ModifiqueaclasseTestaListaparautilizarumaLinkedListemvezdeArrayList:

List<Conta>contas=newLinkedList<Conta>();

Precisamos alterar mais algum código para que essa substituição funcione? Rode o programa.Algumadiferença?

7. (opcional)Imprimaareferênciaparaessalista.OtoStringdeumaArrayList/LinkedListé

.

Page 229: FJ-11 Java e Orientação a Objetos

reescrito?

System.out.println(contas);

Umconjunto(Set)funcionadeformaanálogaaosconjuntosdamatemática,eleéumacoleçãoquenãopermiteelementosduplicados.

Outracaracterísticafundamentaldeleéofatodequeaordememqueoselementossãoarmazenadospodenãoseraordemnaqualelesforaminseridosnoconjunto.Ainterfacenãodefinecomodeveserestecomportamento.Talordemvariadeimplementaçãoparaimplementação.

Um conjunto é representado pela interfaceSet e tem como suas principais implementações asclassesHashSet,LinkedHashSeteTreeSet.

15.7CONJUNTO:JAVA.UTIL.SET

.

Page 230: FJ-11 Java e Orientação a Objetos

Ocódigoaseguircriaumconjuntoeadicionadiversoselementos,ealgunsrepetidos:

Set<String>cargos=newHashSet<>();

cargos.add("Gerente");cargos.add("Diretor");cargos.add("Presidente");cargos.add("Secretária");cargos.add("Funcionário");cargos.add("Diretor");//repetido!

//imprimenatelatodososelementosSystem.out.println(cargos);

Aqui,osegundoDiretornãoseráadicionadoeométodoaddlheretornaráfalse.

O uso de um Set pode parecer desvantajoso, já que ele não armazena a ordem, e não aceitaelementos repetidos. Não hámétodos que trabalham com índices, como o get(int) que as listaspossuem.AgrandevantagemdoSetéqueexistemimplementações,comoaHashSet, quepossuiumaperformanceincomparávelcomasListsquandousadoparapesquisa(métodocontains porexemplo).Veremosessaenormediferençaduranteosexercícios.

ORDEMDEUMSET

Seriapossívelusarumaoutraimplementaçãodeconjuntos,comoumTreeSet,queinsereoselementosdetalformaque,quandoforempercorridos,elesapareçamemumaordemdefinidapelométodo de comparação entre seus elementos. Esse método é definido pela interfacejava.lang.Comparable.Ou,ainda,podesepassarumComparatorparaseuconstrutor.

JáoLinkedHashSetmantémaordemdeinserçãodoselementos.

AntesdoJava5,nãopodíamosutilizargenerics,eusávamosoSetdeformaqueeletrabalhavacomObject,havendonecessidadedecastings.

.

Page 231: FJ-11 Java e Orientação a Objetos

Conheça a Casa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Com a curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

AscoleçõestêmcomobaseainterfaceCollection,quedefinemétodosparaadicionareremoverumelemento,everificarseeleestánacoleção,entreoutrasoperações,comomostraatabelaaseguir:

UmacoleçãopodeimplementardiretamenteainterfaceCollection,porémnormalmenteseusaumadasduassubinterfacesmaisfamosas:justamenteSeteList.

A interfaceSet, como previamente vista, define um conjunto de elementos únicos enquanto ainterfaceListpermiteelementosduplicados,alémdemanteraordemaqualelesforamadicionados.

A busca emumSet pode sermais rápida do que emumobjeto do tipoList, pois diversasimplementações utilizam-se de tabelas de espalhamento (hash tables), realizando a busca para tempolinear(O(1)).

A interfaceMap faz parte do framework,mas não estendeCollection. (veremos Map maisadiante).

Seuslivrosdetecnologiaparecemdoséculopassado?

15.8PRINCIPAISINTERFACES:JAVA.UTIL.COLLECTION

.

Page 232: FJ-11 Java e Orientação a Objetos

NoJava5,temosoutrainterfacefilhadeCollection:aQueue,quedefinemétodosdeentradaede saídae cujocritério serádefinidopela sua implementação (porexemploLIFO,FIFOouaindaumheapondecadaelementopossuisuachavedeprioridade).

Comopercorreroselementosdeumacoleção?Se foruma lista,podemossempreutilizarumlaçofor,invocandoométodogetparacadaelemento.Maseseacoleçãonãopermitirindexação?

Por exemplo, um Set não possui um método para pegar o primeiro, o segundo ou o quintoelementodoconjunto,jáqueumconjuntonãopossuioconceitode"ordem"

Podemosusaroenhanced-for(o"foreach")doJava5parapercorrerqualquerCollectionsemnospreocupar com isso. Internamente o compilador vai fazer com que seja usado o Iterator daCollectiondadaparapercorreracoleção.Repare:

Set<String>conjunto=newHashSet<>();

conjunto.add("java");conjunto.add("vraptor");conjunto.add("scala");

for(Stringpalavra:conjunto){System.out.println(palavra);}

Emqueordemoselementosserãoacessados?

15.9PERCORRENDOCOLEÇÕESNOJAVA5

.

Page 233: FJ-11 Java e Orientação a Objetos

Numa lista, os elementos aparecerão de acordo com o índice em que foram inseridos, isto é, deacordo com o que foi pré-determinado. Em um conjunto, a ordem depende da implementação dainterfaceSet:vocêmuitasvezesnãovaisaberaocertoemqueordemosobjetosserãopercorridos.

PorqueoSeté,então,tãoimportanteeusado?

Paraperceberseumitemjáexisteemumalista,émuitomaisrápidousaralgumasimplementaçõesdeSetdoqueumList, eosTreeSets já vêmordenadosde acordo comas características quedesejarmos!SempreconsidereusarumSetsenãohouveranecessidadedeguardaroselementosemdeterminadaordemebuscá-losatravésdeumíndice.

No eclipse, você pode escrever foreach e dar ctrl+espaço, que ele vai gerar o esqueleto desseenhancedfor!Muitoútil!

Antes do Java 5 introduzir o novo enhanced-for, iterações em coleções eram feitas com oIterator . Toda coleção fornece acesso a um iterator, um objeto que implementa a interfaceIterator,queconheceinternamenteacoleçãoedáacessoatodososseuselementos,comoafiguraabaixomostra.

Aindahoje(depoisdoJava5)podemosusaroIterator,masomaiscomuméusaroenhanced-for.E,naverdade,oenhanced-foréapenasumaçúcarsintáticoqueusaiteratorportrásdospanos.

Primeiro criamos um Iterator que entra na coleção. A cada chamada do método next, oIterator retorna o próximo objeto do conjunto.Um iterator pode ser obtido com ométodoiterator()deCollection,porexemplonumalistadeString:

Iterator<String>i=lista.iterator();

AinterfaceIteratorpossuidoismétodosprincipais:hasNext()(comretornobooleano),indica

15.10 PARA SABER MAIS: ITERANDO SOBRE COLEÇÕES COMJAVA.UTIL.ITERATOR

.

Page 234: FJ-11 Java e Orientação a Objetos

seaindaexisteumelementoaserpercorrido;next(),retornaopróximoobjeto.

Voltandoaoexemplodoconjuntodestrings,vamospercorreroconjunto:

Set<String>conjunto=newHashSet<>();conjunto.add("item1");conjunto.add("item2");conjunto.add("item3");

//retornaoiteratorIterator<String>i=conjunto.iterator();while(i.hasNext()){//recebeapalavraStringpalavra=i.next();System.out.println(palavra);}

Owhile anterior só terminaquando todosos elementosdo conjunto forempercorridos, isto é,quandoométodohasNextmencionarquenãoexistemmaisitens.

LISTITERATOR

Umalistafornece,alémdeacessoaumIterator,umListIterator,queoferecerecursosadicionais,específicosparalistas.

UsandooListIterator,vocêpode,porexemplo,adicionarumelementonalistaouvoltarparaoelementoquefoi"iterado"anteriormente.

USARITERATOREMVEZDOENHANCED-FOR?

OIteratorpodesimaindaserútil.Alémde iterarnacoleçãocomofazoenhanced-for,oIterator consegue remover elementos da coleção durante a iteração de uma forma elegante,atravésdométodoremove.

.

Page 235: FJ-11 Java e Orientação a Objetos

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design, Infra,Front-Ende

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Muitas vezes queremos buscar rapidamente um objeto dado alguma informação sobre ele. Umexemploseria,dadaaplacadocarro,obtertodososdadosdocarro.Poderíamosutilizarumalistaparaissoepercorrer todososseuselementos,mas issopodeserpéssimoparaaperformance,mesmoparalistasnãomuitograndes.Aquientraomapa.

Ummapaécompostoporumconjuntodeassociaçõesentreumobjetochaveaumobjetovalor.Éequivalenteaoconceitodedicionário,usadoemvárias linguagens.Algumas linguagens,comoPerlouPHP,possuemumsuportemaisdiretoamapas,ondesãoconhecidoscomomatrizes/arraysassociativas.

java.util.Map é um mapa, pois é possível usá-lo para mapear uma chave a um valor, porexemplo: mapeie à chave "empresa" o valor "Caelum", ou então mapeie à chave "rua" ao valor"Vergueiro".Semelhanteaassociaçõesdepalavrasquepodemosfazeremumdicionário.

Agoraéamelhorhoraderespirarmaistecnologia!

15.11MAPAS-JAVA.UTIL.MAP

.

Page 236: FJ-11 Java e Orientação a Objetos

Ométodo put(Object, Object) da interface Map recebe a chave e o valor de uma novaassociação. Para saber o que está associado a um determinado objeto-chave, passa-se esse objeto nométodoget(Object).Semdúvidaessassãoasduasoperaçõesprincipaisemaisfrequentesrealizadassobreummapa.

Observeoexemplo:criamosduascontascorrenteseascolocamosemummapaassociando-asaosseusdonos.

ContaCorrentec1=newContaCorrente();c1.deposita(10000);

ContaCorrentec2=newContaCorrente();c2.deposita(3000);

//criaomapaMap<String,ContaCorrente>mapaDeContas=newHashMap<>();

//adicionaduaschaveseseusrespectivosvaloresmapaDeContas.put("diretor",c1);mapaDeContas.put("gerente",c2);

//qualacontadodiretor?(semcasting!)ContaCorrentecontaDoDiretor=mapaDeContas.get("diretor");System.out.println(contaDoDiretor.getSaldo());

Ummapaémuitousadopara"indexar"objetosdeacordocomdeterminadocritério,parapodermosbuscar esse objetos rapidamente. Ummapa costuma aparecer juntamente com outras coleções, parapoderrealizaressasbuscas!

Ele,assimcomoascoleções,trabalhadiretamentecomObjects(tantonachavequantonovalor),oque tornaria necessário o casting no momento que recuperar elementos. Usando os generics, comofizemosaqui,nãoprecisamosmaisdocasting.

SuasprincipaisimplementaçõessãooHashMap,oTreeMapeoHashtable.

Apesardomapa fazerpartedo framework, elenão estende a interfaceCollection, por ter umcomportamentobemdiferente.Porém,ascoleçõesinternasdeummapa(adechaveseadevalores,verFigura7)sãoacessíveispormétodosdefinidosnainterfaceMap.

.

Page 237: FJ-11 Java e Orientação a Objetos

OmétodokeySet()retornaumSetcomaschavesdaquelemapaeométodovalues()retornaaCollectioncomtodososvaloresqueforamassociadosaalgumadaschaves.

Ummapa importante é a tradicional classeProperties, quemapeia strings e émuitoutilizadaparaaconfiguraçãodeaplicações.

APropertiespossui,também,métodosparaleregravaromapeamentocombaseemumarquivotexto,facilitandomuitoasuapersistência.

Propertiesconfig=newProperties();

config.setProperty("database.login","scott");config.setProperty("database.password","tiger");config.setProperty("database.url","jdbc:mysql:/localhost/teste");

//muitaslinhasdepois...

Stringlogin=config.getProperty("database.login");Stringpassword=config.getProperty("database.password");Stringurl=config.getProperty("database.url");DriverManager.getConnection(url,login,password);

ReparequenãohouveanecessidadedocastingparaStringnomomentoderecuperarosobjetosassociados. Isto porque a classe Properties foi desenhada com o propósito de trabalhar com a

15.12PARASABERMAIS:PROPERTIES

.

Page 238: FJ-11 Java e Orientação a Objetos

associaçãoentreStrings.

Muitas das coleções do java guardam os objetos dentro de tabelas de hash. Essas tabelas sãoutilizadasparaqueapesquisadeumobjetosejafeitademaneirarápida.

Comofunciona?Cadaobjetoé"classificado"peloseuhashCodee,comisso,conseguimosespalharcadaobjetoagrupando-ospelohashCode.Quandobuscamosdeterminadoobjeto,sóvamosprocurarentre os elementos que estão no grupo daquele hashCode. Dentro desse grupo, vamos testando oobjetoprocuradocomocandidatousandoequals().

Paraque isso funcionedireito,ométodohashCodedecadaobjetodeve retornaromesmovalorparadoisobjetos,seelessãoconsideradosequals.Emoutraspalavras:

a.equals(b)implicaa.hashCode()==b.hashCode()

Implementar hashCode de tal maneira que ele retorne valores diferentes para dois objetosconsideradosequalsquebraocontratodeObjecteresultaráemcollectionsqueusamespalhamento(comoHashSet,HashMapeHashtable),nãoachandoobjetosiguaisdentrodeumamesmacoleção.

EQUALSEHASHCODENOECLIPSE

O Eclipse é capaz de gerar uma implementação correta de equals e hashcode baseado nosatributosquevocêqueiracomparar.BastairnomenuSourceedepoisemGeneratehashcode()andequals().

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelum eobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

15.13PARASABERMAIS:EQUALSEHASHCODE

EditoraCasadoCódigocomlivrosdeumaformadiferente

.

Page 239: FJ-11 Java e Orientação a Objetos

AscoleçõesdoJavaoferecemgrandeflexibilidadeaousuário.Aperdadeperformanceemrelaçãoàutilizaçãodearrayséirrelevante,masdeve-setomaralgumasprecauções:

Grande parte das coleções usam, internamente, um array para armazenar os seus dados.Quandoessearraynãoémaissuficiente,écriadaummaioreoconteúdodaantigaécopiado.Esteprocessopodeacontecermuitasvezes,nocasodevocêterumacoleçãoquecrescemuito.Vocêdeve,então,criarumacoleçãojácomumacapacidadegrande,paraevitaroexcessoderedimensionamento.

Eviteusarcoleçõesqueguardamoselementospelasuaordemdecomparaçãoquandonãohánecessidade.UmTreeSet gasta computacionalmenteO(log(n)) para inserir (ele utilizaumaárvorerubro-negracomoimplementação),enquantooHashSetgastaapenasO(1).

NãoiteresobreumaListutilizandoumforde0atélist.size()eusandoget(int)parareceberosobjetos.Enquantoissopareceatraente,algumasimplementaçõesdaListnãosão de acesso aleatório como a LinkedList , fazendo esse código ter uma péssimaperformancecomputacional.(useIterator)

1. Crieumcódigoqueinsira30milnúmerosnumaArrayListepesquise-os.VamosusarummétododeSystemparacronometrarotempogasto:

publicclassTestaPerformance{

publicstaticvoidmain(String[]args){System.out.println("Iniciando...");Collection<Integer>teste=newArrayList<>();longinicio=System.currentTimeMillis();

inttotal=30000;

for(inti=0;i<total;i++){teste.add(i);}

for(inti=0;i<total;i++){teste.contains(i);}

longfim=System.currentTimeMillis();longtempo=fim-inicio;System.out.println("Tempogasto:"+tempo);}}

TroqueaArrayListporumHashSeteverifiqueotempoquevaidemorar:

Collection<Integer>teste=newHashSet<>();

15.14PARASABERMAIS:BOASPRÁTICAS

15.15EXERCÍCIOS:COLLECTIONS

.

Page 240: FJ-11 Java e Orientação a Objetos

Oqueélento?Ainserçãode30milelementosouas30milbuscas?Descubracomputandootempogastoemcadaforseparadamente.

Adiferençaémaisquegritante.Sevocêpassarde30milparaumnúmeromaior,como50ou100mil,veráqueissoinviabilizaporcompletoousodeumaList,nocasoemquequeremosutilizá-laessencialmenteempesquisas.

2. (conceitual,importante)Repareque,sevocêdeclararacoleçãoedernewassim:

Collection<Integer>teste=newArrayList<>();

emvezde:

ArrayList<Integer>teste=newArrayList<>();

É garantido que vai ter de alterar só essa linha para substituir a implementação porHashSet.Estamosaquiusandoopolimorfismoparanosprotegerquemudançasde implementaçãovenhamnos obrigar a alterar muito código. Mais uma vez: programe voltado a interface, e não àimplementação!

Esse é um excelente exemplo de bom uso de interfaces, afinal, de que importa como a coleçãofunciona? O que queremos é uma coleção qualquer, isso é suficiente para os nossos propósitos!Nosso código está com baixo acoplamento em relação a estrutura de dados utilizada: podemostrocá-lafacilmente.

Esseéumcódigoextremamenteelegantee flexível.Como tempovocêvai repararque as pessoastentamprogramarsempresereferindoaessasinterfacesmenosespecíficas,namedidadopossível:métodos costumam receber e devolver Collections, Lists e Sets em vez de referenciardiretamente uma implementação. É o mesmo que ocorre com o uso de InputStream eOutputStream:elessãoosuficiente,nãoháporqueforçarousodealgomaisespecífico.

Obviamente,algumasvezesnãoconseguimostrabalhardessaformaeprecisamosusarumainterfacemaisespecíficaoumesmonosreferiraoobjetopelasuaimplementaçãoparapoderchamaralgunsmétodos. Por exemplo, TreeSet tem mais métodos que os definidos em Set, assim comoLinkedListemrelaçãoàList.

DêumexemplodeumcasoemquenãopoderíamosnosreferiraumacoleçãodeelementoscomoCollection,masnecessariamenteporinterfacesmaisespecíficascomoListouSet.

3. FaçatestescomoMap,comovistonessecapítulo:

publicclassTestaMapa{

publicstaticvoidmain(String[]args){Contac1=newContaCorrente();c1.deposita(10000);

Contac2=newContaCorrente();

.

Page 241: FJ-11 Java e Orientação a Objetos

c2.deposita(3000);

//criaomapaMapmapaDeContas=newHashMap();

//adicionaduaschaveseseusvaloresmapaDeContas.put("diretor",c1);mapaDeContas.put("gerente",c2);

//qualacontadodiretor?ContacontaDoDiretor=(Conta)mapaDeContas.get("diretor");System.out.println(contaDoDiretor.getSaldo());}}

Depois,altereocódigoparausarogenericsenãohaveranecessidadedocasting,alémdagarantiadequenossomapaestaráseguroemrelaçãoatipagemusada.

VocêpodeutilizaroquickfixdoEclipseparaqueeleconserteissoparavocê:nalinhaemquevocêestáchamandooput,useoctrl+1.Depoisdemaisumquickfix(descubra!)seucódigodeveficarcomosegue:

//criaomapaMap<String,Conta>mapaDeContas=newHashMap<>();

Queopçãodoctrl+1vocêescolheuparaqueeleadicionasseogenericsparavocê?

4. (opcional)Assimcomono exercício1, crieumacomparação entreArrayList eLinkedList,para ver qual é a mais rápida para se adicionar elementos na primeira posição (list.add(0,elemento)),comoporexemplo:

publicclassTestaPerformanceDeAdicionarNaPrimeiraPosicao{publicstaticvoidmain(String[]args){System.out.println("Iniciando...");longinicio=System.currentTimeMillis();

//trocardepoisporArrayListList<Integer>teste=newLinkedList<>();

for(inti=0;i<30000;i++){teste.add(0,i);}

longfim=System.currentTimeMillis();doubletempo=(fim-inicio)/1000.0;System.out.println("Tempogasto:"+tempo);}}

Seguindo o mesmo raciocínio, você pode ver qual é a mais rápida para se percorrer usando oget(indice) (sabemosqueo correto seriautilizar o enhanced for ouoIterator). Para isso,insira30milelementosedepoispercorra-osusandocadaimplementaçãodeList.

Perceba que aqui o nosso intuito não é que você aprenda qual é o mais rápido, o importante éperceber que podemos tirar proveito do polimorfismo para nos comprometer apenas com a

.

Page 242: FJ-11 Java e Orientação a Objetos

interface.Depois,quandonecessário,podemostrocareescolherumaimplementaçãomaisadequadaasnossasnecessidades.

Qualdasduaslistasfoimaisrápidaparaadicionarelementosàprimeiraposição?

5. (opcional) Crie a classe Banco (caso não tenha sido criada anteriormente) no pacotebr.com.caelum.contas.modeloquepossuiumaListdeContachamadacontas.ReparequenumalistadeConta,vocêpodecolocartantoContaCorrentequantoContaPoupancaporcausadopolimorfismo.

Crie ummétodovoid adiciona(Conta c), ummétodoConta pega(int x) e outro intpegaQuantidadeDeContas(). Basta usar a sua lista e delegar essas chamadas para os métodos ecoleçõesqueestudamos.

ComoficouaclasseBanco?

6. (opcional)NoBanco,crieummétodoContabuscaPorTitular(Stringnome)queprocuraporumaContacujotitularsejaequalsaonomeDoTitulardado.

Vocêpode implementaressemétodocomumfornasua listadeConta, porémnão temumaperformanceeficiente.

Adicionandoum atributo privado do tipoMap<String,Conta> terá um impacto significativo.Toda vez que o método adiciona(Conta c) for invocado, você deve invocar.put(c.getTitular(),c)noseumapa.Dessamaneira,quandoalguéminvocarométodoContabuscaPorTitular(String nomeDoTitular), basta você fazer o get no seu mapa, passandonomeDoTitularcomoargumento!

Note, apenas, que isso é só um exercício! Dessa forma você não poderá ter dois clientes com omesmonomenessebanco,oquesabemosquenãoélegal.

ComoficariasuaclasseBancocomesseMap?

7. (opcional, avançado) Crie o método hashCode para a sua conta, de forma que ele respeite oequalsdequeduascontassãoequalsquandotemomesmonúmeroeagência.Felizmenteparanós, o próprio Eclipse já vem com um criador de equals e hashCode que os faz de formaconsistente.

NaclasseConta,useoctrl+3ecomeceaescreverhashCodeparaacharaopçãodegerá-los.Então,selecioneosatributosnumeroeagenciaemandegerarohashCodeeoequals.

Comoficouocódigogerado?

8. (opcional, avançado) Crie uma classe de teste e verifique se sua classe Conta funciona agoracorretamenteemumHashSet,istoé,queelanãoguardacontascomnúmeroeagênciarepetidos.

.

Page 243: FJ-11 Java e Orientação a Objetos

Depois,removaométodohashCode.Continuafuncionando?

DominarousoeofuncionamentodohashCodeéfundamentalparaobomprogramador.

1. Gere todososnúmeros entre 1 e 1000 eordene emordemdecrescenteutilizandoumTreeSet.Comoficouseucódigo?

2. Geretodososnúmerosentre1e1000eordeneemordemdecrescenteutilizandoumArrayList.Comoficouseucódigo?

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

E se precisarmos ordernar uma lista com outro critério de comparação? Se precisarmos alterar aprópriaclasseemudarseumétodocompareTo, teremosapenasuma formade comparaçãoporvez.Precisamosdemais!

É possível definir outros critérios de ordenação usando a interface do java.util chamadaComparator . Existe um método sort em Collections que recebe, além da List , umComparatordefinindoumcritériodeordenaçãoespecífico.ÉpossívelterváriosComparators comcritériosdiferentesparausarquandofornecessário.

VamoscriarumComparatorqueserveparaordernarStringsdeacordocomseutamanho.

classComparadorPorTamanhoimplementsComparator<String>{publicintcompare(Strings1,Strings2){if(s1.length()<s2.length())return-1;

15.16DESAFIOS

JáconheceoscursosonlineAlura?

15.17PARASABERMAIS:COMPARATORS,CLASSESANÔNIMAS,JAVA8EOLAMBDA

.

Page 244: FJ-11 Java e Orientação a Objetos

if(s2.length()<s1.length())return1;return0;}}

Repare que, diferente de Comparable , o método aqui se chama compare e recebe doisargumentos,jáquequemoimplementanãoéopróprioobjeto.

Podemosdeixá-lomaiscurto,tomandoproveitodométodoestáticoauxiliarInteger.comparequecomparadoisinteiros:

classComparadorPorTamanhoimplementsComparator<String>{publicintcompare(Strings1,Strings2){returnInteger.compare(s1.length(),s2.length());}}

Depois, dentro do nosso código, teríamos uma chamada a Collections.sort passando ocomparadortambém:

List<String>lista=newArrayList<>();lista.add("Sérgio");lista.add("Paulo");lista.add("Guilherme");

//invocandoosortpassandoocomparadorComparadorPorTamanhocomparador=newComparadorPorTamanho();Collections.sort(lista,comparador);

System.out.println(lista);

Comoavariáveltemporáriacomparadoréutilizadaapenasaí,écomumescrevermosdiretamenteCollections.sort(lista,newComparadorPorTamanho()).

ReparequeaclasseComparadorPorTamanhoébempequena.Écomumhaveranecessidadedecriarvários critérios de comparação, emuitas vezes eles são utilizados apenas num único ponto do nossoprograma.

Háumaformadeescreveressaclasseeinstanciá-lanumaúnicainstrução.VocêfazissodandonewemComparator.Mascomo,sedissemosqueumainterfacenãopodeserinstanciada?RealmentenewComparator() não compila. Mas vai compilar se você abrir chaves e implementar tudo o que énecessário.Vejaocódigo:

List<String>lista=newArrayList<>();lista.add("Sérgio");lista.add("Paulo");lista.add("Guilherme");

Comparator<String>comparador=newComparator<String>(){publicintcompare(Strings1,Strings2){

EscrevendoumComparatorcomclasseanônima

.

Page 245: FJ-11 Java e Orientação a Objetos

returnInteger.compare(s1.length(),s2.length());}};Collections.sort(lista,comparador);

System.out.println(lista);

Asintaxeérealmenteesdrúxula!Numaúnicalinhanósdefinimosumaclasseeainstanciamos!Umaclassequenemmesmonometem.Poressemotivoorecursoéchamadodeclasseanônima.Eleaparececomcertafrequência,emespecialparanãoprecisarimplementarinterfacesqueocódigodosmétodosseriammuitocurtosenão-reutilizáveis.

Há ainda como diminuir ainda mais o código, evitando a criação da variável temporáriacomparadoreinstanciandoainterfacedentrodainvocaçãoparaosort:

List<String>lista=newArrayList<>();lista.add("Sérgio");lista.add("Paulo");lista.add("Guilherme");

Collections.sort(lista,newComparator<String>(){publicintcompare(Strings1,Strings2){returnInteger.compare(s1.length(),s2.length());}});

System.out.println(lista);

VocêpodefazerodownloaddoJava8aqui:

https://jdk8.java.net/download.html

O Eclipse já possui atualizações para compatibilidade com a nova versão, mas ele pode serrelativamenteinstável.Vocêpodeutilizaralinhadecomando,comofizemosnocomeçodocurso,paraessestestes,casoachenecessário.

ApartirdessanovaversãodoJavaháumaformamaissimplesdeobteressemesmoComparator.Repare:

Collections.sort(lista,(s1,s2)->Integer.compare(s1.length(),s2.length()));

Ocódigo(s1,s2)->Integer.compare(s1.length(),l2.length())geraráumainstânciadeComparatorqueocompare devolveInteger.compare(s1.length,l2.length).Atémesmooreturnnãoénecessário,jáquesótemosumainstruçãoapóso->.EsseéorecursodelambdadoJava8.

Uma outra novidade do Java 8 é a possibilidade de declarar métodos concretos dentro de umainterface, os chamadosdefaultmethods. Até o Java 7 não existiasort em listas. Colocar um novométodoabstratoemumainterfacepodeterconsequênciasdrásticas: todomundoqueaimplementava

EscrevendoumComparatorcomlambdanoJava8

.

Page 246: FJ-11 Java e Orientação a Objetos

paradecompilar!Mascolocarummétododefaultnãotemessemesmoimpactodevastador, jáqueasclassesqueimplementamainterface'herdam'essemétodo.Entãovocêpodefazer:

lista.sort((s1,s2)->Integer.compare(s1.length(),s2.length()));

Háoutrosmétodosnascoleçõesqueutilizamdolambdaparaseremmaissucintos.

UmdeleséoforEach.Vocêpodefazerlista.forEach(s->System.out.println(s)).

OremoveIféoutrodeles.Porexemplo,podemosescreverlista.removeIf(c->c.getSaldo()<0).OremoveIfrecebecomoargumentoumobjetoqueimplementeainterfacePredicate,quepossuiapenasummétodo,querecebeumelementedevolveboolean.Porpossuirapenasummétodoabstrato também chamamos essa interface é uma interface funcional. Omesmo ocorre ao invocar oforEach,querecebeumargumentoqueimplementaainterfacefuncionalConsumer.

TrabalharcomlambdasnoJava8vaimuitoalém.Hádiversosdetalheserecursosquenãoveremosnesseprimeirocurso.Casotenhacuriosidadeequeirasabermais,vejanoblog:

http://blog.caelum.com.br/o-minimo-que-voce-deve-saber-de-java-8/

Mais?Methodreferences,streamsecollectors

.

Page 247: FJ-11 Java e Orientação a Objetos

CAPÍTULO16

"A benevolência é sobretudo um vício do orgulho e não uma virtude da alma." -- Doantien AlphonseFrançois(MarquêsdeSade)

Aotérminodessecapítulo,vocêserácapazde:

usarasclasseswrappers(comoInteger)eboxing;lereescreverbytes,caractereseStringsde/paraaentradaesaídapadrão;lereescreverbytes,caractereseStringsde/paraarquivos;utilizarbuffersparaagilizaraleituraeescritaatravésdefluxos;usarScannerePrintStream.

VamospassaraconhecerAPIsdoJava.java.ioejava.utilpossuemasclassesquevocêmaiscomumentevaiusar,nãoimportandoseseuaplicativoédesktop,web,oumesmoparacelulares.

Apesardeserimportanteconhecernomesemétodosdasclassesmaisutilizadas,ointeressanteaquiéquevocêenxerguequetodososconceitospreviamenteestudadossãoaplicadosatodahoranasclassesdabibliotecapadrão.

Nãosepreocupeemdecorarnomes.Atenha-seementendercomoessasclassesestãorelacionadasecomoelasestãotirandoproveitodousodeinterfaces,polimorfismo,classesabstrataseencapsulamento.Lembre-sedeestarcomadocumentação(javadoc)abertaduranteocontatocomessespacotes.

Veremos também threads e sockets em capítulos posteriores, que ajudarão a condensar nossoconhecimento, tendo em vista que no exercício de sockets utilizaremos todos conceitos aprendidos,juntamentecomasváriasAPIs.

PACOTEJAVA.IO

16.1CONHECENDOUMAAPI

.

Page 248: FJ-11 Java e Orientação a Objetos

Conheça a Casa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Com a curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

AssimcomotodoorestodasbibliotecasemJava,apartedecontroledeentradae saídadedados(conhecidocomoio)éorientadaaobjetoseusaosprincipaisconceitosmostradosatéagora:interfaces,classesabstratasepolimorfismo.

Aideiaatrásdopolimorfismonopacotejava.ioédeutilizarfluxosdeentrada(InputStream)edesaída(OutputStream)paratodaequalqueroperação,sejaelarelativaaumarquivo,aumcampoblobdobancodedados,aumaconexãoremotaviasockets,ouatémesmoàsentradaesaídapadrãodeumprograma(normalmenteotecladoeoconsole).

AsclassesabstratasInputStreameOutputStreamdefinem,respectivamente,ocomportamentopadrãodos fluxosemJava:emumfluxodeentrada,épossível lerbytese,no fluxode saída,escreverbytes.

A grande vantagem dessa abstração pode ser mostrada em ummétodo qualquer que utiliza umOutputStreamrecebidocomoargumentoparaescreveremumfluxodesaída.Paraondeométodoestáescrevendo?Nãosesabeenãoimporta:quandoosistemaprecisarescreveremumarquivoouemumasocket,bastachamaromesmométodo,jáqueeleaceitaqualquerfilhadeOutputStream!

Paralerumbytedeumarquivo,vamosusaroleitordearquivo,oFileInputStream.ParaumFileInputStreamconseguirlerumbyte,eleprecisasaberdeondeeledeveráler.Essainformaçãoétãoimportantequequemescreveuessaclasseobrigavocêapassaronomedoarquivopeloconstrutor:semissooobjetonãopodeserconstruído.

classTestaEntrada{publicstaticvoidmain(String[]args)throwsIOException{

Seuslivrosdetecnologiaparecemdoséculopassado?

16.2ORIENTAÇÃOAOBJETOSNOJAVA.IO

16.3INPUTSTREAM,INPUTSTREAMREADEREBUFFEREDREADER

.

Page 249: FJ-11 Java e Orientação a Objetos

InputStreamis=newFileInputStream("arquivo.txt");intb=is.read();}}

A classe InputStream é abstrata e FileInputStream uma de suas filhas concretas.FileInputStream vai procurar o arquivo no diretório em que a JVM fora invocada (no caso doEclipse,vaiserapartirdedentrododiretóriodoprojeto).Alternativamentevocêpodeusarumcaminhoabsoluto.

Quandotrabalhamoscomjava.io,diversosmétodoslançamIOException,queéumaexceptiondo tipo checked - o que nos obriga a tratá-la ou declará-la. Nos exemplos aqui, estamos declarandoIOExceptionatravésdaclausulathrowsdomainapenasparafacilitaroexemplo.Casoaexceptionocorra,aJVMvaiparar,mostrandoastacktrace.Estanãoéumaboapráticaemumaaplicaçãoreal:tratesuasexceptionsparasuaaplicaçãopoderabortarelegantemente.

InputStream tem diversas outras filhas, como ObjectInputStream , AudioInputStream ,ByteArrayInputStream,entreoutras.

Pararecuperarumcaractere,precisamostraduzirosbytescomoencodingdadoparaorespectivocódigounicode,issopodeusarumoumaisbytes.Escreveressedecodificadorémuitocomplicado,quemfazissoporvocêéaclasseInputStreamReader.

classTestaEntrada{publicstaticvoidmain(String[]args)throwsIOException{InputStreamis=newFileInputStream("arquivo.txt");InputStreamReaderisr=newInputStreamReader(is);intc=isr.read();}}

OconstrutordeInputStreamReaderpodereceberoencodingaserutilizadocomoparâmetro,sedesejado,talcomoUTF-8ouISO-8859-1.

ENCODINGS

Devidoagrandequantidadedeaplicativosinternacionalizadosdehojeemdia,éimprescindívelqueumbomprogramadorentendabemoquesãooscharacterencodingseoUnicode.OblogdaCaelumpossuiumbomartigoarespeito:

http://blog.caelum.com.br/2006/10/22/entendendo-unicode-e-os-character-encodings/

InputStreamReader é filha da classe abstrataReader, que possui diversas outras filhas - sãoclassesquemanipulamchars.

ApesardaclasseabstrataReader jáajudarnotrabalhodemanipulaçãodecaracteres,aindaseria

.

Page 250: FJ-11 Java e Orientação a Objetos

difícilpegarumaString.AclasseBufferedReaderéumReaderquerecebeoutroReaderpeloconstrutoreconcatenaosdiversoscharsparaformarumaStringatravésdométodoreadLine:

classTestaEntrada{publicstaticvoidmain(String[]args)throwsIOException{InputStreamis=newFileInputStream("arquivo.txt");InputStreamReaderisr=newInputStreamReader(is);BufferedReaderbr=newBufferedReader(isr);Strings=br.readLine();}}

Como o próprio nome diz, essa classe lê doReader por pedaços (usando o buffer) para evitarrealizarmuitaschamadasao sistemaoperacional.Vocêpodeatéconfiguraro tamanhodobufferpeloconstrutor.

Éessaacomposiçãodeclassesqueestáacontecendo:

Essepadrãodecomposiçãoébastanteutilizadoeconhecido.ÉoDecoratorPattern.

Aqui,lemosapenasaprimeiralinhadoarquivo.OmétodoreadLinedevolvealinhaquefoilidaemuda o cursor para a próxima linha. Caso ele chegue ao fim do Reader (no nosso caso, fim doarquivo),elevaidevolvernull.Então,comumsimpleslaço,podemosleroarquivoporinteiro:

classTestaEntrada{publicstaticvoidmain(String[]args)throwsIOException{InputStreamis=newFileInputStream("arquivo.txt");InputStreamReaderisr=newInputStreamReader(is);BufferedReaderbr=newBufferedReader(isr);

Strings=br.readLine();//primeiralinha

while(s!=null){System.out.println(s);s=br.readLine();}

br.close();}}

Com um passe de mágica, passamos a ler do teclado em vez de um arquivo, utilizando oSystem.in,queéumareferênciaaumInputStreamoqual,porsuavez,lêdaentradapadrão.

16.4LENDOSTRINGSDOTECLADO

.

Page 251: FJ-11 Java e Orientação a Objetos

classTestaEntrada{publicstaticvoidmain(String[]args)throwsIOException{InputStreamis=System.in;InputStreamReaderisr=newInputStreamReader(is);BufferedReaderbr=newBufferedReader(isr);Strings=br.readLine();

while(s!=null){System.out.println(s);s=br.readLine();}}}

Apenasmodificamosaquemavariávelisestásereferindo.PodemosreceberargumentosdotipoInputStream e ter esse tipo de abstração: não importa exatamente de onde estamos lendo essepunhadodebytes,desdequeagenterecebaainformaçãoqueestamosquerendo.Comonafigura:

Repare que a ponta da direita poderia ser qualquer InputStream, seja ObjectInputStream,AudioInputStream,ByteArrayInputStream,ouanossaFileInputStream.Polimorfismo!OuvocêmesmopodecriarumafilhadeInputStream,sedesejar.

Por isso émuito comummétodos recebereme retornaremInputStream, em vez de suas filhasespecíficas. Com isso, elas desacoplam as informações e escondem a implementação, facilitando amudançaemanutençãodocódigo.Reparequeissovaiaoencontrodetudooqueaprendemosduranteoscapítulosqueapresentaramclassesabstratas,interfaces,polimorfismoeencapsulamento.

.

Page 252: FJ-11 Java e Orientação a Objetos

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design, Infra,Front-Ende

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Comovocêpodeimaginar,escreveremumarquivoéomesmoprocesso:

classTestaSaida{publicstaticvoidmain(String[]args)throwsIOException{OutputStreamos=newFileOutputStream("saida.txt");OutputStreamWriterosw=newOutputStreamWriter(os);BufferedWriterbw=newBufferedWriter(osw);

bw.write("caelum");

bw.close();}}

Lembre-sededarrefresh (cliquedadireitanonomedoprojeto,refresh)noseuprojetodoEclipseparaqueoarquivocriadoapareça.OFileOutputStream pode receberumbooleanocomosegundoparâmetro,paraindicarsevocêquerreescreveroarquivooumanteroquejáestavaescrito(append).

OmétodowritedoBufferedWriternãoinsereo(s)caractere(s)dequebradelinha.Paraisso,vocêpodechamarométodonewLine.

Agoraéamelhorhoraderespirarmaistecnologia!

16.5AANALOGIAPARAAESCRITA:OUTPUTSTREAM

.

Page 253: FJ-11 Java e Orientação a Objetos

FECHANDOOARQUIVOCOMOFINALLYEOTRY-WITH-RESOURCES

Éimportantesemprefecharoarquivo.Vocêpodefazerissochamandodiretamenteométodo close do FileInputStream / OutputStream , ou ainda chamando o close doBufferedReader/Writer.Nesseúltimocaso,ocloseserácascateadoparaosobjetososquaisoBufferedReader/Writer utiliza para realizar a leitura/escrita, além dele fazer o flush dosbuffersnocasodaescrita.

Écomumefundamentalqueocloseestejadentrodeumblocofinally.Seumarquivoforesquecido aberto e a referência para ele for perdida, pode ser que ele seja fechado pelo garbagecollector,queveremosmaisa frente,porcausadofinalize.Masnãoébomvocêseprenderaisso. Se você esquecer de fechar o arquivo, no caso de um programa minúsculo como esse, oprogramavaiterminarantesqueotaldogarbagecollectorteajude,resultandoemumarquivonãoescrito(osbytes ficaramnobufferdoBufferedWriter). Problemas similares podemacontecercomleitoresquenãoforemfechados.

No Java 7 há a estrutura try-with-resources, que já fará o finally cuidar dos recursosdeclarados dentro do try(), invocando close. Pra isso, os recursos devem implementar ainterfacejava.lang.AutoCloseable,queéocasodosReaders,WriterseStreamsestudadosaqui:

try(BufferedReaderbr=newBufferedReader(newFile("arquivo.txt"))){//comexceçãoounão,oclose()dobrserainvocado}

ApartirdoJava5,temosaclassejava.util.Scanner,quefacilitabastanteotrabalhodelerdeumInputStream.Alémdisso,aclassePrintStreampossuiumconstrutorquejárecebeonomedeumarquivo como argumento.Dessa forma, a leitura do teclado com saída para um arquivo ficoumuitosimples:

Scanners=newScanner(System.in);PrintStreamps=newPrintStream("arquivo.txt");while(s.hasNextLine()){ps.println(s.nextLine());}

NenhumdosmétodoslançaIOException:PrintStreamlançaFileNotFoundExceptionsevocêoconstruirpassandoumaString.EssaexceçãoéfilhadeIOExceptioneindicaqueoarquivonãofoiencontrado.OScanner considerará que chegou ao fim se umaIOException for lançada, mas oPrintStreamsimplesmenteengoleexceptionsdessetipo.Ambospossuemmétodosparavocêverificarsealgumproblemaocorreu.

16.6UMAMANEIRAMAISFÁCIL:SCANNEREPRINTSTREAM

.

Page 254: FJ-11 Java e Orientação a Objetos

AclasseScanner é dopacotejava.util. Ela possuimétodosmuitoúteis para trabalhar comStrings, em especial, diversos métodos já preparados para pegar números e palavras já formatadasatravésdeexpressõesregulares.Ficafácilparsearumarquivocomqualquerformatodado.

SYSTEM.OUT

Comovimosnocapítulopassado,oatributooutdaclasseSystemédotipoPrintStream(e,portanto,éumOutputStream).

EOF

Quando rodar sua aplicação, para encerrar a entrada de dados do teclado, é necessárioenviarmosumsinaldefimdestream.ÉofamosoEOF,istoé,endoffile.

NoLinux/Mac/Solaris/Unixvocêfazissocomoctrl+D.NoWindows,useoctrl+Z.

Existem duas classes chamadas java.io.FileReader e java.io.FileWriter. Elas sãoatalhosparaaleituraeescritadearquivos.

Odo{..}while(condicao);éumaalternativaparaseconstruirumlaço.Pesquise-oeutilize-ono códigopara ler umarquivo, ele vai ficarmais sucinto (vocênãoprecisará ler aprimeiralinhaforadolaço).

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelum eobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

16.7UMPOUCOMAIS...

EditoraCasadoCódigocomlivrosdeumaformadiferente

.

Page 255: FJ-11 Java e Orientação a Objetos

Anteriormente, vimos que conseguimos ler e escrever dados emum arquivono Java utilizando aclasseScanner. Por padrão, quando fazemos essas operações, estamos trabalhando sempre com osdadosemformadeString.Maseseprecisássemoslerouescrevernúmerosinteirosemumarquivo?ComofaríamosparatransformaressesnúmerosemStringevice-versa?

Cuidado!Usamosaquiotermo"transformar",porémoqueocorrenãoéumatransformaçãoentreos tipos e sim uma forma de conseguirmos umString dado umint e vice-versa. O jeito maissimplesdetransformarumnúmeroemStringéconcatená-lodaseguintemaneira:

inti=100;Strings=""+i;System.out.println(s);

doubled=1.2;Strings2=""+d;System.out.println(s2);

Para formatar o número de uma maneira diferente, com vírgula e número de casas decimaisdevemosutilizaroutrasclassesdeajuda(NumberFormat,Formatter).

ParatransformarumaStringemnúmero,utilizamosasclassesdeajudaparaostiposprimitivoscorrespondentes. Por exemplo, para transformar a Strings em um número inteiro utilizamos ométodoestáticodaclasseInteger:

Strings="101";inti=Integer.parseInt(s);

As classes Double, Short , Long , Float etc contêm o mesmo tipo de método, comoparseDoubleeparseFloatqueretornamumdoubleefloatrespectivamente.

Essas classes também sãomuito utilizadas para fazer owrapping (embrulho) de tipos primitivoscomo objetos, pois referências e tipos primitivos são incompatíveis. Imagine que precisamos passarcomoargumentouminteiroparaonossoguardadordeobjetos.UminteironãoéumObject,comofazer?

inti=5;Integerx=newInteger(i);guardador.adiciona(x);

E,dadoumInteger,podemospegarointqueestádentrodele(desembrulhá-lo):

inti=5;Integerx=newInteger(i);intnumeroDeVolta=x.intValue();

Esse processo de wrapping e unwrapping é entediante. O Java 5.0 em diante traz um recurso

16.8INTEGERECLASSESWRAPPERS(BOX)

16.9AUTOBOXINGNOJAVA5.0

.

Page 256: FJ-11 Java e Orientação a Objetos

chamadodeautoboxing,quefazissosozinhoparavocê,custandolegibilidade:

Integerx=5;inty=x;

NoJava1.4essecódigoéinválido.NoJava5.0emdianteelecompilaperfeitamente.Éimportanteressaltar que isso não quer dizer que tipos primitivos e referências sejam do mesmo tipo, isso ésimplesmenteum"açúcarsintático"(syntaxsugar)parafacilitaracodificação.

Vocêpodefazertodosostiposdeoperaçõesmatemáticascomoswrappers,porémcorreoriscodetomarumNullPointerException.

Vocêpode fazer o autoboxingdiretamenteparaObject também,possibilitandopassarum tipoprimitivoparaummétodoquereceberObjectcomoargumento:

Objecto=5;

NaclasseMath, existeumasériedemétodosestáticosque fazemoperaçõescomnúmeroscomo,por exemplo, arredondar(round), tirar o valor absoluto (abs), tirar a raiz(sqrt), calcular oseno(sin)eoutros.

doubled=4.6;longi=Math.round(d);

intx=-4;inty=Math.abs(x);

Consulteadocumentaçãoparaveragrandequantidadedemétodosdiferentes.

NoJava5.0,podemostirarproveitodoimportstaticaqui:

importstaticjava.lang.Math.*;

Issoeliminaanecessidadedeusaronomedaclasse,sobocustodelegibilidade:

doubled=4.6;longi=round(d);intx=-4;inty=abs(x);

16.10PARASABERMAIS:JAVA.LANG.MATH

.

Page 257: FJ-11 Java e Orientação a Objetos

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

Vamossalvarascontascadastradasemumarquivoparanãoprecisarficaradicionandoascontasatodomomento.

1. NaclasseManipuladorDeContas,crieométodosalvaDadosquerecebeumEvento de ondeobteremosalistadecontas:

publicvoidsalvaDados(Eventoevento){List<Conta>contas=evento.getLista("listaContas");//aquisalvaremosascontasemarquivo}

2. Para não colocarmos todo o código de gerenciamento de arquivos dentro da classeManipuladorDeContas,vamoscriarumanovaclassecujaresponsabilidadeserálidarcomaescrita/ leitura de arquivos. Crie a classe RepositorioDeContas dentro do pacotebr.com.caelum.contasedeclareométodosalvaquedeverárecebera listadecontasaseremguardadas.Nestemétodovocêdevepercorreralistadecontasesalvá-lasseparandoasinformaçõesdetipo,numero,agencia,titularesaldocomvírgulas.Ocódigoficaráparecidocom:

publicclassRepositorioDeContas{

publicvoidsalva(List<Conta>contas){PrintStreamstream=newPrintStream("contas.txt");for(Contaconta:contas){stream.println(conta.getTipo()+","+conta.getNumero()+","+conta.getAgencia()+","+conta.getTitular()+","+conta.getSaldo());}stream.close();}}

O compilador vai reclamar que você não está tratando algumas exceções (como

JáconheceoscursosonlineAlura?

16.11EXERCÍCIOS:JAVAI/O

.

Page 258: FJ-11 Java e Orientação a Objetos

java.io.FileNotFoundException). Utilize o devido try/catch e relance a exceção comoRuntimeException.UtilizeoquickfixdoEclipseparafacilitar(ctrl+1).

Vale lembrarquedeixar todasasexceptionspassaremdespercebidasnãoéumaboaprática!Vocêpodeusaraqui,poisestamosfocandoapenasnoaprendizadodautilizaçãodojava.io.

Quandotrabalhamoscomrecursosquefalamcomaparteexternaànossaaplicação,éprecisoqueavisemosquandoacabarmosdeusaressesrecursos.Porisso,éimportantíssimo lembrardefecharoscanaiscomoexteriorqueabrimosutilizandoométodoclose!

3. Voltando à classe ManipuladorDeContas, vamos completar o método salvaDados para queutilizeanossanovaclasseRepositorioDeContascriada.

publicvoidsalvaDados(Eventoevento){List<Conta>contas=evento.getLista("listaContas");RepositorioDeContasrepositorio=newRepositorioDeContas();repositorio.salva(contas);}

Rodesuaaplicação,cadastrealgumascontaseveja seapareceumarquivochamadocontas.txtdentrododiretóriosrcdeseuprojeto.TalvezsejanecessáriodarumF5neleparaqueoarquivoapareça.

4. (Opcional,Difícil)Vamos fazercomquealémdesalvarosdadosemumarquivo,nossaaplicaçãotambém consiga carregar as informações das contas para já exibir na tela. Para que a aplicaçãofuncione, é necessário que a nossa classe ManipuladorDeContas possua um método chamadocarregaDados que devolva uma List<Conta>. Vamos fazer o mesmo que anteriormente eencapsularalógicadecarregamentodentrodaclasseRepositorioDeContas:

publicList<Conta>carregaDados(){RepositorioDeContasrepositorio=newRepositorioDeContas();returnrepositorio.carrega();}

Faça o código referente ao método carrega que devolve uma List dentro da classeRepositorioDeContasutilizandoaclasseScanner.ParaobterosvaloresdecadaatributovocêpodeutilizarométodosplitdaString.Lembre-sequeosatributosdascontassãocarregadosnaseguinteordem:tipo,numero,agencia,titularesaldo.Exemplo:

Stringlinha=scanner.nextLine();String[]valores=linha.split(",");Stringtipo=valores[0];

Alémdisso,acontadeveserinstanciadadeacordocomoconteúdodotipoobtido.Tambémfiqueatentopois osdados lidos virão sempre lidos em formadeString e para alguns atributos seránecessáriotransformarodadonostiposprimitivoscorrespondentes.Porexemplo:

StringnumeroTexto=valores[1];intnumero=Integer.parseInt(numeroTexto);

.

Page 259: FJ-11 Java e Orientação a Objetos

5. (opcional) A classe Scanner é muito poderosa! Consulte seu javadoc para saber sobre odelimitereosoutrosmétodosnext.

6. (opcional) Crie uma classe TestaInteger e vamos fazer comparações com Integers dentro domain:

Integerx1=newInteger(10);Integerx2=newInteger(10);

if(x1==x2){System.out.println("igual");}else{System.out.println("diferente");}

Esetestarmoscomoequals?Oquepodemosconcluir?

7. (opcional)Umdoublenãoestásendosuficienteparaguardaraquantidadedecasasnecessáriasemumaaplicação.Precisoguardarumnúmerodecimalmuitogrande!Oquepoderiausar?

Odoubletambémtemproblemasdeprecisãoaofazercontas,porcausadearredondamentosdaaritméticadepontoflutuantedefinidopelaIEEE754:

http://en.wikipedia.org/wiki/IEEE_754

Elenãodeveserusadosevocêprecisarealmentedemuitaprecisão(casosqueenvolvamdinheiro,porexemplo).

Consulteadocumentação,tenteadivinharondevocêpodeencontrarumtipoqueteajudariapararesolveressescasosevejacomoéintuitivo!Qualéaclassequeresolveriaessesproblemas?

Lembre-se:noJavahámuitojápronto.Sejanabibliotecapadrão,sejaembibliotecasopensourcequevocêpodeencontrarpelainternet.

Aplicarbemosconceitosdeorientaçãoaobjetosé sempreumagrandedúvida.Semprequeremosencapsular direito, favorecer a flexibilidade, desacoplar classes, escrever código elegante e de fácilmanutenção.EouvimosfalarqueaOrientaçãoaObjetosajudaemtudoisso.

Mas,ondeusarherançadeformasaudável?Comousarinterfaces?Ondeopolimorfismomeajuda?Comoencapsulardireito?Classesabstratassãousadasemquesituações?

Muitos anos atrás, grandes nomes domundo da orientação a objetos perceberam que criar bonsdesigns orientados a objetos era um grande desafio para muitas pessoas. Perceberam que muitosproblemas de OO apareciam recorrentemente em vários projetos; e que as pessoas já tinham certas

16.12 DISCUSSÃO EM AULA: DESIGN PATTERNS E O TEMPLATEMETHOD

.

Page 260: FJ-11 Java e Orientação a Objetos

soluçõesparaessesproblemasclássicos(nemsempremuitoelegantes).

O que fizeram foi criar soluções padrões para problemas comuns na orientação a objetos, echamaramissodeDesignPatterns, ouPadrõesdeProjeto.Oconceitovinhadaarquiteturaondeeramuitocomumteressetipodesolução.E,em1994,ganhougrandepopularidadenacomputaçãocomolivroDesign Patterns: Elements of Reusable Object-Oriented Software, um catálogo com várias dessassoluções escrito por Erich Gamma, Ralph Johnson, Richard Helm e John Vlissides (a Gangue dosQuatro,GoF).

DesignPatterns tornou-sereferênciaabsolutanobomusodaorientaçãoaobjetos.Outrospadrõessurgiram depois, em outras literaturas igualmente consagradas. O conhecimento dessas técnicas éimprescindívelparaobomprogramador.

DiscutacomoinstrutorcomoDesignPatternsajudamaresolverproblemasdemodelagememsistemas orientados a objetos. Veja como Design Patterns são aplicados em muitos lugares dopróprioJava.

OinstrutorcomentarádoTemplateMethodemostraráocódigofontedométodoread()daclassejava.io.InputStream:

publicintread(byteb[],intoff,intlen)throwsIOException{if(b==null){thrownewNullPointerException();}elseif(off<0||len<0||len>b.length-off){thrownewIndexOutOfBoundsException();}elseif(len==0){return0;}

intc=read();if(c==-1){return-1;}

b[off]=(byte)c;

inti=1;try{for(;i<len;i++){c=read();if(c==-1){break;}b[off+i]=(byte)c;}}catch(IOExceptionee){}returni;}

Discuta em aula como esse método aplica conceitos importantes da orientação a objetos epromoveflexibilidadeeextensibilidade.

.

Page 261: FJ-11 Java e Orientação a Objetos

CAPÍTULO17

"Aprimeiracoisaaentenderéquevocênãoentende."--SorenAabyeKierkegaard

Ondecontinuarao terminarosexercíciosde 'JavaeOrientaçãoaObjetos'?Aquiháumpost comsugestõesdecomoiniciarnacarreira:

http://blog.caelum.com.br/como-posso-aprender-java-e-iniciar-na-carreira/

Evocêpodeseguirnessescursoseáreas:

UmdosprincipaisusosdoJavaérodaraplicaçõesweb.EntramaquitecnologiascomoServlets,JSPseferramentasfamosasdomercado,comooStruts.

A Caelum oferece o curso FJ-21, onde você pode estudar os tópicos necessários para começar atrabalharcomJavanawebusandoasmelhorespráticas,designpatternsetecnologiasdomercado.Essaapostilatambémestádisponívelparadownload.

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelum eobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

A melhor maneira para fixar tudo o que foi visto nos capítulos anteriores é planejar e montar

EAGORA?

17.1WEB

EditoraCasadoCódigocomlivrosdeumaformadiferente

17.2PRATICANDOJAVAEUSANDOBIBLIOTECAS

.

Page 262: FJ-11 Java e Orientação a Objetos

pequenos sistemas. Pense na modelagem de suas classes, como e onde usar herança, polimorfismo,encapsulamentoeoutrosconceitos.PratiqueousodasAPIsmaisúteisdo Java integrando-asao seussistemas.

O curso FJ-22 é um laboratório que alémde demonstrar o uso diversasAPIs e boas práticas, vaimostrardiversosdesignpatternseseuscasosdeuso.

Diversosprogramadorescomomínimooumáximodeconhecimentosereúnemonlineparaatrocadedúvidas,informaçõeseideiassobreprojetos,bibliotecasemuitomais.Sãoosgruposdeusuáriosdejava.

UmdosmaisimportanteseconhecidosnoBrasiléoGUJ:

http://www.guj.com.br

O'FalandoemJava'nãopáraporaqui.ACaelumofereceumagrandevariedadedecursosquevocêpodeseguir.Algunsdosmaisrequisitados:

FJ-21:JavaparadesenvolvimentoWeb

FJ-22:LaboratórioJavacomTestes,JSF,WebServiceseDesignPatterns

FJ-25:PersistênciacomJPA,HibernateeEJBlite

FJ-26:LaboratórioWebcomJSFeCDI

FJ-57:DesenvolvimentomóvelcomGoogleAndroid

FJ-91:ArquiteturaeDesigndeProjetosJava

Consulte mais informações no nosso site e entre em contato conosco. Conheça nosso mapa decursos:

http://www.caelum.com.br/mapa-dos-cursos/

17.3GRUPOSDEUSUÁRIOS

17.4PRÓXIMOSCURSOS

.

Page 263: FJ-11 Java e Orientação a Objetos

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

JáconheceoscursosonlineAlura?

.

Page 264: FJ-11 Java e Orientação a Objetos

CAPÍTULO18

"Oúnicolugarondeosucessovemantesdotrabalhoénodicionário."--AlbertEinstein

Aotérminodessecapítulo,vocêserácapazde:

executartarefassimultaneamente;colocartarefasparaaguardaratéqueumdeterminadoeventoocorra;entenderofuncionamentodoGarbageCollector.

Emvárias situações, precisamos "rodarduas coisas aomesmo tempo". ImagineumprogramaquegeraumrelatóriomuitograndeemPDF.Éumprocessodemoradoe,paradaralgumasatisfaçãoparaousuário,queremosmostrarumabarradeprogresso.QueremosentãogeraroPDFeaomesmotempoatualizarabarrinha.

Pensando um pouco mais amplamente, quando usamos o computador também fazemos váriascoisassimultaneamente:queremosnavegarnainterneteaomesmotempoouvirmúsica.

Anecessidadedesefazerváriascoisassimultaneamente,aomesmotempo,paralelamente,aparecefrequentemente na computação. Para vários programas distintos, normalmente o próprio sistemaoperacionalgerenciaissoatravésdeváriosprocessosemparalelo.

Em um programa só (um processo só), se queremos executar coisas em paralelo, normalmentefalamosdeThreads.

EmJava,usamosaclasseThreaddopacotejava.langparacriarmoslinhasdeexecuçãoparalelas.AclasseThreadrecebecomoargumentoumobjetocomocódigoquedesejamosrodar.Porexemplo,noprogramadePDFebarradeprogresso:

publicclassGeraPDF{

APÊNDICE-PROGRAMAÇÃOCONCORRENTEETHREADS

18.1THREADS

"Duastarefasaomesmotempo"

ThreadsemJava

.

Page 265: FJ-11 Java e Orientação a Objetos

publicvoidrodar(){//lógicaparageraropdf...}}

publicclassBarraDeProgresso{publicvoidrodar(){//mostrabarradeprogressoevaiatualizandoela...}}

E,nométodomain, criamososobjetosepassamosparaaclasseThread.Ométodostart éresponsávelporiniciaraexecuçãodaThread:

publicclassMeuPrograma{publicstaticvoidmain(String[]args){

GeraPDFgerapdf=newGeraPDF();ThreadthreadDoPdf=newThread(gerapdf);threadDoPdf.start();

BarraDeProgressobarraDeProgresso=newBarraDeProgresso();ThreadthreadDaBarra=newThread(barraDeProgresso);threadDaBarra.start();

}}

Ocódigoacima,porém,nãocompilará.ComoaclasseThread sabequedeve chamarométodoroda?Comoelasabequenomedemétododaremosequeeladevechamaressemétodoespecial?FaltanaverdadeumcontratoentreasnossasclassesaseremexecutadaseaclasseThread.

EssecontratoexisteeéfeitopelainterfaceRunnable:devemosdizerquenossaclasseé"executável"e que segue esse contrato. Na interface Runnable, há apenas um método chamado run. Bastaimplementá-lo,"assinar"ocontratoeaclasseThreadjásaberáexecutarnossaclasse.

publicclassGeraPDFimplementsRunnable{publicvoidrun(){//lógicaparageraropdf...}}

publicclassBarraDeProgressoimplementsRunnable{publicvoidrun(){//mostrabarradeprogressoevaiatualizandoela...}}

AclasseThread recebe no construtor umobjeto que éumRunnable, e seumétodo startchamaométodorundanossaclasse.ReparequeaclasseThreadnãosabequaléotipoespecíficodanossaclasse;paraela,bastasaberqueaclassesegueocontratoestabelecidoepossuiométodorun.

Éobomusodeinterfaces,contratosepolimorfismonaprática!

.

Page 266: FJ-11 Java e Orientação a Objetos

ESTENDENDOACLASSETHREAD

A classe Thread implementa Runnable . Então, você pode criar uma subclasse dela ereescreverorunque,naclasseThread,nãofaznada:

publicclassGeraPDFextendsThread{publicvoidrun(){//...}}

E,comonossaclasseéumaThread,podemosusarostartdiretamente:

GeraPDFgera=newGeraPDF();gera.start();

Apesar de ser um código mais simples, você está usando herança apenas por "preguiça"(herdamosummontedemétodosmasusamosapenasorun),enãoporpolimorfismo,queseriaagrandevantagem.PrefiraimplementarRunnableaherdardeThread.

DORMINDO

Paraque a threadatualdurmabasta chamarométodoa seguir,por exemplo,paradormir3segundos:

javaThread.sleep(3*1000);

.

Page 267: FJ-11 Java e Orientação a Objetos

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

Vejaaclasseaseguir:

publicclassProgramaimplementsRunnable{

privateintid;//colocargetteresetterproatributoid

publicvoidrun(){for(inti=0;i<10000;i++){System.out.println("Programa"+id+"valor:"+i);}}}

Éumaclasseque implementaRunnable e,nométodorun, apenas imprimedezmil números.Vamosusá-lasduasvezesparacriarduasthreadseimprimirosnúmerosduasvezessimultaneamente:

publicclassTeste{publicstaticvoidmain(String[]args){

Programap1=newPrograma();p1.setId(1);

Threadt1=newThread(p1);t1.start();

Programap2=newPrograma();p2.setId(2);

Threadt2=newThread(p2);t2.start();

SaberinglêsémuitoimportanteemTI

18.2ESCALONADORETROCASDECONTEXTO

.

Page 268: FJ-11 Java e Orientação a Objetos

}}

Serodarmosesseprograma,qual seráasaída?Deumamiledepoisdeumamil?Provavelmentenão, senão seria sequencial. Ele imprimirá 0 de t1, 0 de t2, 1 de t1, 1 de t2, 2 de t1, 2 de t2 e etc?Exatamenteintercalado?

Naverdade,não sabemos exatamentequal é a saída.Rodeoprogramavárias vezes eobserve: emcadaexecuçãoasaídaéumpoucodiferente.

Oproblemaéquenocomputadorexisteapenasumprocessadorcapazdeexecutarcoisas.Equandoqueremosexecutarváriascoisasaomesmotempo,eoprocessadorsóconseguefazerumacoisadecadavez?Entraemcenaoescalonadordethreads.

O escalonador (scheduler), sabendo que apenas uma coisa pode ser executada de cada vez, pegatodasas threadsqueprecisamser executadas e fazoprocessador ficar alternandoa execuçãodecadauma delas. A ideia é executar um pouco de cada thread e fazer essa troca tão rapidamente que aimpressãoqueficaéqueascoisasestãosendofeitasaomesmotempo.

Oescalonadoréresponsávelporescolherqualapróximathreadaserexecutadaefazeratrocadecontexto (context switch).Eleprimeiro salvaoestadodaexecuçãoda threadatualparadepoispoderretomar a execução da mesma. Aí ele restaura o estado da thread que vai ser executada e faz oprocessadorcontinuaraexecuçãodesta.Depoisdeumcertotempo,estathreadétiradadoprocessador,seuestado(ocontexto)ésalvoeoutrathreadécolocadaemexecução.Atrocadecontextoéjustamenteas operações de salvar o contexto da thread atual e restaurar o da thread que vai ser executada emseguida.

Quando fazer a troca de contexto, por quanto tempo a thread vai rodar e qual vai ser a próximathread a ser executada, são escolhas do escalonador. Nós não controlamos essas escolhas (emborapossamosdar"dicas"aoescalonador).Porissoquenuncasabemosaocertoaordememqueprogramasparalelossãoexecutados.

Vocêpodepensarqueéruimnãosaberaordem.Maspercebaqueseaordemimportaparavocê,seé importantequedeterminadacoisaseja feitaantesdeoutra,entãonãoestamos falandodeexecuçõesparalelas,massimdeumprogramasequencialnormal(ondeumacoisaéfeitadepoisdaoutra,emumasequência).

Todo esse processo é feito automaticamente pelo escalonador do Java (e,mais amplamente, peloescalonador do sistema operacional). Para nós, programadores das threads, é como se as coisasestivessemsendoexecutadasaomesmotempo.

.

Page 269: FJ-11 Java e Orientação a Objetos

EEMMAISDEUMPROCESSADOR?

AVMdoJavaeamaioriadosSOsmodernosconseguefazerproveitodesistemascomváriosprocessadoresoumulti-core.Adiferençaéqueagora temosmaisdeumprocessadorexecutandocoisaseteremos,sim,execuçõesverdadeiramenteparalelas.

MasonúmerodeprocessosnoSOeonúmerodeThreadsparalelascostumamsertãograndesque, mesmo com vários processadores, temos as trocas de contexto. A diferença é que oescalonadortemdoisoumaisprocessadoresparaexecutarsuasthreads.Masdificilmenteteráumamáquinacommaisprocessadoresquethreadsparalelasexecutando.

OGarbageCollector(coletordelixo, lixeiro)funcionacomoumaThread responsávelpor jogarfora todos os objetos que não estão sendo referenciados por nenhum outro objeto - seja demaneiradiretaouindireta.

Considereocódigo:

Contaconta1=newContaCorrente();Contaconta2=newContaCorrente();

Atéestemomento,sabemosquetemos2objetosemmemória.Aqui,oGarbageCollectornãopodeeliminarnenhumdosobjetos,poisaindatemalguémsereferindoaelesdealgumaforma.

Podemos, então, executar uma linha que nos faça perder a referência para um dos dois objetoscriados,como,porexemplo,oseguintecódigo:

conta2=conta1;

Quantosobjetostemosemmemória?

Perdemosareferênciaparaumdosobjetosqueforamcriados.Esseobjeto jánãoémaisacessível.Temos,então,apenasumobjetoemmemória?Nãopodemosafirmarisso!ComooGarbageCollectoréumaThread,vocênãotemgarantiadequandoelevairodar.Vocêsósabeque,emalgummomentonofuturo,aquelamemóriavaiserliberada.

Algumaspessoascostumamatribuirnullaumavariável,comointuitodeacelerarapassagemdoGarbageCollectorporaqueleobjeto:

for(inti=0;i<100;i++){Listx=newArrayList();//fazalgumascoisascomaarraylistx=null;}

18.3GARBAGECOLLECTOR

.

Page 270: FJ-11 Java e Orientação a Objetos

Isso rarissimamente é necessário. O Garbage Collector age apenas sobre objetos, nunca sobrevariáveis.Nessecaso,avariávelxnãoexistirámaisacadaiteração,deixandoaArrayListcriadasemnenhumareferênciaparaela.

SYSTEM.GC()

Vocênunca consegue forçar oGarbageCollector,mas chamandoométodo estáticogc daclasseSystem, você está sugerindo que a Virtual Machine rode o Garbage Collector naquelemomento.Sesuasugestãovaiseraceitaounão, istodependedeJVMparaJVM,evocênãotemgarantias. Evite o uso destemétodo.Você não deve basear sua aplicação em quando oGarbageCollectorvairodarounão.

FINALIZER

A classe Object define também ummétodo finalize, que você pode reescrever. Essemétodo será chamado no instante antes do Garbage Collector coletar este objeto. Não é umdestrutor, você não sabe em quemomento ele será chamado. Algumas pessoas o utilizam paraliberar recursos "caros"comoconexões, threadse recursosnativos. Issodeve serutilizadoapenasporsegurança:oidealéliberaressesrecursosomaisrápidopossível,semdependerdapassagemdoGarbageCollector.

1. Testeoexemplodestecapítuloparaimprimirnúmerosemparalelo.

EscrevaaclassePrograma:

publicclassProgramaimplementsRunnable{

privateintid;//colocargetteresetterproatributoid

publicvoidrun(){for(inti=0;i<10000;i++){System.out.println("Programa"+id+"valor:"+i);}}}

EscrevaaclassedeTeste:

publicclassTeste{publicstaticvoidmain(String[]args){

18.4EXERCÍCIOS

.

Page 271: FJ-11 Java e Orientação a Objetos

Programap1=newPrograma();p1.setId(1);

Threadt1=newThread(p1);t1.start();

Programap2=newPrograma();p2.setId(2);

Threadt2=newThread(p2);t2.start();

}}

RodeváriasvezesaclasseTesteeobserveosdiferentesresultadosemcadaexecução.Oquemuda?

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

É comum aparecer uma classe anônima junto com uma thread. Vimos como usá-la com oComparator.VamosvercomousaremumRunnable.

ConsidereumRunnablesimples,queapenasmandaimprimiralgonasaídapadrão:

publicclassPrograma1implementsRunnable{publicvoidrun(){for(inti=0;i<10000;i++){System.out.println("Programa1valor:"+i);}}}

Noseumain,vocêfaz:

AprendasedivertindonaAluraStart!

18.5EASCLASSESANÔNIMAS?

.

Page 272: FJ-11 Java e Orientação a Objetos

Runnabler=newPrograma1();Threadt=newThread(r);t.start();

Em vez de criar essa classe Programa1, podemos utilizar o recurso de classe anônima. Ela nospermitedarnewnumainterface,desdequeimplementemosseusmétodos.Comisso,podemoscolocardiretamentenomain:

Runnabler=newRunnable(){publicvoidrun(){for(inti=0;i<10000;i++)System.out.println("programa1valor"+i);}};Threadt=newThread(r);t.start();

LIMITAÇÕESDASCLASSESANÔNIMAS

O uso de classes anônimas tem limitações. Não podemos declarar um construtor. Comoestamosinstanciandoumainterface,entãonãoconseguimospassarumparâmetroparaela.Comoentão passar o id como argumento? Você pode, de dentro de uma classe anônima, acessaratributos da classe dentro da qual foi declarada! Também pode acessar as variáveis locais dométodo,desdequeelessejamfinal.

Dá para ir mais longe com o Java 8, utilizando o lambda. Como Runnable é uma interfacefuncional(contémapenasummétodoabstrato),elapodeserfacilmenteescritadessaforma:

Runnabler=()->{for(inti=0;i<10000;i++)System.out.println("programa1valor"+i);};Threadt=newThread(r);t.start();

A sintaxepode serumpouco estranha.Comonãoháparâmetros a serem recebidospelométodorun, usamoso() para indicar isso.Vale lembrar,maisumavez, queno lambdanãoprecisamosescreveronomedométodoqueestamos implementando,nonossocasoorun. Isso é possível poisexisteapenasummétodoabstratonainterface.

Querdeixarocódigomaisenxutoainda?PodemospassarolambdadiretamenteparaoconstrutordeThread,semcriarumavariáveltemporária!Elogoemseguidachamarostart:

newThread(()->{for(inti=0;i<10000;i++)System.out.println("programa1valor"+i);}).start();

EcomlambdadoJava8?

.

Page 273: FJ-11 Java e Orientação a Objetos

Obviamente o uso excessivo de lambdas e classes anônimas pode causar uma certa falta delegibilidade.Você deve lembrar que usamos esses recursos para escrever códigosmais legíveis, e nãoapenas para poupar algumas linhas de código.Caso nossa implementação do lambda venha a ser deváriaslinhas,éumfortesinaldequedeveríamosterumaclasseapartesomenteparaela.

.

Page 274: FJ-11 Java e Orientação a Objetos

CAPÍTULO19

"Olhoporolho,eomundoacabarácego."--MohandasGandhi

Conectando-seamáquinasremotas.

Nestecapítulo,vocêvaiconheceraAPIdeSocketsdojavapelopacotejava.net.

Mais útil que conhecer a API, é você perceber que estamos usando, aqui, todos os conceitos ebibliotecas aprendidas durante os outros capítulos. Repare, também, que é relativamente simplesaprenderautilizarumaAPI,agoraquetemostodososconceitosnecessáriosparatal.

Lembre-sedefazeresseapêndicecomojavadocabertoaoseulado.

AAlura oferece centenasdecursosonline em suaplataforma exclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design & UX, Infra e Business, com um plano que dá acesso a todos os cursos. Ex aluno daCaelumtem15%dedescontonestelink!

ConheçaoscursosonlineAlura.

Da necessidade de dois computadores se comunicarem, surgiram diversos protocolos quepermitissemtaltrocadeinformação:oprotocoloquevamosusaraquiéoTCP(TransmissionControlProtocol).

AtravésdoTCP,épossívelcriarumfluxoentredoiscomputadores-comoémostradonodiagrama

APÊNDICE-SOCKETS

19.1MOTIVAÇÃO:UMAAPIQUEUSAOSCONCEITOSAPRENDIDOS

JáconheceoscursosonlineAlura?

19.2PROTOCOLO

.

Page 275: FJ-11 Java e Orientação a Objetos

abaixo:

É possível conectarmais de um cliente aomesmo servidor, como é o caso de diversos banco dedados,servidoresWeb,etc.

Ao escrever um programa em Java que se comunique com outra aplicação, não é necessário sepreocupar com um nível tão baixo quanto o protocolo. As classes que trabalham com eles já foramdisponibilizadasparaseremusadaspornósnopacotejava.net.

A vantagemde se usar TCP, em vez de criar nosso próprio protocolo de bytes, é que oTCP vaigarantir a entrega dos pacotes que transferirmos e criar um protocolo base para isto é algo bemcomplicado.

Acabamosdemencionarquediversoscomputadorespodemseconectaraumsó,mas,narealidade,émuito comum encontrarmáquinas clientes com uma só conexão física. Então, como é possível seconectaradoispontos?Comoépossívelserconectadopordiversospontos?

Todas as aplicações que estão enviando e recebendodados fazem isso através damesma conexãofísica, mas o computador consegue discernir, durante a chegada de novos dados, quais informaçõespertencemaqualaplicação.Mascomo?

19.3PORTA

.

Page 276: FJ-11 Java e Orientação a Objetos

AssimcomoexisteoIPparaidentificarumamáquina,aportaéasoluçãoparaidentificardiversasaplicaçõesemumamáquina.Estaportaéumnúmerode2bytes,variade0a65535.Setodasasportasdeumamáquinaestiveremocupadas,nãoépossívelseconectaraelaenquantonenhumaforliberada.

Ao configurar um servidor para rodar na porta 80 (padrão http), é possível se conectar a esseservidoratravésdessaportaque, juntocomo ip, vai formaro endereçodaaplicação.Por exemplo,oservidorwebdacaelum.com.brpodeserrepresentadopor:caelum.com.br:80

Masseumclienteseconectaaumprogramarodandonaporta80deumservidor,enquantoelenãosedesconectardessaporta,seráimpossívelqueoutrapessoaseconecte?

Acontece que, ao efetuar e aceitar a conexão, o servidor redireciona o cliente de uma porta paraoutra,liberandonovamentesuaportainicialepermitindoqueoutrosclientesseconectemnovamente.

EmJava,issodeveserfeitoatravésdethreadseoprocessodeaceitaraconexãodeveserrodadoomaisrápidopossível.

19.4SOCKET

.

Page 277: FJ-11 Java e Orientação a Objetos

NaAlura Língua você reforça e aprimora seuinglês! Usando a técnica Spaced Repetitions oaprendizado naturalmente se adapta ao seuconhecimento. Exercícios e vídeos interativosfazem com que você pratique em situações

cotidianas. Além disso, todas as aulas possuem explicações gramaticais, para você entendercompletamente o que está aprendendo. Aprender inglês é fundamental para o profissional detecnologiadesucesso!

PratiqueseuinglêsnaAluraLíngua.

Iniciandoummodelodeservidordechat,oserviçodocomputadorquefuncionacomobasedeve,primeiro,abrirumaportaeficarouvindoatéalguémtentarseconectar.

importjava.net.*;

publicclassServidor{publicstaticvoidmain(String[]args)throwsIOException{

ServerSocketservidor=newServerSocket(12345);System.out.println("Porta12345aberta!");//acontinuaçãodoservidordeveserescritaaqui

}}

Seoobjeto for realmente criado, significaque aporta 12345 estava fechada e foi aberta. Seoutroprogramapossuiocontroledestaportanesteinstante,énormalqueonossoexemplonãofuncione,poiselenãoconsegueutilizarumaportaquejáestáemuso.

Após abrir a porta, precisamos esperar por um cliente através do método accept daServerSocket.Assimqueumclienteseconectar,oprogramacontinuará,porissodizemosqueessemétodoéblocante,seguraathreadatéquealgoonotifique.

Socketcliente=servidor.accept();System.out.println("Novaconexãocomocliente"+cliente.getInetAddress().getHostAddress());//imprimeoipdocliente

Porfim,bastalertodasasinformaçõesqueoclientenosenviar:

SaberinglêsémuitoimportanteemTI

19.5SERVIDOR

.

Page 278: FJ-11 Java e Orientação a Objetos

Scannerscanner=newScanner(cliente.getInputStream());

while(scanner.hasNextLine()){System.out.println(scanner.nextLine());}

Fechamosasconexões,começandopelofluxo:

in.close();cliente.close();servidor.close();

Oresultadoéaclasseaseguir:

publicclassServidor{publicstaticvoidmain(String[]args)throwsIOException{ServerSocketservidor=newServerSocket(12345);System.out.println("Porta12345aberta!");

Socketcliente=servidor.accept();System.out.println("Novaconexãocomocliente"+cliente.getInetAddress().getHostAddress());

Scanners=newScanner(cliente.getInputStream());while(s.hasNextLine()){System.out.println(s.nextLine());}

s.close();servidor.close();cliente.close();}}

Anossatarefaécriarumprogramaclientequeenviemensagensparaoservidor...oclienteéaindamaissimplesdoqueoservidor.

O código a seguir é a parte principal e tenta se conectar a um servidorno IP 127.0.0.1 (máquinalocal)eporta12345:

Socketcliente=newSocket("127.0.0.1",12345);System.out.println("Oclienteseconectouaoservidor!");

Queremoslerosdadosdocliente,daentradapadrão(teclado):

Scannerteclado=newScanner(System.in);while(teclado.hasNextLine()){//lêalinhaefazalgocomela}

Bastaleraslinhasqueousuáriodigitaratravésdobufferdeentrada(in),e jogá-lasnobufferdesaída:

PrintStreamsaida=newPrintStream(cliente.getOutputStream());

19.6CLIENTE

.

Page 279: FJ-11 Java e Orientação a Objetos

Scannerteclado=newScanner(System.in);while(teclado.hasNextLine()){saida.println(teclado.nextLine());}saida.close();teclado.close();

Reparequeusamosos conceitodejava.io aquinovamente, para leiturado teclado e enviodemensagensparaoservidor.ParaasclassesScannerePrintStream, tantofazdeondequese lêouescreveosdados:oimportanteéqueessestreamsejaumInputStream/OutputStream.Éopoderdasinterfaces,dopolimorfismo,aparecendonovamente.

Nossoprogramafinal:

publicclassCliente{publicstaticvoidmain(String[]args)throwsUnknownHostException,IOException{Socketcliente=newSocket("127.0.0.1",12345);System.out.println("Oclienteseconectouaoservidor!");

Scannerteclado=newScanner(System.in);PrintStreamsaida=newPrintStream(cliente.getOutputStream());

while(teclado.hasNextLine()){saida.println(teclado.nextLine());}

saida.close();teclado.close();cliente.close();}}

Paratestarosistema,precisamosrodarprimeirooservidore,logodepois,ocliente.Tudooquefordigitadonoclienteseráenviadoparaoservidor.

.

Page 280: FJ-11 Java e Orientação a Objetos

MULTITHREADING

Paraqueoservidorsejacapazdetrabalharcomdoisclientesaomesmotempoénecessáriocriarumathreadlogoapósexecutarométodoaccept.

A threadcriadaseráresponsávelpelo tratamentodessaconexão,enquantoo laçodoservidordisponibilizaráaportaparaumanovaconexão:

while(true){

Socketcliente=servidor.accept();

//criaumobjetoquevaitrataraconexãoTratamentoClasstratamento=newTratamentoClass(cliente);

//criaathreademcimadesteobjetoThreadt=newThread(tratamento);

//iniciaathreadt.start();

}

AsocketdoclientetemumInputStream,querecebedoOutputStreamdoservidor,e temumOutputStream, que transfere tudo para o InputStream do servidor. Muito parecido com umtelefone!

Reparequeclienteeservidorsãorótulosqueindicamumestado.Ummicro(oumelhor,umaJVM)podeserservidornumcaso,maspodeserclienteemoutrocaso.

19.7IMAGEMGERAL

.

Page 281: FJ-11 Java e Orientação a Objetos

Você conhece alguém que tem potencial paratecnologia e programação, mas que nuncaescreveuumalinhadecódigo?Podeserumfilho,sobrinho, amigo ou parente distante. NaAlura

Start ela vai poder criar games, apps, sites e muito mais! É o começo da jornada comprogramaçãoeaportadeentradaparaumapossívelcarreiradesucesso.Elavaiestudaremseupróprioritmoecomamelhordidática.AqualidadedaconceituadaAlura,agoraparaStarters.

ConheçaoscursosonlinedaAluraStart!

1. Crieumprojetosockets.

Vamosfazerumpequenosistemaemquetudoqueédigitadonomicroclienteacabaaparecendonomicroservidor.Istoé,apenasumacomunicaçãounidirecional.

CrieaclasseServidorcomovimosnessecapítulo.AbusedosrecursosdoEclipseparanãoterdeescrevermuito!

packagebr.com.caelum.chat;

importjava.io.IOException;importjava.net.ServerSocket;importjava.net.Socket;importjava.util.Scanner;

publicclassServidor{publicstaticvoidmain(String[]args)throwsIOException{ServerSocketservidor=newServerSocket(12345);System.out.println("Porta12345aberta!");

Socketcliente=servidor.accept();System.out.println("Novaconexãocomocliente"+cliente.getInetAddress().getHostAddress());

Scannerentrada=newScanner(cliente.getInputStream());while(entrada.hasNextLine()){System.out.println(entrada.nextLine());}

entrada.close();servidor.close();}}

AprendasedivertindonaAluraStart!

19.8EXERCÍCIOS:SOCKETS

.

Page 282: FJ-11 Java e Orientação a Objetos

2. CrieaclasseClientecomovistaanteriormente:

packagebr.com.caelum.chat;

importjava.io.IOException;importjava.io.PrintStream;importjava.net.Socket;importjava.net.UnknownHostException;importjava.util.Scanner;

publicclassCliente{publicstaticvoidmain(String[]args)throwsUnknownHostException,IOException{Socketcliente=newSocket("127.0.0.1",12345);System.out.println("Oclienteseconectouaoservidor!");

Scannerteclado=newScanner(System.in);PrintStreamsaida=newPrintStream(cliente.getOutputStream());

while(teclado.hasNextLine()){saida.println(teclado.nextLine());}

saida.close();teclado.close();}}

Utilizedosquickfixesecontrolespaçoparaosimportseothrows.

3. RodeaclasseServidor:reparenoconsoledoEclipsequeoprogramaficaesperando.RodeaclasseCliente:aconexãodeveserfeitaeoEclipsedevemostrarosdoisconsolesparavocê(existeumpequenoíconenaviewdeConsoleparavocêalternarentreeles).

Digitemensagensnoclienteevejaseelasaparecemcorretamentenoservidor.

4. Testeseuprogramacomumcolegadocurso,usandocomunicaçãoremotaentreasduasmáquinas.Combinementresiquemvairodaroclienteequemvairodaroservidor.Quemforrodaroclientedeve editar o IP na classe para indicar o endereço da outramáquina (verifique também se estãoacessandoamesmaporta).

DESCOBRINDOOIPDAMÁQUINA

NoWindows,abraoconsoleedigiteipconfigparasaberqualéoseuIP.NoLinux(ounoBSD,Mac,Solaris),vánoconsoleedigiteifconfig.

5. (opcional)Esevocêquisesse,emvezdeenviartudooqueoclientedigitou,transferirumarquivotextodomicrodoclienteparaservidor?Seriadifícil?

Abusedopolimorfismo!Façaocliente lerdeumarquivochamadoarquivo.txt (crie-o!)e faça

.

Page 283: FJ-11 Java e Orientação a Objetos

comqueoservidorgravetudoquerecebenumarquivoquechamarecebido.txt.

Quandooservidoraceitaumclientecomachamadaaoaccept, ele poderia chamarnovamenteeste método para aceitar um novo cliente. E, se queremos aceitar vários clientes, simultâneos, bastachamaroacceptváriasvezesetratarcadaclienteemsuaprópriaThread(senãoométodoacceptnãoseráinvocadonovamente!).

UmesboçodesoluçãoparaaclasseServidor:

ServerSocketservidor=newServerSocket(12345);

//servidorficaeternamenteaceitandoclientes...while(true){Socketcliente=servidor.accept();//disparaumaThreadquetrataesseclienteejáesperaopróximo}

[TODO:serialegalessasoluçãoparcialparaapenasessaparte!]

Agora que vários clientes podemmandar mensagens, gostaríamos que os clientes recebessem asmensagensenviadaspelasoutraspessoas.Aoinvésdoservidorsimplesmenteescreverasmensagensnoconsole,eledevemandarcadamensagemparatodososclientesconectados.

Precisamosmanterumalistadeclientesconectadose,quandochegarumamensagem(dequalquercliente),percorremosessalistaemandamosparatodos.

UseumListparaguardarosPrintStreamsdosclientes.Logodepoisqueoservidoraceitarumcliente novo, crie um PrintStream usando o OutputStream dele e adicione na lista. E, quandoreceberumamensagemnova,enviaparatodosnalista.

Umesboço:

Adicionandonalista:

while(true){Socketcliente=servidor.accept();this.lista.add(newPrintStream(cliente.getOutputStream()));

//disparaumaThreadquetrataesseclienteejáesperaopróximo}

Métodoquedistribuiasmensagens:

voiddistribuiMensagem(Stringmsg){for(PrintStreamcliente:lista){cliente.println(msg);

19.9DESAFIO:MÚLTIPLOSCLIENTES

19.10DESAFIO:BROADCASTDASMENSAGENS

.

Page 284: FJ-11 Java e Orientação a Objetos

}}

Masnossoclientetambémrecebemensagens.EntãoprecisamosfazercomqueoCliente,alémdelermensagensdotecladoeenviarparaoservidor,simultaneamentetambémpossarecebermensagensdeoutrosclientesenviadaspeloservidor.

Ouseja,precisamosdeumasegundaThreadnaclasseClientequeficarecebendomensagensdoInputStreamdoservidoreimprimindonoconsole.

Umesboço:

Scannerservidor=newScanner(cliente.getInputStream());while(servidor.hasNextLine()){System.out.println(servidor.nextLine());}

Lembre que você precisará de no mínimo 2 threads para o cliente e 2 para o servidor. Entãoprovavelmentevocêvaiterqueescrever4classes.

Melhoriaspossíveis:

Façacomoaprimeiralinhaenviadapeloclientesejasempreonickdele.Equandooservidorenviaramensagem,façaeleenviaronickdecadaclienteantesdamensagem.

Equandoumclientedesconectar?Comoretirá-lodalista?

Édifícil fazeroenviodearquivospelonossosistemadechats?Sabendoquea leituradeumarquivo é feita pelo FileInputStream , seria difícil mandar esse InputStream peloOutputStreamdaconexãoderede?

Conheça a Casa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Com a curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

19.11SOLUÇÃODOSISTEMADECHAT

.

Page 285: FJ-11 Java e Orientação a Objetos

Umasoluçãoparao sistemadechatcliente-servidorcommúltiplosclientespropostonosdesafiosacima. Repare que a solução não está nem um pouco elegante: o main já faz tudo, além de nãotratarmosasexceptions.OcódigovisaapenasmostrarousodeumaAPI.Éumapéssimapráticacolocartodaafuncionalidadedoseuprogramanomainetambémdejogarexceçõesparatrás.

Nestalistagem,faltamosdevidosimports.

Primeiro, as duas classes para o cliente. Repare que a única mudança grande é a classe nova,Recebedor:

publicclassCliente{publicstaticvoidmain(String[]args)throwsUnknownHostException,IOException{//disparaclientenewCliente("127.0.0.1",12345).executa();}

privateStringhost;privateintporta;

publicCliente(Stringhost,intporta){this.host=host;this.porta=porta;}

publicvoidexecuta()throwsUnknownHostException,IOException{Socketcliente=newSocket(this.host,this.porta);System.out.println("Oclienteseconectouaoservidor!");

//threadpararecebermensagensdoservidorRecebedorr=newRecebedor(cliente.getInputStream());newThread(r).start();

//lêmsgsdotecladoemandaproservidorScannerteclado=newScanner(System.in);PrintStreamsaida=newPrintStream(cliente.getOutputStream());while(teclado.hasNextLine()){saida.println(teclado.nextLine());}

saida.close();teclado.close();cliente.close();}}

publicclassRecebedorimplementsRunnable{

privateInputStreamservidor;

publicRecebedor(InputStreamservidor){this.servidor=servidor;}

publicvoidrun(){//recebemsgsdoservidoreimprimenatelaScanners=newScanner(this.servidor);while(s.hasNextLine()){System.out.println(s.nextLine());

.

Page 286: FJ-11 Java e Orientação a Objetos

}}}

JáoServidorsofreubastantemodificações.AclasseTrataClienteéaresponsávelporcuidardecadaclienteconectadonosistema:

publicclassServidor{

publicstaticvoidmain(String[]args)throwsIOException{//iniciaoservidornewServidor(12345).executa();}

privateintporta;privateList<PrintStream>clientes;

publicServidor(intporta){this.porta=porta;this.clientes=newArrayList<PrintStream>();}

publicvoidexecuta()throwsIOException{ServerSocketservidor=newServerSocket(this.porta);System.out.println("Porta12345aberta!");

while(true){//aceitaumclienteSocketcliente=servidor.accept();System.out.println("Novaconexãocomocliente"+cliente.getInetAddress().getHostAddress());

//adicionasaidadoclienteàlistaPrintStreamps=newPrintStream(cliente.getOutputStream());this.clientes.add(ps);

//criatratadordeclientenumanovathreadTrataClientetc=newTrataCliente(cliente.getInputStream(),this);newThread(tc).start();}

}

publicvoiddistribuiMensagem(Stringmsg){//enviamsgparatodomundofor(PrintStreamcliente:this.clientes){cliente.println(msg);}}}

publicclassTrataClienteimplementsRunnable{

privateInputStreamcliente;privateServidorservidor;

publicTrataCliente(InputStreamcliente,Servidorservidor){this.cliente=cliente;this.servidor=servidor;}

.

Page 287: FJ-11 Java e Orientação a Objetos

publicvoidrun(){//quandochegarumamsg,distribuipratodosScanners=newScanner(this.cliente);while(s.hasNextLine()){servidor.distribuiMensagem(s.nextLine());}s.close();}}

.

Page 288: FJ-11 Java e Orientação a Objetos

CAPÍTULO20

"Quempoucopensa,engana-semuito."--LeonardodaVinci

OusodeThreadscomeçaaficarinteressanteecomplicadoquandoprecisamoscompartilharobjetosentreváriasThreads.

Imagineaseguintesituação: temosumBancocommilhõesdeContasBancárias.Clientessacamedepositamdinheiro continuamente, 24 horas por dia.No primeiro dia de cadamês, o Banco precisaatualizar o saldo de todas as Contas de acordo com uma taxa específica. Para isso, ele utiliza oAtualizadorDeContasquevimosanteriormente.

OAtualizadorDeContas,basicamente,pegaumaaumacadaumadasmilhõesdecontasechamaseumétodoatualiza.Aatualizaçãodemilhõesdecontaséumprocessodemorado,quedurahoras;éinviávelpararobancoportantotempoatéqueasatualizaçõestenhamcompletado.Éprecisoexecutarasatualizaçõesparalelamenteàsatividades,dedepósitosesaques,normaisdobanco.

Ouseja,teremosváriasthreadsrodandoparalelamente.Emumathread,pegamostodasascontasevamoschamandoométodoatualizadecadauma.Emoutra,podemosestarsacandooudepositandodinheiro.Estamoscompartilhandoobjetosentremúltiplasthreads(ascontas,nonossocaso).

Imagineaseguintepossibilidade(mesmoquemuitoremota):noexatoinstanteemqueoatualizadorestáatualizandoumaContaX,oclientedonodestaContaresolveefetuarumsaque.Comosabemos,aotrabalharcomThreads,oescalonadorpodepararumacertaThreadaqualquer instanteparaexecutaroutra,evocênãotemcontrolesobreisso.

VejaessaclasseConta:

publicclassConta{

privatedoublesaldo;

//outrosmétodoseatributos...

publicvoidatualiza(doubletaxa){doublesaldoAtualizado=this.saldo*(1+taxa);

APÊNDICE-PROBLEMASCOMCONCORRÊNCIA

20.1THREADSACESSANDODADOSCOMPARTILHADOS

.

Page 289: FJ-11 Java e Orientação a Objetos

this.saldo=saldoAtualizado;}

publicvoiddeposita(doublevalor){doublenovoSaldo=this.saldo+valor;this.saldo=novoSaldo;}}

ImagineumaContacomsaldode100reais.Umclienteentranaagênciaefazumdepósitode1000reais.IssodisparaumaThreadnobancoquechamaométododeposita();elecomeçacalculandoonovoSaldo que passa a ser 1100 (linha 13). Só que por algum motivo que desconhecemos, oescalonadorpáraessathread.

Nesteexatoinstante,elecomeçaaexecutarumaoutraThreadquechamaométodoatualizadamesmaConta,porexemplo,comtaxade1%.IssoquerdizerqueonovoSaldopassaavaler101reais(linha8).E,nesseinstanteoescalonadortrocadeThreadsnovamente.Eleexecutaalinha14naThreadquefaziaodepósito;osaldopassaavaler1100.Acabandoodeposita,oescalonadorvoltapraThreaddoatualizaeexecutaalinha9,fazendoosaldovaler101reais.

Resultado:odepósitodemilreaisfoitotalmenteignoradoeseuClienteficarápoucofelizcomisso.Perceba quenão é possível detectar esse erro, já que todo o código foi executadoperfeitamente, semproblemas.Oproblema,aqui,foioacessosimultâneodeduasThreadsaomesmoobjeto.

EoerrosóocorreuporqueoescalonadorparounossasThreadsnaquelesexatos lugares.Podeserquenossocódigofiquerodando1anosemdarproblemaalgumeemumbelodiaoescalonadorresolvealternar nossas Threads daquela forma. Não sabemos como o escalonador se comporta! Temos queprotegernossocódigocontraesse tipodeproblema.Dizemosqueessaclassenãoé threadsafe, issoé,nãoestáprontaparaterumainstânciautilizadaentreváriasthreadsconcorrentemente.

OquequeríamoseraquenãofossepossívelalguématualizaraContaenquantooutrapessoaestádepositandoumdinheiro.QueríamosqueumaThreadnãopudessemexeremumaConta enquantooutraThreadestámexendonela.Nãohácomoimpediroescalonadordefazertalescolha.Então,oquefazer?

.

Page 290: FJ-11 Java e Orientação a Objetos

Conheça a Casa do Código, uma nova editora, com autores de destaque nomercado, foco em ebooks (PDF, epub, mobi), preços imbatíveis e assuntosatuais.Com a curadoria daCaelum e excelentes autores, é uma abordagemdiferenteparalivrosdetecnologianoBrasil.

CasadoCódigo,LivrosdeTecnologia.

Uma ideia seria criar uma trava e, no momento em que uma Thread entrasse em um dessesmétodos,ela trancariaaentradacomumachave.Dessamaneira,mesmoquesendocolocadade lado,nenhumaoutraThreadpoderiaentrarnessesmétodos,poisachaveestariacomaoutraThread.

Essaideiaéchamadaderegiãocrítica.Éumpedaçodecódigoquedefinimoscomocríticoequenãopodeserexecutadoporduasthreadsaomesmotempo.Apenasumathreadporvezconsegueentraremalgumaregiãocrítica.

PodemosfazerissoemJava.Podemosusarqualquerobjetocomoumlock(trava,chave),parapodersincronizar em cimadesse objeto, isto é, se umaThread entrar emumbloco que foi definido comosincronizadoporesse lock,apenasumaThreadpoderáestar ládentroaomesmotempo,poisachaveestarácomela.

Apalavrachavesynchronizeddáessacaracterísticaaumblocodecódigoerecebequaléoobjetoqueseráusadocomochave.AchavesóédevolvidanomomentoemqueaThreadquetinhaessachavesair do bloco, seja por return ou disparo de uma exceção (ou ainda na utilização do métodowait())..

Queremos,então,bloquearoacessosimultâneoaumamesmaConta:

publicclassConta{

privatedoublesaldo;

//outrosmétodoseatributos...

publicvoidatualiza(doubletaxa){synchronized(this){doublesaldoAtualizado=this.saldo*(1+taxa);this.saldo=saldoAtualizado;

Seuslivrosdetecnologiaparecemdoséculopassado?

20.2CONTROLANDOOACESSOCONCORRENTE

.

Page 291: FJ-11 Java e Orientação a Objetos

}}

publicvoiddeposita(doublevalor){synchronized(this){doublenovoSaldo=this.saldo+valor;this.saldo=novoSaldo;}}}

Observeousodosblocossynchronized dentrodosdoismétodos.Eles bloqueiamumaThreadutilizandoomesmoobjetoConta,othis.

Essesmétodossãomutuamenteexclusivosesóexecutamdemaneiraatômica.Threadsquetentampegarumlockquejáestápego,ficarãoemumconjuntoespecialesperandopelaliberaçãodolock(nãonecessariamentenumafila).

SINCRONIZANDOOBLOCOINTEIRO

Écomumsempresincronizarmosummétodointeiro,normalmenteutilizandoothis.

publicvoidmetodo(){synchronized(this){//conteúdodometodo}}

Paraestemesmoefeito,existeumasintaxemaissimples,ondeosynchronizedpodeserusadocomomodificadordométodo:

publicsynchronizedvoidmetodo(){//conteúdodometodo}

MAISSOBRELOCKS,MONITORESECONCORRÊNCIA

Se ométodo for estático, será sincronizado usando o lock do objeto que representa a classe(NomeDaClasse.class).

Alémdisso,opacotejava.util.concurrent,conhecidocomoJUC,entrounoJava5.0parafacilitarumasériedetrabalhoscomunsquecostumamapareceremumaaplicaçãoconcorrente.

Essepacoteajudaatémesmocriarthreadsepooldethreads,atravésdosExecutors.

20.3VECTOREHASHTABLE

.

Page 292: FJ-11 Java e Orientação a Objetos

Duas collections muito famosas são Vector e Hashtable, a diferença delas com suas irmãsArrayListeHashMapéqueasprimeirassãothreadsafe.

Vocêpodeseperguntarporquenãousamossempreessasclassesthreadsafe.Adquirirumlocktemumcusto,ecasoumobjetonãováserusadoentrediferentesthreads,nãoháporqueusaressasclassesqueconsomemmaisrecursos.Masnemsempreéfácilenxergarsedevemossincronizarumbloco,ousedevemosutilizarblocossincronizados.

Antigamenteocustodeseusar lockseraaltíssimo,hojeemdia issocustapoucoparaaJVM,masnãoémotivoparavocêsincronizartudosemnecessidade.

VocêpodemudaraprioridadedecadaumadesuasThreads,masistotambéméapenasumasugestãoaoescalonador.

ExisteummétodostopnasThreads,porquenãoéboapráticachamá-lo?

Um tópicomais avançado é a utilização dewait,notifiy e notifyAll para que asThreadscomuniquem-sedeeventosocorridos,indicandoquepodemounãopodemavançardeacordocomcondições

O pacote java.util.concurrent foi adicionado no Java 5 para facilitar o trabalho naprogramação concorrente. Ele possui uma série de primitivas para que você não tenha detrabalhardiretamentecomwaitenotify,alémdeterdiversascoleçõesthreadsafe.

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design, Infra,Front-Ende

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Exercícios só recomendados se você já tinha algum conhecimento prévio de programação

20.4UMPOUCOMAIS...

Agoraéamelhorhoraderespirarmaistecnologia!

20.5EXERCÍCIOSAVANÇADOSDEPROGRAMAÇÃOCONCORRENTEELOCKS

.

Page 293: FJ-11 Java e Orientação a Objetos

concorrente,locks,etc.

1. Vamosenxergaroproblemaaoseusarumaclassequenãoéthread-safe:aArrayListporexemplo.

Imaginequetemosumobjetoqueguardatodasasmensagensqueumaaplicaçãodechatrecebeu.VamosusarumaArrayList<String> para armazená-las.Nossa aplicação émulti-thread, entãodiferentes threads vão inserir diferentesmensagens para serem registradas.Não importa a ordemqueelassejamguardadas,desdequeelasumdiasejam!

Vamosusaraseguinteclasseparaadicionarasqueries:

publicclassProduzMensagensimplementsRunnable{privateintcomeco;privateintfim;privateCollection<String>mensagens;

publicProduzMensagens(intcomeco,intfim,Collection<String>mensagens){this.comeco=comeco;this.fim=fim;this.mensagens=mensagens;}

publicvoidrun(){for(inti=comeco;i<fim;i++){mensagens.add("Mensagem"+i);}}}

Vamos criar três threads que rodem esse código, todas adicionando as mensagens na mesmaArrayList.Emoutraspalavras,teremosthreadscompartilhandoeacessandoummesmoobjeto:éaquiquemoraoperigo.

publicclassRegistroDeMensagens{

publicstaticvoidmain(String[]args)throwsInterruptedException{Collection<String>mensagens=newArrayList<String>();

Threadt1=newThread(newProduzMensagens(0,10000,mensagens));Threadt2=newThread(newProduzMensagens(10000,20000,mensagens));Threadt3=newThread(newProduzMensagens(20000,30000,mensagens));

t1.start();t2.start();t3.start();

//fazcomqueathreadquerodaomainaguardeofimdessast1.join();t2.join();t3.join();

System.out.println("Threadsprodutorasdemensagensfinalizadas!");

//verificasetodasasmensagensforamguardadasfor(inti=0;i<15000;i++){if(!mensagens.contains("Mensagem"+i)){thrownewIllegalStateException("nãoencontreiamensagem:"+i);}

.

Page 294: FJ-11 Java e Orientação a Objetos

}

//verificasealgumamensagemficounulaif(mensagens.contains(null)){thrownewIllegalStateException("nãodeviaternullaquidentro!");}

System.out.println("Fimdaexecucaocomsucesso");}}

Rodealgumasvezes.Oqueacontece?

2. Testeocódigoanterior,masusandosynchronizedaoadicionarnacoleção:

publicvoidrun(){for(inti=comeco;i<fim;i++){synchronized(mensagens){mensagens.add("Mensagem"+i);}}}

3. SemusarosynchronizedtestecomaclasseVector,queéumaCollectioneéthread-safe.

Oquemudou?OlheocódigodométodoaddnaclasseVector.Oquetemdediferentenele?

4. Novamentesemusarosynchronized,testeusarHashSeteLinkedList,emvezdeVector.Façaváriostestes,poisasthreadsvãoseentrelaçarcadavezdeumamaneiradiferente,podendoounãoterumefeitoinesperado.

NocapítulodeSocketsusaremosthreadsparasolucionarumproblemarealdeexecuçõesparalelas.

.

Page 295: FJ-11 Java e Orientação a Objetos

CAPÍTULO21

"Quempoucopensa,engana-semuito."--LeonardodaVinci

Como vimos antes, aVM é apenas uma especificação e devemos baixar uma implementação.HámuitasempresasqueimplementamumaVM,comoaprópriaOracle,aIBM,aApacheeoutros.

AdaOracleéamaisusadaepossuiversõesparaWindows,LinuxeSolaris.VocêpodebaixaroSDKacessando:

http://www.oracle.com/technetwork/java/

NestapáginadaOracle,vocêdeveescolheroJavaSE,dentrodostopdownloads.Depois,escolhaoJDKeseusistemaoperacional.

CadadistribuiçãoLinuxtemsuaprópriaformadeinstalação.AlgumasjátrazemoJavajunto,outraspossibilitamquevocêinstalepelosrepositóriosoficiaiseemalgunscasosvocêprecisabaixardiretodaOracleeconfigurartudomanualmente.

NoUbuntu,adistribuiçãousadanaCaelum,ainstalaçãoébastantesimples.Bastairnoterminaledigitar:

sudoadd-apt-repositoryppa:webupd8team/javasudoapt-getupdatesudoapt-getinstalloracle-java8-installer

Casoprefirautilizaroopenjdk,adistribuiçãoopensource,bastafazer

sudoapt-getinstallopenjdk-7-jdk

Porenquantoelepossuiapenasaversão7.Nolinuxfedora,vocêfariacomsu-c"yuminstalljava-1.7.0-openjdk".

SevocêjátiveroutrasversõesinstaladasnoseuUbuntu,podeutilizarsudoupdate-alternatives--configjavaparaescolherentreelas.

Umainstalaçãomaisbraçal,semusarrepositório ,podeserfeitabaixandooinstaladornoprópriosite da Oracle. É um tar.gz que possui um .bin que deve ser executado. Depois, é necessário

APÊNDICE-INSTALAÇÃODOJAVA

21.1INSTALANDONOUBUNTUEEMOUTROSLINUX

.

Page 296: FJ-11 Java e Orientação a Objetos

apontarJAVA_HOMEparaessediretórioeadicionarJAVA_HOME/binnoseuPATH.

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelum eobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

OMacOSXjátrazoJavainstaladojuntocomosistemaoperacionalatéaversão10.6.Asversõesmaisnovas,doLionemdiante,o instaladordoMacvaiperguntar sevocêdesejabaixá-loquando forrodarsuaprimeiraaplicaçãoJava,comooEclipse.

AversãoparaoJava8podeserbaixadanomesmosite:

http://www.oracle.com/technetwork/java/

Para instalar o JDK no Windows, primeiro baixe-o no site da Oracle. É um simples arquivoexecutávelquecontémoWizarddeinstalação:

http://www.oracle.com/technetwork/java/

EditoraCasadoCódigocomlivrosdeumaformadiferente

21.2NOMACOSX

21.3INSTALAÇÃODOJDKEMAMBIENTEWINDOWS

.

Page 297: FJ-11 Java e Orientação a Objetos

Dêumcliqueduplonoarquivojdk-<versão>-windows-i586-p.exeeespereatéeleentrarnowizarddeinstalação.

AceiteospróximosdoispassosclicandoemNext.Apósumtempo,o instaladorpediráparaescolher emquediretório instalaroSDK.Pode serondeele jáoferececomopadrão.Anotequalfoiodiretórioescolhido,vamosutilizaressecaminhomaisadiante.Acópiadearquivosiniciará:

Instalação

.

Page 298: FJ-11 Java e Orientação a Objetos

O instalador instalará também o JavaFX 2. Após isso, você será direcionado à uma páginaondevocêpode,opcionalmente,criarumacontanaOraclepararegistrarsuainstalação.

Precisamosconfiguraralgumasvariáveisdeambienteapósainstalação,paraqueocompiladorsejaacessível via linha de comando. Caso você vá utilizar diretamente o Eclipse, provavelmente não seránecessáriorealizaressespassos.

CliquecomobotãodireitoemcimadoíconeComputadoreselecioneaopçãoPropriedades.

Escolhaaaba "ConfiguraçõesAvançadasdeSistema"edepois cliquenobotão "VariáveisdeAmbiente"

Configurandooambiente

.

Page 299: FJ-11 Java e Orientação a Objetos

Nesta tela, você verá, na parte de cima, as variáveis de ambiente do usuário corrente e,embaixo,asvariáveisdeambientedocomputador(servemparatodososusuários).CliquenobotãoNovo...dapartedebaixo.

EmNomedaVariáveldigiteJAVA_HOMEe,emvalordavariável,digiteocaminhoquevocêutilizou na instalação do Java. Provavelmente será algo como: C:\Program

Files\Java\jdk1.8.0_03:

CliqueemOk.

Nãovamoscriaroutravariável,massimalterar.Paraisso,procureavariávelPATH,ouPath(dánomesmo),ecliquenobotãodebaixo"Editar".

.

Page 300: FJ-11 Java e Orientação a Objetos

Não altere o nome da variável! Deixe como está e adicione no final do valor;%JAVA_HOME%\bin,nãoesqueçadoponto-e-vírgula-assim,vocêestáadicionandomaisumcaminhoàsuavariávelPath.

Abraoprompt,indoemIniciar,Executaredigitecmd.

Noconsole,digitejavac-version.OcomandodevemostraraversãodoJavaCompilerealgumasopções.

VocêpodeseguirparaainstalaçãodoEclipse,conformevistonoseucapítulo,ouutilizarumeditordetextosimplescomooblocodenotasparaosprimeiroscapítulosdeapostila.

Qualquerdúvida,nãohesitedepostá-lanoGrupodeUsuáriosJava:

http://www.guj.com.br.

.

Page 301: FJ-11 Java e Orientação a Objetos

CAPÍTULO22

"Olhoporolho,eomundoacabarácego."--MohandasGandhi

Debugging(emportuguês,depuraçãooudepurar)éumprocessodereduzirouencontrarbugsnoseusistema.Deumaformageral,debuggingnãoéumatarefa fácildeserexecutada.Muitasvariaçõespodem atrapalhar esse processo, por exemplo, a linguagem que estamos utilizando e ferramentasdisponíveisparafazermosdebuggingdeumcódigo.

OJavaemsifacilitamuitonesteprocesso,poisnosfornecemaneirasdesabermosseocódigoestáerrado, por exemplo as exceptions. Em linguagens de baixo nível saber onde o bug estava eraextremamentecomplicado.Oquetambémfacilitanossotrabalhosãoasferramentasdedebug.Veremosqueelas sãonecessáriasnoscasosquenossos testesdeunidadede loggingnão foramsuficientesparaencontrararazãodeumproblema.

Se você está gostando dessa apostila, certamente vai aproveitar os cursosonlinequelançamosnaplataformaAlura.VocêestudaaqualquermomentocomaqualidadeCaelum.Programação,Mobile,Design, Infra,Front-Ende

Business!Ex-alunodaCaelumtem15%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

No curso utilizamos o Eclipse como IDE para desenvolvermos nosso código. Como foi ditoferramentasdedebuggingfacilitammuitonossotrabalho,oEclipseéumadasIDEsmaispoderosasdomercadoenosforneceumaferramentaquetornaoprocessoextremamentesimples.

APÊNDICE-DEBUGGING

22.1OQUEÉDEBUGAR

Agoraéamelhorhoraderespirarmaistecnologia!

22.2DEBUGANDONOECLIPSE

.

Page 302: FJ-11 Java e Orientação a Objetos

O primeiro recurso que temos que conhecer quando começamos a debugar no Eclipse são osbreakpoints. Eles são pontos de partida em nosso código para iniciarmos o processo de debug. Porexemplo,no código abaixo, imaginequedesejamosdebugaro comportamentodométodosaca daclasseConta,mais especificamentedoif que verifica se saldo émenorqueo valor a ser sacado.Colocaríamosobreakpointexatamentenalinhaif(this.saldo<valor){:

publicclassConta{

privatedoublesaldo;

publicbooleansaca(doublevalor){if(this.saldo<valor){returnfalse;}else{this.saldo=this.saldo-valor;returntrue;}}}

Mascomofaçoisso?Muitosimples,bastaclicarnalinhaquedesejaadicionarobreakpoint,depoisclicarnomenuRun->ToogleBreakpoint.

.

Page 303: FJ-11 Java e Orientação a Objetos

Esseéotipomaisclássicodebreakpoint,veremosalgunsoutrosaolongodocapítulo.

Agora que já adicionamos o breakpoint que é o ponto de partida, vamos debugar nosso código.Precisamosrodarnossocódigo,ouseja,chamarométodosacaparaqueobreakpointsejaencontrado.Teremosumcódigosimilaraoseguinte:

publicclassTestaConta{publicstaticvoidmain(String[]args){Contaconta=newConta();conta.saca(200);}}

.

Page 304: FJ-11 Java e Orientação a Objetos

O processo normal para executarmos esse código seria clicar no menu Run -> Run As -> JavaApplication. Porém para rodar o nosso código emmododebug e ativar nosso breakpoint, devemosrodarocodigonomenuRun->DebugAs->JavaApplication.Quandoumbreakpointforencontradonocódigoqueestásendoexecutado,oeclipseexibiráumaperspectivaespecíficadedebug,apontandoparaalinhaquetemobreakpoint.

Temos várias informações disponíveis nessa perspectiva, algumas são essenciais e básicas paratrabalharmos com debug no nosso dia-a-dia, outras não tão relevantes e só usamos em casosmuito

22.3PERSPECTIVADEDEBUG

.

Page 305: FJ-11 Java e Orientação a Objetos

específicos.

Dentro da perspectiva de debug, temos uma aba chamada Variables. São exibidas todas asvariáveisencontradasdentrodocódigoquevocêestádebugando.Porexemplo,nodebugquefizemosserãoexibidasasvariáveisdométodosaca,nestecaso,valor.Alémdosatributosde instânciadoobjeto.

Podemosexibirmais informaçõessobreasvariáveis,bastaadicionarmosascolunasquedesejamosnatabelaexibida.

.

Page 306: FJ-11 Java e Orientação a Objetos

Épossíveltambémadicionarmosconstantesevariáveisestáticasdaclassequeestásendodebugada.

.

Page 307: FJ-11 Java e Orientação a Objetos

NaabaBreakpointssãoexibidostodososbreakpointsqueseuworkspacepossui.Masporqueissoéimportante?Éimportanteporquepodemosvertodosospontosdedebugpresentesemelhor,podemosdesabilitá-los um a um ou todos de uma só vez. Você pode até mesmo pedir para exportar osbreakpoints.

Paradesabilitar ouhabilitar todosbreakpoints basta clicarmosno íconeSkipAllBreakpoints. Sequisermosdesabilitarumaum,bastadesmarcarocheckboxeobreakpointserádesativado.Àsvezes,encontrarocódigoondeobreakpointfoicolocadopodesercomplicado,naabaBreakpointsissoficabemfácildefazer,bastadarumduplocliquenobreakpointeoeclipseautomaticamentenosmostraaclasse"dona"dele.

Quandoestamosdebugandocódigo,muitasvezeséinteressantesaberovalordealgumaexpressãooumétodo.Porexemplo,umacondiçãodentrodeumif,this.saldo>valor.Essevalornãoestáemumavariável,eleestáemumaexpressão,oquepodetornarsaberovalordelacomplicado.Afeaturede Expressions descomplica esse processo para nós. Na perspectiva de Debug temos a abaExpressions.Bastaclicarcomodireitodentrodaaba,eclicaremAddExpression:

.

Page 308: FJ-11 Java e Orientação a Objetos

Eoresultadodaexpressãoéexibido.

TemosoutraabaimportantechamadadeDebug.Dentreasfunçõesdelaestão:

Threads-Exibeasthreadsqueestãosendoexecutadas,emelhor,mostraqualthreadefetuouachamadaparaométodoondeestáodebug.Alémdissomostraapilhadeexecução,oquenospermitevoltarachamadadeummétodoBarradenavegação-Quepermitealterarmososcaminhosqueodebugseguirá.

.

Page 309: FJ-11 Java e Orientação a Objetos

Alistaaseguirmostraralgumasteclasebotõesquealteramocaminhonaturaldosnosssdebug:

F5 - Vai para o próximo passo do seu programa. Se o próximo passo for ummétodo, eleentraránocódigoassociado;F6 -Tambémvaiparaopróximopasso,porémseopróximopasso forummétodo,elenãoentraránocódigoassociado;F7-Voltaráemostraráométodoquefezachamadaparaocódigoqueestásendodebugado.NonossocasovoltaráparaométodomaindaclasseTestaConta;F8-Vaiparaopróximobreakpoint,senenhumforencontrado,oprogramaseguiráseufluxodeexecuçãonormal.

VocêtambémpodeusarosbotõesqueestãopresentesnaabaDebug.

.

Page 310: FJ-11 Java e Orientação a Objetos

Depoisquecolocamosumbreakpointemalgumpontodonossocódigo,podemoscolocaralgumaspropriedadesnele,porexemplo,usaralgumacondiçãopararestringirquandoobreakpointseráativadoemtempodeexecução.PodemosrestringirnapropriedadeHitCountqueobreakpointsóseráativadoquandoalinhaemqueeleencontra-seforexecutada'X'vezes.

22.4DEBUGAVANÇADO

.

Page 311: FJ-11 Java e Orientação a Objetos

Como na imagem acima o breakpoint só será ativado quando a linha de código em que ele seencontraforexecutada'2'vezes.Podemostambémcolocaralgumaexpressãocondicional,umif,porexemplo.

.

Page 312: FJ-11 Java e Orientação a Objetos

Obreakpoint, neste caso, somente será ativadoquandoo argumentovalor que foi passado aométodosaca formaior que 100.O importante aqui énotarmosquedevemos retornar sempre umvalorbooleano,senãoofizermos, teremosumerroemtempodeexecução.EssapropriedadeéválidaquandoqueremoscolocaraquelesfamososSystem.out.println("entrounoiftal")paraefeitode log, podemos fazer isso colocando o log dentro da expressão condicional nas propriedades dobreakpoint.

O display é uma das partes mais interessantes do debug do eclipse, ele provê uma maneira deexecutarmos qualquer código que quisermos quando estamos em debugging. Criar uma classe,instanciarobjetosdessaclasse,utilizarif's,for's,while's,todososrecursosdoJava,alémdepoderutilizarasvariáveis,métodos,constantesdaclassequeestamosdebugando.

Umexemploclássicoéquandoestamosemdebuggingequeremossaberoretornodealgummétododoqualnãotemosacesso,oquefaríamosantesseriacolocarumamontoadodeSystem.out.println,poluindo extremamente nosso código.Nodisplay o que fazemos é efetuar a chamadadesse código eautomaticamenteosresultadossãoexibidos.

Para vermos um efeito real disso, vamos alterar umpouco o comportamento da classeConta, demodoqueagoraosaldoparasaquetenhaqueserosaldorealmaisovalordolimite.Nossocódigofica

.

Page 313: FJ-11 Java e Orientação a Objetos

assim:

publicclassConta{

privatedoublesaldoReal;privatedoublelimite;

publicConta(doublelimite){this.limite=limite;}

publicbooleansaca(doublevalor){if(!isSaldoSuficiente(valor)){returnfalse;}else{this.saldoReal=this.saldoReal-valor;returntrue;}}

privatebooleanisSaldoSuficiente(doublevalor){return(this.saldoReal+this.limite)>valor;}}

Reparequeoif queverifica seo saldoé suficienteparaefetuarmoso saquechamaummétodoisSaldoSuficiente,oquepodeserumproblemaquandoestamosdebugando,afinalacondiçãodoiféummétodo.SeutilizarmosodisplaypodemosfazerachamadadométodoisSaldoSuficiente,verseuresultadoeomelhor,nãoafetamosodebug,apenasqueremosveroresultadodométodo,porexemplo.

Para exibirmos a abaDisplay é bem simples. TecleCtrl+ 3, digiteDisplay e a aba será exibida.Quandorodarmosnossocódigoemmododebug,podemosirnodisplay,digitarmosumachamadaparaométodoisSaldoSuficiente, executamos esse código que foi digitado selecionando-o dentro dodisplayeteclandoCtrl+Shift+Deoresultadoseráimpresso,assimcomonaimagemabaixo:

.

Page 314: FJ-11 Java e Orientação a Objetos

Muitasvezesqueremos "seguir"algumavariávelde instância,ouseja,qualquerchamadaparaessavariável(leituraouescrita)queremossernotificadosdisso.Podemosusarowatchpoint,quefaránossoprogramaentraremmododebug,quandoqualqueralteraçãonavariávelqueestamosseguindoocorrer,oprogramaentraráemdebugexatamentenalinhaquefezaalteração.Paracolocarmosumwatchpoint,bastadarumduplocliquenoatributodeinstânciaquedesejacolocá-lo.

.

Page 315: FJ-11 Java e Orientação a Objetos

Épossívelalteraressecomportamentopadrão,edefinirsevocêquerqueowatchpointsejaativadoparaleituraousomenteparaescrita.

.

Page 316: FJ-11 Java e Orientação a Objetos

Aidéiadesse tipodebreakpointé fazernossoprogramaentraremdebugquandoalgumaexceçãoespecífica ocorrer. Quando definirmos essa exceção no Exception Breakpoint e a mesma ocorrer,automaticamente nosso programa entra em debug na linha que gerou aquela exceção. Por exemplo,vamosalterarocodigodaclasseTestaContaparaqueamesmatenhaumaNullPointerException:

publicclassTestaConta{publicstaticvoidmain(String[]args){Contaconta=null;conta.saca(10);}}

Quando rodarmos o código acima, teremos uma NullPointerException. Pode ser útil nessescasosdebugaresaberondeaexceçãoestáocorrendodefato,emquallinhamaisespecificamente.Parafazermos isso podemos criar um Exception Breakpoint, que debugará códigos que eventualmentelancemumaNullPointerException,porexemplo.BastaabrirmosaabaBreakpointseclicarmosnoíconeabaixo:

.

Page 317: FJ-11 Java e Orientação a Objetos

Seráabertaumajanelaondepodemosbuscarporumaexceçãoespecífica.

Podemosdefinirumbreakpointqueé ativadoouantesoudepoisqueométodoé chamado.Paradefinirmosele,bastaestaremqualquerpartedométodoquedesejamosdebugar,clicarnomenuRun->ToogleMethodBreakpoint.Podemoseditaraspropriedadesdessebreakpointdizendosequeremosqueele seja ativado antes(default) ou depois da execução do método. Basta acessar as propriedades domethodbreakpointealterá-las.

.

Page 318: FJ-11 Java e Orientação a Objetos

Éutilquandodesejamosqueumbreakpointsejaativadoquandoumaclasseespecíficaforcarregadapelaprimeiravez, chamamosessebreakpointdeClassBreakpoint. Basta clicarmosnomenuRun ->AddClassLoadBreakpoint,umajanelaseráabertaebastadigitarmosonomedaclasseeadicionarmos:

.

Page 319: FJ-11 Java e Orientação a Objetos

Editorastradicionaispoucoligamparaebooksenovastecnologias.Nãodominamtecnicamente o assunto para revisar os livros a fundo. Não têm anos deexperiênciaemdidáticascomcursos.ConheçaaCasadoCódigo,umaeditoradiferente,comcuradoriadaCaelum eobsessãoporlivrosdequalidadeapreçosjustos.

CasadoCódigo,ebookcompreçodeebook.

Um dos principais hábitos que nós desenvolvedores devemos evitar é a questão da otimizaçãoprematura,ouseja,quandodesenvolvemosumaaplicaçãoparaumcliente,devemosnospreocuparematenderorequisitosfuncionaisdemaneiramaisrápidaemaissimplespossível.Opassoseguinteérefatorar seu código para que ele sejamelhorado e para que no futuro possa se adaptar as possíveismudanças.

Aregraé:"Deixeosproblemasdofuturo,paraseremresolvidosnofuturo".

Umadasferramentasquenosauxiliamnaquestãodenãootimizarnossocódigoprematuramente,sãoas ferramentasdeprofiling,que tornamaparentes,porexemplo,osproblemasdememóriaecpu,quepodemfazercomqueotimizemosnossocódigo.Atualmentedevidoastécnicasqueutilizamosparaentregaralgodevalorparaocliente,focamosprincipalmentenaqualidade,aspectosfuncionais,testes,etc.Porém,muitosproblemasquenão fazempartedosrequisitos funcionaispodemacontecerapenasquandoaaplicaçãoestáemprodução,nestepontoasferramentasdeprofilingtambémnosajudam.

JuntamentecomoEclipsetemosaopçãodeinstalareutilizarumaferramentadeprofilingconhecidacomoEclipseTPTP(EclipseTest&PerformanceToolsPlatform),quenosforneceopçõesparaisolareidentificarproblemasdeperformance,taiscomo:memória(memoryleak),recursoseprocessamento.OTPTPnospermiteanalisardesimplesaplicaçõesjavaatéaplicaçõesquerodamemmúltiplasmáquinaseemmúltiplasplataformas.

EditoraCasadoCódigocomlivrosdeumaformadiferente

22.5PROFILING

22.6PROFILINGNOECLIPSETPTP

.

Page 320: FJ-11 Java e Orientação a Objetos

ALTERNATIVASAOTPTP

Existem algumas alternativas ao TPTP, os mais conhecidos são Netbeans Profiler(http://profiler.netbeans.org/) que é gratuito, e o JProfiler (http://www.ej-technologies.com/products/jprofiler/overview.html)queépago.

O TPTP não vem por padrão junto com o Eclipse. Portanto, para utilizarmos é necessário ainstalaçãodomesmo.Podemosfazeroprocessodeinstalaçãodeduasmaneiras.Aprimeiraemaisfácilé utilizandooUpdate Site doEclipse que resolve as possíveis dependências e nos possibilita escolherquaisfeaturesqueremosinstalar.ParainstalaroTPTPatravésdesserecurso,bastairnomenu:Help->InstallNewSoftware,umajanelaseráaberta,bastaclicaremAdd...epreenchê-laconformeaimagemaseguir:

Basta adicionar as ferramentas do TPTP em nosso eclipse, para isto, selecione o repositório queacabamosdeadicionareaversãodoTPTPquequeremosinstalar,nestecaso,aversão4.6.2.

.

Page 321: FJ-11 Java e Orientação a Objetos

INSTALANDOPELOZIP

VocêtemaopçãodeinstalaroTPTPbaixandoozipdoprojetoecolocandomanualmentenodiretório de instalação do seu eclipse. Mais informações no link:http://www.eclipse.org/tptp/home/downloads/4.6.0/documents/installguide/InstallGuide46.html

Umproblemaquepodeaconteceremaplicaçõesequemuitaspessoasnãoconhecema fundo,éaquestãodopooldeStringsquepodeeventualmenteficarmuitogrande.Esteproblemapodesercausado

.

Page 322: FJ-11 Java e Orientação a Objetos

porqueobjetosdotipoStringsãoimutáveis,sendoassim,sefizermosconcatenaçõesdeStringsmuitasvezes,cadaumadessasconcatenaçõesproduziráumanovaString,queautomaticamenteserácolocadanopooldaJVM.

A alternativa neste caso, seria trabalhar com objetos do tipo StringBuilder ou StringBuffer quefuncionam como Strings,mas que não produzem Strings novas em caso de uma concatenação.MascomomedirotamanhodonossopooldeString?

O TPTP possui uma aba de estatísticas que nosmostra o tempo que ummétodo levou para serexecutado,quantoprocessamentoessemétodogastou,quantodememóriafoigastocomcadamétodo.VamosanalisaralgumasdessasestatísticascriandoumcódigoqueconcateneváriasStrings,demaneiraquesobrecarregueopool,gerebastanteprocessamentoeconsumodememória.

publicclassTeste{

publicstaticvoidmain(String[]args){for(inti=0;i<1000000;i++){Stringx="a"+i;System.out.println(x);}}

}

Paraanalisarmosoresultadodocódigo,vamosrodarocódigodomainatravésdomenuRun ->ProfileAs->JavaApplication.

VERSÕES

Infelizmente o TPTP funciona somente no Windows. Versões para MacOS e Linux sãoprometidas, mas até hoje estão em desenvolvimento. Uma alternativa paga para esses outrossistemasoperacionaiséoJProfiler.

.