uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é...

202

Transcript of uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é...

Page 1: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o
Page 2: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o
Page 3: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

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

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

EssaapostilaéconstantementeatualizadaedisponibilizadanositedaCaelum.Sempreconsulteositeparanovasversõ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 C# 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 e utilização paraministrar treinamentos são absolutamente vedadas. Parausocomercialdestematerial,porfavor,consulteaCaelumpreviamente.

SOBREESTAAPOSTILA

Page 4: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

1

3

14

20

25

Sumário

1ComoaprenderC#1.1Oqueérealmenteimportante? 1

1.2Sobreosexercícios 1

1.3Tirandodúvidaseindoalém 2

2OqueéC#e.Net2.1UmpoucosobreahistóriadoC#e.Net 3

2.2Máquinavirtual 4

2.3ExecuçãodocódigonaCLReoJIT 5

2.4OambientededesenvolvimentodoC# 6

2.5ExecutandoaplicaçõessemoVisualStudio 6

2.6OprimeiroprogramaemC# 7

2.7Exercícios 11

2.8Oqueaconteceuduranteaexecução? 12

3Variáveisetiposprimitivos3.1Operaçõescomvariáveis 14

3.2TiposPrimitivos 16

3.3Armazenandotextoemvariáveis 17

3.4Documentandoocódigoatravésdecomentários 17

3.5Exercícios 18

4Estruturasdecontrole4.1Tomandodecisõesnocódigo 20

4.2Maissobrecondições 21

4.3Exercíciosopcionais 22

5Estruturasderepetição5.1Repetindoumblocodecódigo 25

5.2Parasabermaisdowhile 26

5.3Parasabermaisincrementoedecremento 26

SumárioCaelum

Page 5: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

29

47

57

61

80

5.4Exercícios 27

6Classeseobjetos6.1OrganizandoocódigocomObjetos 29

6.2Extraindocomportamentosatravésdemétodos 32

6.3Devolvendovaloresdedentrodométodo 34

6.4Valorpadrãodosatributosdaclasse 36

6.5Maisumexemplo:Transfere 37

6.6Convençãodenomes 38

6.7Exercícios 45

6.8Composiçãodeclasses 44

6.9Exercícios 45

7EncapsulamentoeModificadoresdeAcesso7.1Encapsulamento 48

7.2Controlandooacessocomproperties 50

7.3SimplificandoadeclaraçãodepropriedadescomAuto-ImplementedProperties 52

7.4Convençãodenomeparaproperty 53

7.5Exercícios 54

7.6Parasabermais:VisibilidadeInternal 55

8Construtores8.1Múltiplosconstrutoresdentrodaclasse 57

8.2Parasabermais—Initializer 59

8.3Exercícios 59

9IntroduçãoaoVisualStudiocomWindowsForm9.1IntroduçãopráticaaosatalhosdoVisualStudio 64

9.2AclasseConvert 68

9.3Operaçõesnaconta:saqueedepósito 69

9.4Controlandoonomedaaçãodeumbotão 71

9.5RenomeandoVariáveis,MétodoseClassescomoVisualStudio 72

9.6Parasabermais—organizandooformuláriocomLabeleGroupBox 73

9.7ResumodosatalhosdoVisualStudio 75

9.8Exercícios 76

9.9Parasabermais—tiposimplícitoseapalavraVAR 76

9.10ExercíciosOpcionais 77

10Herança10.1ReaproveitandocódigocomaHerança 81

10.2Reaproveitandoaimplementaçãodaclassebase 83

CaelumSumário

Page 6: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

91

100

109

113

120

125

134

141

149

10.3Polimorfismo 84

10.4Exercícios 87

10.5Parasabermais—oqueéherdado? 89

11Trabalhandocomarrays11.1Parasabermais—inicializaçãodeArrays 92

11.2Exercícios 98

11.3OrganizandoascontascomoComboBox 96

11.4Exercícios 98

12Cadastrodenovascontas12.1UtilizandooAdicionaContanoloaddoformulário 104

12.2Exercícios 106

13Classesabstratas13.1Exercícios 111

14Interfaces14.1Exercícios 116

15Métodoseatributosestáticos15.1ExercíciosOpcionais 122

15.2Parasabermaisclassesestáticas 123

16Exceções16.1Retornodométodoparacontrolarerros 125

16.2Controlandoerroscomexceções 126

16.3Tratandomúltiplasexceções 128

16.4Exercícios 131

17Namespaces17.1Parasabermais-Declaraçãodenamespaceaninhados 136

17.2Parasabermais-Aliasparanamespaces 137

17.3Exercícios 139

18ClasseObject18.1Implementandoacomparaçãodeobjetos 141

18.2MelhorandoaimplementaçãodoEqualscomois 144

18.3IntegrandooObjectcomoComboBox 145

18.4Exercícios 146

19Trabalhandocomlistas

SumárioCaelum

Page 7: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

153

166

176

185

190

19.1Facilitandootrabalhocomcoleçõesatravésdaslistas 149

19.2Exercícios 151

20Lidandocomconjuntos20.1Otimizandoabuscaatravésdeconjuntos 153

20.2ConjuntosOrdenadoscomoSortedSet 155

20.3Ainterfacedetodososconjuntos 156

20.4Comparaçãoentrelistaseconjuntos 156

20.5Exercícios 163

20.6BuscasrápidasutilizandoDicionários 160

20.7Iterandonodicionário 161

20.8Exercícios 163

21LINQeLambda21.1FiltrosutilizandooLINQ 166

21.2Simplificandoadeclaraçãodolambda 167

21.3OutrosmétodosdoLINQ 168

21.4UtilizandooLINQcomoutrostipos 169

21.5Melhorandoasbuscasutilizandoasintaxedequeries 169

21.6Parasabermais—projeçõeseobjetosanônimos 170

21.7Exercícios 171

21.8OrdenandocoleçõescomLINQ 174

21.9Exercícios-Ordenação 175

22System.IO22.1Leituradearquivos 176

22.2Escrevendoemarquivos 178

22.3Gerenciandoosarquivoscomousing 179

22.4Exercícios 180

22.5Parasabermais—ondecolocarosarquivosdaaplicação 183

23Manipulaçãodestrings23.1Exercícios 186

24Apêndice—estendendocomportamentosatravésdemétodosextras24.1Exercícios 191

Versão:24.8.9

CaelumSumário

Page 8: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO1

Muitoslivros,aopassardoscapítulos,mencionamtodososdetalhesdalinguagem,juntamentecomseusprincípios básicos. Isso acaba criandomuita confusão, em especial porque o estudante não conseguediferenciarexatamenteoqueéessencialaprendernoinício,daquiloquepodeserdeixadoparaestudarmaistarde.

Se uma classe abstrata deve ou não ter aomenos ummétodo abstrato, se oif somente aceita

argumentosbooleanosetodososdetalhessobreclassesinternas,realmentenãodevemserpreocupaçõesparaaquelecujoobjetivoprimárioéaprenderC#.Essetipodeinformaçãoseráadquiridacomotempoenãoénecessárianoinício.

Nestecurso,separamosessasinformaçõesemquadrosespeciais, jáquesãoinformaçõesextra.Ouentão,apenascitamosemalgumexercícioedeixamosparaoleitorprocurarinformaçõesadicionais,sefordeseuinteresse.

Porfim,faltamencionaralgosobreaprática,quedeveser tratadaseriamente: todososexercíciossãomuito importanteseosdesafiospodemser feitosapóso términodocurso.Dequalquermaneira,recomendamosaosalunosestudarememcasaepraticarembastantecódigoevariações.

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

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

COMOAPRENDERC#

1.1OQUEÉREALMENTEIMPORTANTE?

Agoraéamelhorhoradeaprenderalgonovo

1.2SOBREOSEXERCÍCIOS

1COMOAPRENDERC# 1

Page 9: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

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

Existe também, emdeterminados capítulos, uma série de desafios.Eles focammais no problemacomputacionalquenalinguagem,porémsãoumaexcelenteformadetreinarasintaxee,principalmente,familiarizaroalunocomasbibliotecaspadrãodoC#,alémdeproporcionarumganhonavelocidadededesenvolvimento.

Paratirardúvidasdeexercícios,oudeC#emgeral,recomendamosofórumdoGUJRespostas:

http://www.guj.com.br

Lásuadúvidaserárespondidaprontamente.OGUJfoifundadopordesenvolvedoresdaCaelumehojecontacommaisdeummilhãodemensagens.

Oprincipalrecursooficialparaencontrardocumentação,tutoriaiseatémesmolivrossobre.NETeC#,éaMicrosoftDevelopersNetwork,ouMSDN:

https://msdn.microsoft.com

DestacamosaseçãodetutoriaisdeC#(eminglês),noendereço:

https://www.microsoft.com/net/tutorials/csharp/getting-started

HátambémfórunsoficiaisemportuguêsnaMSDN:

https://social.msdn.microsoft.com/Forums/pt-br/home

Foraisso,sinta-seàvontadeparaentraremcontatocomseuinstrutorparatirartodasasdúvidasquesurgiremduranteocurso.

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

https://www.casadocodigo.com.br/

ACaelumofereceoutrocursodeC#/.NET,oFN-23,quetrazaaplicaçãodoC#naWeb:

https://www.caelum.com.br/

Hátambémcursosonlinequevãoajudá-loairalém,commuitainteraçãocomosinstrutores:

https://www.alura.com.br/

1.3TIRANDODÚVIDASEINDOALÉM

2 1.3TIRANDODÚVIDASEINDOALÉM

Page 10: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO2

EntenderumpoucodahistóriadoC#edo.Netéessencialparaenxergarosmotivosquealevaramaosucesso.

Nofinaldadécadade1990aMicrosofttinhadiversastecnologiaselinguagensdeprogramaçãopararesolvermuitosproblemasdiferentes.Todavezqueumprogramadorprecisavamigrarparaumanovalinguagem, era necessário aprender tanto a nova linguagemquanto suas bibliotecas e conceitos. Parasolucionaressesproblemas,aMicrosoftrecorreuàlinguagemJava.

OJavaagradouosengenheirosdaMicrosoftpoiscomelapodíamosconstruirprogramasqueeramindependentesdoambientedeexecução,alémdepossuirdiversasbibliotecascomsoluçõesprontasparadiversos problemas. Para lançar produtos baseados no Java, a Microsoft assinou um acordo delicenciamentocomaSunparautilizaroJavaemambienteWindows.

Porém, a linguagem Java possuía um grave problema: ela não se comunicava bem com asbibliotecasdecódigonativo(códigodemáquina)quejáexistiam.Pararesolverisso,aMicrosoftdecidiucriar a sua própria implementação do Java chamado J++, que possuía extensões proprietárias queresolviamo problema de comunicação como código nativo existente. Para o desenvolvimento dessanovaimplementaçãodoJava,aMicrosoftcontratouumengenheirochamadoAndersHejlsberg,umdosprincipaisnomesportrásdoDelphi.

OJ++eraumaversãoda linguagemJavaquesópodiaserexecutadanoambienteMicrosoft.Seucódigonãopodia ser executadoemmaisnenhumambiente Java,oqueviolavao licenciamento feitocomaSune,porisso,aMicrosoftfoiprocessada.Umadasmaisconhecidasbatalhasjudiciaisdaépoca.

SemoJ++,aMicrosoft foiobrigadaa repensarsuaestratégiasobrecomo lidarcomasdiferenteslinguagens e tecnologias utilizadas internamente. A empresa começou a trabalhar em um novaplataformaque seria abasede todas as suas soluções,queposteriormente foi chamadade .Net.Essenovo ambiente de desenvolvimento da Microsoft foi desde o início projetado para trabalhar comdiversas linguagens de programação, assim diversas linguagens diferentes compartilhariam omesmoconjunto de bibliotecas. Com isso, para um programador migrar de uma linguagem para outra eleprecisariaapenasaprenderalinguagemsemsepreocuparcomasbibliotecaseAPIs.

Alémde uma plataforma aMicrosoft tambémprecisava de uma linguagemde programação.Um

OQUEÉC#E.NET

2.1UMPOUCOSOBREAHISTÓRIADOC#E.NET

2OQUEÉC#E.NET 3

Page 11: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

novo projeto de linguagem de programação foi iniciado, o projeto COOL (C-like Object OrientedLanguage).AndersHejlsbergfoiescolhidocomoengenheirochefedessenovoprojeto.COOLteveseudesignbaseadoemdiversasoutraslinguagensdomercadocomoJava,C,C++,Smalltalk,DelphieVB.Aideiaeraestudarosproblemasexistenteseincorporarsoluções.

Em 2002, o projetoCOOL foi lançado como linguagemC# 1.0, junto com o ambiente .Net 1.0.Atualmente, a linguagem C# está em sua versão 7.0, e o .Net na versão 4.7, tendo evoluído comexpressivavelocidade,adotandonovidadesnasuasintaxequeadiferenciarambastantedoJavaeoutrasconcorrentes.

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

CasadoCódigo,ebookcompreçodeebook.

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, ele deve saber conversar com o sistema operacional em questão. Isto é, temos um códigoexecutáveldiferenteparacadasistemaoperacionaldiferente.

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

OC#utilizaoconceitodemáquinavirtual.Entreosistemaoperacionaleaaplicaçãoexisteumacamadaextraresponsávelpor"traduzir"—masnãoapenasisso—oquesuaaplicaçãodesejafazerparaasrespectivaschamadasdosistemaoperacionalondeelaestárodandonomomento.

EditoraCasadoCódigocomlivrosdeumaformadiferente

2.2MÁQUINAVIRTUAL

4 2.2MÁQUINAVIRTUAL

Page 12: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

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çãoetc.

Sua aplicação roda sem nenhum envolvimento com o sistema operacional! Sempre conversandoapenascomamáquinavirtualdoC#,aCommonLanguageRuntime(CLR).ACLRéoambientedeexecuçãopara todasas linguagensdaplataforma.Net,nãoapenasparaoC#.Certamente issonãofoiuma revolução.O Java trouxe esse conceito para omercado e já haviamuitas linguagens com essesrecursos,apesardequeeramencontradasmaisnomeioacadêmico.

O CLR isola totalmente a aplicação do sistema operacional. Se uma aplicação rodando no CLRtermina abruptamente, ela não afetará as outrasmáquinas virtuais e nemo sistemaoperacional.Essacamadadeisolamentotambéméinteressantequandopensamosemumservidorquenãopodesesujeitararodarcódigoquepossainterferirnaboaexecuçãodeoutrasaplicações.

Comoamáquinavirtualdevetrabalharcomdiversaslinguagensdeprogramaçãodiferentes,aCLRnão pode executar diretamente o código do C#, ela precisa executar uma linguagem intermediáriacomumatodasaslinguagensdaplataforma.Net,aCIL(CommonIntermediateLanguage).ParageraroCILque seráexecutadopelaCLR,precisamospassarocódigoC#porumcompiladorda linguagem,comooprogramacsc.exe.Ocompiladorlêoarquivocomocódigofontedoprogramaeotraduzpara

ocódigointermediárioqueseráexecutadopelamáquinavirtual.

COMMONLANGUAGEINFRASTRUCTURE

Ainfraestruturanecessáriaparaexecutaroscódigosescritosparaaplataforma.NetéchamadadeCLI (Common Language Infrastructure). A CLI engloba amáquina virtual do C# (CLR), alinguagemintermediária(CIL)eostiposbaseutilizadosnosprogramas.

ParaexecutarmosumaaplicaçãoC#,precisamospassarocódigoCILdoprogramaparaaCLR,amáquina virtual do .Net. A CLR por sua vez precisa executar o código da aplicação no sistemaoperacionaldousuárioe,paraisso,precisaemitirocódigodemáquinacorretoparaoambienteemqueoprogramaestásendoexecutado.MasaCLRnãointerpretaoCILdoprograma,issoseriamuitolento,ao invés disso, quando o programaC# é carregado namemória, aCLR converte automaticamente ocódigoCILparacódigodemáquina, esseprocessoé feitoporumcompiladorJust inTime (JIT) daCLR.

EssecarregamentoutilizandooJITfazcomqueocódigoescritonalinguagemC#executecomo

2.3EXECUÇÃODOCÓDIGONACLREOJIT

2.3EXECUÇÃODOCÓDIGONACLREOJIT 5

Page 13: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

desempenhomáximo,omesmodeumprogramaescritoemlinguagensquecompilamdiretamenteparaocódigodemáquina,mascomavantagemdeexecutarnoambienteintegradodo.Net.

NessecursoescreveremostodoocódigoutilizandooVisualStudioComunity,aversãogratuitadaferramenta de desenvolvimento de aplicações, que é distribuída pela própria Microsoft. Apesar dasexplicações serem feitas com base na versão comunity, tudo funcionará damesma forma dentro dasversõespagasdaferramenta.

OVisualStudioComunitypodeserencontradonosite:

https://www.visualstudio.com/pt-br/downloads/

AversãoqueutilizaremosnaapostilaéaVisualStudioComunity2017.

Durantea instalaçãodoVisualStudio,o .NetFramework tambémseráautomaticamente instaladoemsuamáquina,entãoelaestaráprontaexecutarasaplicaçõesescritasemC#.

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

Comovimosanteriormente,paraexecutarmosumaaplicaçãoC#precisamosdamáquinavirtualdalinguagemalémdasbibliotecasdo.NetFramework.AoinstalarmosoVisualStudio,todoesseambientede execução de programas é automaticamente instalado em nossas máquinas, mas e se quisermosexecutaroprogramaemumcomputadorquenãotenhaoVisualStudioinstalado,ocomputadordeumcliente,porexemplo?

Nessecasoprecisamosinstalarapenasoambientedeexecuçãonocomputadordocliente.ParaissopodemosutilizarumpacotedeinstalaçãofornecidopelaprópriaMicrosoft,essessãoos.NetFramework

2.4OAMBIENTEDEDESENVOLVIMENTODOC#

JáconheceoscursosonlineAlura?

2.5EXECUTANDOAPLICAÇÕESSEMOVISUALSTUDIO

6 2.4OAMBIENTEDEDESENVOLVIMENTODOC#

Page 14: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Redistributable.Opacotedeinstalaçãoparaaúltimaversãodo.NetFramework(4.5.1lançadaem2013)podeserencontradanoseguintesite:

http://www.microsoft.com/en-us/download/details.aspx?id=40779

C#EMOUTROSAMBIENTES

Podemos também executar o código C# dentro de ambientes não windows utilizandoimplementaçõeslivresdoCommonLanguageInfrastructure.UmaimplementaçãodoambientedeexecuçãoparaambientesnãoWindowséoMono:

http://www.mono-project.com/Main_Page

Agora que já entendemos o funcionamento da linguagem C#, vamos começar a desenvolver aprimeiraaplicaçãoutilizandooVisualStudio.ParacriarmosumprogramaC#utilizandooVisualStudioprecisamosinicialmentedeumnovoprojeto.

DentrodoVisualStudio2017,aperteoatalhoCtrl+Shift+Nparaabriroassistentedecriação

denovoprojeto.

2.6OPRIMEIROPROGRAMAEMC#

2.6OPRIMEIROPROGRAMAEMC# 7

Page 15: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Nocantoesquerdodajaneladoassistentedecriaçãodenovoprojeto,podemosescolheralinguagemde programação que desejamos utilizar, escolha a opçãoVisualC#. Como tipo de projeto escolha aopçãoWindowsFormApplication, com isso estamos criando um novo projeto de interface gráficautilizandooC#.

No canto inferior da janela, podemos escolher o nome do projeto alémda pasta emque ele seráarmazenado.UtilizaremosOiMundocomonomedessenovoprojeto.

Queremos inicialmentecolocarumbotãono formulárioque,quandoclicado, abriráumacaixademensagemdoWindows.

Paracolocarmosobotãonoformulário,precisamosabrirumanovajaneladoVisualStudiochamadaToolbox, que fica no canto esquerdo da janela do formulário. O Toolbox também pode ser abertoutilizando-seoatalhoCtrl+Alt+X.Dentrodajanelado"Toolbox",nogrupo"CommonControls",

cliquenocomponente"Button"earraste-oparaoformulário.

8 2.6OPRIMEIROPROGRAMAEMC#

Page 16: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Agora dê um duplo clique no botão que acabamos de adicionar para programarmos o que deveacontecerquandoobotãoforclicado.OVisualStudioabriráocódigodoformulário.Nãosepreocupecomtodoocódigocomplicadoqueestáescritonessearquivo,entenderemososignificadodecadaumadessaslinhasmaisafrentenocurso.

2.6OPRIMEIROPROGRAMAEMC# 9

Page 17: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Windows.Forms;

namespaceform{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}

privatevoidbutton1_Click(objectsender,EventArgse){

}}}

Otrechodecódigoquenosinteressanomomentoé:

privatevoidbutton1_Click(objectsender,EventArgse){

}

Todocódigoqueforcolocadodentrodaschavesseráexecutadoquandoobotãoforclicado.

No clique do botão, queremos executar o comando que mostra uma caixa de mensagens para ousuário.

MessageBox.Show(mensagem)

NoC#,todocomandodeveserterminadopelocaractere";".Portanto,ocódigoparamostraracaixademensagemficadaseguinteforma:

MessageBox.Show(mensagem);

Queremos que, ao clicar no botão, a mensagem Hello World seja exibida em uma caixa de

mensagens.Então,utilizaremososeguintecódigo:

privatevoidbutton1_Click(objectsender,EventArgse){MessageBox.Show(HelloWorld);}

Como a mensagem é somente um texto, o compilador do C# nos força a colocá-la entre aspasduplas.Portanto,ocódigodocliquedobotãoficaráassim:

privatevoidbutton1_Click(objectsender,EventArgse){MessageBox.Show("HelloWorld");

10 2.6OPRIMEIROPROGRAMAEMC#

Page 18: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

}

Ocódigocompletofica:

usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Windows.Forms;

namespaceform{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}

privatevoidbutton1_Click(objectsender,EventArgse){MessageBox.Show("HelloWorld");}}}

Nãosepreocupecomaslinhasdecódigoquenãoforamexplicadas.Entenderemosoqueelasfazemduranteocurso.

Aperte"F5"paraexecutarocódigodoformulário.Aoclicarno"button1",oresultadodeveseralgoparecidocomaimagemaseguir:

2.7EXERCÍCIOS

2.7EXERCÍCIOS 11

Page 19: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

1. Qualamensagemqueseráexibidanacaixadetextocriadapeloseguintecódigo?

MessageBox.Show("CursodeC#daCaelum");

HelloWorld

CursodeC#daCaelum

OláMundo

Caelum

Nenhumadasopções

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoC#eOrientaçãoaObjetos

Vimos que quando apertamos a tecla F5 do teclado dentro do Visual Studio, nosso programa éexecutado.Agoravamosentenderoqueaconteceu.

Quando pedimos para o Visual Studio executar uma aplicação, ele chama o compilador dalinguagem C# passando os arquivos de texto que contém o código da aplicação (código fonte doprograma). Caso o código fonte não tenha nenhum erro de sintaxe, o compilador gera o códigointermediário (CIL, Common Intermediate Language) que é entendido pela máquina virtual dalinguagem C#, a CLR (Common Language Runtime). O código CIL é colocado em um arquivoexecutável (arquivo com extensão .exe) dentro da pasta do projeto. Esse arquivo que é resultado dacompilaçãodoprogramaéchamadodeAssemblydentrodalinguagemC#.

Depoisdacompilação,oVisualStudioexecutaoassemblygeradonamáquinavirtualdoC#.ACLRporsuavezcarregaocódigoCILquefoigeradopelocompiladoreoexecutanosistemaoperacional,masseaCLRinterpretasseocódigoCILparalinguagemdemáquina,odesempenhodoC#nãoseriamuito bom, e por isso, quando um programa C# é carregado pela CLR ele já é automaticamente

VocêpodetambémfazerocursodatadessaapostilanaCaelum

2.8OQUEACONTECEUDURANTEAEXECUÇÃO?

12 2.8OQUEACONTECEUDURANTEAEXECUÇÃO?

Page 20: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

convertidopara linguagemdemáquinaporumprocessoconhecidocomoJIT(Just-in-time).EntãonoC#,ocódigosempreéexecutadocomomesmodesempenhodocódigodemáquina.

2.8OQUEACONTECEUDURANTEAEXECUÇÃO? 13

Page 21: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO3

Namaioriadosprogramasqueescrevemos,nãoestamosinteressadosemapenasmostrarumacaixademensagensparaousuário.Queremostambémarmazenareprocessarinformações.

Emumsistemabancário,porexemplo,estaríamosinteressadosemarmazenarosaldodeumacontaeonomedocorrentista.Paraarmazenaressesdados,precisamospedirparaoC# reservar regiõesdememória que serão utilizadas para armazenar informações.Essas regiões dememória são conhecidascomovariáveis.

As variáveis guardam informações de um tipo específico. Podemos, por exemplo, guardar umnúmerointeirorepresentandoonúmerodaconta,umtextopararepresentaronomedocorrentistaouumnúmerorealpararepresentarosaldoatualdaconta.Parautilizarumavariável,devemosprimeiramentedeclará-lanotextodoprograma.

Nadeclaraçãodeumavariável,devemosdizerseutipo(inteiro,textooureal,porexemplo)e,alémdisso,qualéonomequeusaremosparareferenciá-lanotextodoprograma.Paradeclararumavariáveldotipointeiroquerepresentaonúmerodeumaconta,utilizamososeguintecódigo:

intnumeroDaConta;

Repareno;nofinaldalinha.Comoadeclaraçãodeumavariáveléumcomandodalinguagem

C#,precisamosdo;paraterminá-lo.

Alémdo tipoint (para representar inteiros), temos tambémos tiposdouble efloat (para

númerosreais),string(paratextos),entreoutros.

Depois de declarada, uma variável pode ser utilizada para armazenar valores. Por exemplo, seestivéssemos interessados em guardar o valor 1 na variável numeroDaConta que declaramos

anteriormente,utilizaríamososeguintecódigo:

numeroDaConta=1;

Lê-se"numeroDaContarecebe1".Quando,nomomentodadeclaraçãodavariável, sabemosqualseráseuvalor,podemosutilizaraseguintesintaxeparadeclarareatribuirovalorparaavariável.

doublesaldo=100.0;

VARIÁVEISETIPOSPRIMITIVOS

3.1OPERAÇÕESCOMVARIÁVEIS

14 3VARIÁVEISETIPOSPRIMITIVOS

Page 22: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Agoraque já sabemoscomoguardar informaçõesnoprograma,estamos interessadosemexecutaroperaçõesnessesvalores.Podeserinteressanteparaumcorrentistasaberqualseráosaldodesuacontaapósumsaquede10reais.Pararealizaressaoperação,devemossubtrair10reaisdosaldodaconta:

doublesaldo=100.0;saldo=saldo-10.0;

Nessecódigo,estamosguardandonavariávelsaldoovalordaconta100.0(saldoantigo)menos

10.0entãoseuvalorfinalseráde90.0.Damesmaformaquepodemossubtrairvalores,podemos

tambémfazersomas(comooperador+),multiplicações(operador*)edivisões(operador/).

Podemosaindaguardarovalordosaqueemumavariável:

doublesaldo=100.0;doublevalorDoSaque=10.0;saldo=saldo-valorDoSaque;

Depois de realizar o saque, queremosmostrar para o usuário qual é o saldo atual da conta. Paramostrarmosessainformação,utilizaremosnovamenteoMessageBox.Show:

MessageBox.Show("Osaldodacontaapósosaqueé:"+saldo);

Veja que, no código do saque, estamos repetindo o nome da variável saldo dos dois lados daatribuição.Quandotemosessetipodecódigo,podemosutilizarumaabreviaçãodisponibilizadapeloC#,ooperador-=:

doublesaldo=100.0;doublevalorDoSaque=10.0;saldo-=valorDoSaque;

QuandoocompiladordoC#encontraosaldo-=valorDoSaque, essa linhaé traduzidaparaa

formaquevimosanteriormente:saldo=saldo-valorDoSaque.Alémdo-=, temostambémos

operadores+=(parasomas),*=(paramultiplicações)e/=(paradivisões).

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

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Agoraéamelhorhoradeaprenderalgonovo

3.1OPERAÇÕESCOMVARIÁVEIS 15

Page 23: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Vimos que noC# toda variável possui um tipo, utilizamos o int quando queremos armazenar

valores inteiros edouble para números reais. Agora vamos descobrir quais são os outros tipos de

variáveisdoC#.

Ostiposlistadosnessatabelasãoconhecidoscomotiposprimitivosouvaluetypes da linguagemC#. Toda vez que atribuímos um valor para uma variável de um tipo primitivo, o C# copia o valoratribuídoparadentrodavariável.

AgoraqueconhecemosostiposprimitivosdalinguagemC#,vamosvercomoéqueelesinteragemdentro de uma aplicação. Suponha que temos um código que declara uma variável do tipo inteiro edepoistentacopiarseuconteúdoparaumavariávellong:

intvalor=1;longvalorGrande=valor;

Nessecaso,comootamanhodeumavariávellongémaiordoqueodeumavariávelint,oC#

sabe que podemos copiar o seu conteúdo sem perder informações e, por isso, esse é um código quecompilasemnenhumerro.Agoravamostentarcopiarointparaumavariáveldotiposhort:

intvalor=1;shortvalorPequeno=valor;

3.2TIPOSPRIMITIVOS

16 3.2TIPOSPRIMITIVOS

Page 24: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Nessecódigo, tentamoscopiaroconteúdodeumavariávelmaiorparadentrodeumade tamanhomenor.Essacópiapodeserperigosapoisovalorqueestánavariáveldotipointpodenãocaberna

variávelshort e,por isso,ocompiladordoC#geraumerrodecompilaçãoquando tentamos fazer

essaconversão.

Para forçarmos o compilador do C# a fazer uma conversão perigosa, precisamos utilizar umaoperaçãodoC#chamadacastingfalandoparaqualtipoqueremosfazeraconversão.

intvalor=1;shortvalorPequeno=(short)valor;

Alémdostiposprimitivos,oC#tambémpossuiumtipoespecíficoparaarmazenartextos.Notipostring,podemosguardarqualquervalorquesejadelimitadoporaspasduplas,porexemplo:

stringmensagem="MinhaMensagem";MessageBox.Show(mensagem);

Podemosjuntarovalordeduasvariáveisdotipostringutilizandoooperador+dalinguagem.A

somadestringséumaoperaçãoconhecidacomoconcatenação.

stringmensagem="Olá";stringnome="victor";

MessageBox.Show(mensagem+nome);

Esse código imprime o texto Olá victor em uma caixa de mensagens. Podemos utilizar a

concatenaçãoparaadicionaroconteúdodequalquervariávelemumastring:

intidade=25;stringmensagem="suaidadeé:"+idade;

MessageBox.Show(mensagem);

Essesegundocódigoimprimeotextosuaidadeé:25.

QuandoqueremosdocumentarosignificadodealgumcódigodentrodeumprogramaC#,podemosutilizarcomentários.Parafazermosumcomentáriodeumalinha,utilizamoso//.Tudoque estiver

depoisdo//éconsideradocomentárioe,porisso,ignoradopelocompiladordalinguagem.

doublesaldo=100.0;//Issoéumcomentárioeseráignoradopelocompilador

Muitas vezes precisamos escrever diversas linhas de comentários para, por exemplo, documentarumalógicacomplexadaaplicação.Nessescasospodemosutilizarocomentáriodemúltiplaslinhasqueéinicializadoporum/*eterminadopelo*/.Tudoqueestiverentreaaberturaeofechamentodo

3.3ARMAZENANDOTEXTOEMVARIÁVEIS

3.4DOCUMENTANDOOCÓDIGOATRAVÉSDECOMENTÁRIOS

3.3ARMAZENANDOTEXTOEMVARIÁVEIS 17

Page 25: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

comentárioéignoradopelocompiladordalinguagem:

/*Issoéumcomentáriodemúltiplaslinhas*/

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

CasadoCódigo,ebookcompreçodeebook.

Faça o código dos exercícios do capítulo dentro de botões no formulário do projeto inicial, cadaexercíciodeveficarnaaçãodeumbotãodiferente.

1. Crie3variáveiscomasidadesdosseusmelhoresamigose/oufamiliares.Algocomo:

intidadeJoao=10;intidadeMaria=25;

Emseguida,pegueessas3idadesecalculeamédiadelas.ExibaoresultadoemumMessageBox.

2. Oqueacontececomocódigoabaixo?

intpi=3.14;

Ocódigocompila,e"pi"guardaonúmero3

Ocódigocompila,e"pi"guarda3.14(inteirospodemguardarcasasdecimais)

Ocódigonãocompila,pois3.14não"cabe"dentrodeuminteiro

3. Executeotrechodecódigoaseguir.Oqueacontececomele?

doublepi=3.14;intpiQuebrado=(int)pi;MessageBox.Show("piQuebrado="+piQuebrado);

Repareo(int).Estamos"forçando"aconversãododoubleparauminteiro.

EditoraCasadoCódigocomlivrosdeumaformadiferente

3.5EXERCÍCIOS

18 3.5EXERCÍCIOS

Page 26: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

QualovalordepiQuebradonessecaso?

3.14

0

3

4. (Opcional) No colegial, aprendemos a resolver equações de segundo grau usando a fórmula deBhaskara.Afórmulaéassim:

delta=b*b-4*a*c;a1=(-b+raiz(delta))/(2*a);a2=(-b-raiz(delta))/(2*a);

Crie um programa com três variáveis inteiras,a,b,c, com quaisquer valores. Depois crie 3

variáveisdouble,delta,a1,a2,comafórmulaanterior.

Imprimaa1ea2emumMessageBox.

Dica:Paracalcularraizquadrada,useMath.Sqrt(variavel).Nãoseesqueçaquenãopodemos

calculararaizquadradadenúmerosnegativos.

3.5EXERCÍCIOS 19

Page 27: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO4

Voltandoparanossoexemplodeaplicaçãobancária,queremospermitirumsaquesomenteseovaloraserretiradoformenorouigualaosaldodaconta,ouseja,seosaldodacontaformaiorouigualaovalordosaque,devemospermitiraoperação,docontrárionãopodemospermitirosaque.Precisamosfazerexecuçãocondicionaldecódigo.

NoC#,podemosexecutarcódigocondicionalutilizandoaconstruçãoif:

if(condicao){//Essecódigoseráexecutadosomenteseacondiçãoforverdadeira}

Nonossoexemplo,queremosexecutar a lógicade saqueapenas seo saldo formaiorou igual aovalordosaque:

doublesaldo=100.0;doublevalorSaque=10.0;if(saldo>=valorSaque){//códigodosaque.}

O código do saque deve diminuir o saldo da conta e mostrar uma mensagem para o usuárioindicandoqueosaqueocorreucomsucesso:

doublesaldo=100.0;doublevalorSaque=10.0;if(saldo>=valorSaque){saldo=saldo-valorSaque;MessageBox.Show("Saquerealizadocomsucesso");}

Repare que, se a conta não tiver saldo suficiente para o saque, o usuário não é avisado. Entãoestamos na seguinte situação: "Se a conta tiver saldo suficiente, quero fazer o saque, senão, queromostraramensagemSaldoInsuficienteparaousuário".Parafazerisso,podemosusaroelsedoC#:

if(saldo>=valorSaque){//códigodosaque}else

ESTRUTURASDECONTROLE

4.1TOMANDODECISÕESNOCÓDIGO

20 4ESTRUTURASDECONTROLE

Page 28: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

{MessageBox.Show("SaldoInsuficiente");}

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

Repare na expressão que passamos para o if: saldo >= valorSaque. Nele, utilizamos o

operador"maiorouigual".Alémdele,existemoutrosoperadoresdecomparaçãoquepodemosutilizar:maior (>),menor (<),menor ou igual (<=), igual (==) e diferente (!=). Podemos tambémnegar umacondiçãodeumifutilizandoooperador!nafrentedacondiçãoqueseránegada.

No capítulo anterior, vimos que um valor tem um tipo associado em C#: 10 é um int ,

"mensagem"éumastring.Damesmaforma,aexpressãosaldo>=valorSaquetambémtemum

tipo associado: o tipobool, que pode assumir os valores true (verdadeiro) ou false (falso).

Podemosinclusiveguardarumvalordessetiponumavariável:

boolpodeSacar=(saldo>=valorSaque);

Tambémpodemosrealizaralgumasoperaçõescomvaloresdotipobool.Podemos,porexemplo,

verificarseduascondiçõessãoverdadeirasaomesmotempousandoooperador&&(AND)parafazer

umelógico:

boolrealmentePodeSacar=(saldo>=valorSaque)&&(valorSaque>0);

QuandoprecisamosdeumOUlógico,utilizamosooperador||:

//essacondiçãoéverdadeirase(saldo>=valorSaque)fortrue//ouse(valorSaque>0)forverdadeiro.boolrealmentePodeSacar=(saldo>=valorSaque)||(valorSaque>0);

Assim,podemosconstruircondiçõesmaiscomplexasparaumif.Porexemplo,podemosusara

variávelrealmentePodeSacardeclaradanoifqueverificaseoclientepodesacarounão:

JáconheceoscursosonlineAlura?

4.2MAISSOBRECONDIÇÕES

4.2MAISSOBRECONDIÇÕES 21

Page 29: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

if(realmentePodeSacar){//códigodosaque}else{MessageBox.Show("SaldoInsuficiente");}

1. Qualéamensagemeovalordavariávelsaldoapósaexecuçãodoseguintecódigo?

doublesaldo=100.0;doublevalorSaque=10.0;if(saldo>=valorSaque){saldo-=valorSaque;MessageBox.Show("Saquerealizadocomsucesso");}else{MessageBox.Show("SaldoInsuficiente");}

mensagem:Saquerealizadocomsucesso;saldo:90.0

mensagem:SaldoInsuficiente;saldo90.0

mensagem:Saquerealizadocomsucesso;saldo:100.0

mensagem:SaldoInsuficiente;saldo100.0

mensagem:Saquerealizadocomsucesso;saldo:10.0

2. Qualéamensagemeovalordavariávelsaldoapósaexecuçãodoseguintecódigo?

doublesaldo=5.0;doublevalorSaque=10.0;if(saldo>=valorSaque){saldo-=valorSaque;MessageBox.Show("Saquerealizadocomsucesso");}else{MessageBox.Show("SaldoInsuficiente");}

mensagem:Saquerealizadocomsucesso;saldo:-5.0

mensagem:SaldoInsuficiente;saldo-5.0

mensagem:Saquerealizadocomsucesso;saldo:5.0

mensagem:SaldoInsuficiente;saldo5.0

4.3EXERCÍCIOSOPCIONAIS

22 4.3EXERCÍCIOSOPCIONAIS

Page 30: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

mensagem:Saquerealizadocomsucesso;saldo:10.0

3. Emalgunscasos,podemostermaisdeduasdecisõespossíveis.Obancopode,porexemplo,decidirquecontascomsaldomenorqueR$1000pagam1%detaxademanutenção,contascomsaldoentreR$1000eR$5000pagam5%econtascomsaldomaiorqueR$5000pagam10%.

Pararepresentaressetipodesituação,podemosusaroelseifdoC#,quefuncionaemconjunto

comoifquejáconhecemos.Vejacomoficariaasituaçãodescritaanteriormente:

doubletaxa;if(saldo<1000){taxa=0.01;}elseif(saldo<=5000){taxa=0.05;}else{taxa=0.1;}

OC#vaiprocessarascondiçõesnaordem,atéencontrarumaquesejasatisfeita.Ouseja,nasegundacondiçãodocódigo,sóprecisamosverificarquesaldoémenorouigualaR$5000,poisseoC#

chegarnessacondiçãoéporqueelenãoentrounoprimeiroif, istoé, sabemosqueosaldo é

maiorouigualaR$1000nesseponto.

Combasenisso,qualvaiseramensagemexibidapelocódigoseguinte?

doublesaldo=500.0;if(saldo<0.0){MessageBox.Show("Vocêestánonegativo!");}elseif(saldo<1000000.0){MessageBox.Show("Vocêéumbomcliente");}else{MessageBox.Show("Vocêémilionário!");}

"Vocêestánonegativo!"

"Vocêéumbomcliente"

Nenhumamensagem

"Vocêémilionário!"

"Vocêéumbomcliente",seguidade"Vocêémilionário!"

4.3EXERCÍCIOSOPCIONAIS 23

Page 31: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

4. Uma pessoa só pode votar em eleições brasileiras se ela for maior que 16 anos e for cidadãbrasileira.Crieumprogramacomduasvariáveis,intidade,boolbrasileira,efaçacomque

oprogramadigaseapessoaestáaptaavotarounão,deacordocomosdadosnasvariáveis.

5. Crie umprogramaque tenhaumavariáveldoublevalorDaNotaFiscal e, de acordo com esse

valor,oimpostodevesercalculado.Asregrasdecálculosão:

Seovalorformenorouiguala999,oimpostodeveserde2%Seovalorestiverentre1000e2999,oimpostodeveserde2.5%Seovalorestiverentre3000e6999,oimpostodeveserde2.8%

Seformaiorouiguala7000,oimpostodeveserde3%

ImprimaoimpostoemumMessageBox.

6. (Desafio)Dadooseguintecódigo:

intvalor=15;stringmensagem="";if(valor>10){mensagem="Maiorquedez";}else{mensagem="Menorquedez;}MessageBox.Show(mensagem);

Existeumaformade fazero ifdessecódigouma linhasó, semusar apalavra if e else.Pesquisesobreissoetentefazer.

24 4.3EXERCÍCIOSOPCIONAIS

Page 32: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO5

De volta ao exemplo da aula anterior, suponha agora que o cliente dessemesmo banco queira saberquanto ele ganhará, ao final de 1 ano, caso ele invista um valor. O investimento paga 1% do valorinvestidoaomês.

Porexemplo,seoclienteinvestirR$1000,00,aofinalde12meses,teráporvoltadeR$1126,82:noprimeiromês,R$1000,00+R$1000,001%=R$1010,00;nosegundomês,R$1010,00+R$1010,001% =R$ 1020,10; e assim por diante. Ou seja, para calcular o quanto ele terá ao final de um ano,podemosmultiplicarovalorinvestido12vezespor1%.

Pararesolvermosesseproblema,precisamosfazerusodeumaestruturadecontrolequerepeteumdeterminadoblocodecódigoatéqueumacondiçãosejasatisfeita.Essaestruturarecebeonomedeloop.

ParafazerumloopnoC#,utilizaremos,inicialmente,ainstruçãofor.Oforéumainstruçãoque

possuitrêspartes:

Aprimeira parte é a inicialização, na qual podemos declarar e inicializar uma variável que seráutilizadanofor;

A segunda parte é a condição do loop. Enquanto a condição do loop for verdadeira, o loopcontinuaráexecutando;Aterceiraparteéaatualização,naqualpodemosatualizarasvariáveisquesãoutilizadaspelofor.

Cadaumadaspartesdoforéseparadaporum;.

for(inicialização;condição;atualização){//Essecódigoseráexecutadoenquantoacondiçãoforverdadeira}

Vejaocódigoaseguir,porexemplo,emqueusamosumforquerepetiráocálculo12vezes:

doublevalorInvestido=1000.0;for(inti=1;i<=12;i+=1){valorInvestido=valorInvestido*1.01;}MessageBox.Show("Valorinvestidoagoraé"+valorInvestido);

ESTRUTURASDEREPETIÇÃO

5.1REPETINDOUMBLOCODECÓDIGO

5ESTRUTURASDEREPETIÇÃO 25

Page 33: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Vejaquenossoforcomeça inicializandoavariáveli com1e repeteo códigodedentrodele

enquantoovalordeiformenorouiguala12,ouseja,elesóparanomomentoemqueiformaior

doque12.Evejaque,acadaiteraçãodesseloop,ovalordeicresce(i+=1).Nofim,ocódigode

dentrodoforserárepetido12vezes,comoprecisávamos.

Omesmoprogramapoderiaserescritoutilizando-seumwhile,emvezdeumfor:

doublevalorInvestido=1000.0;inti=1;while(i<=12){valorInvestido=valorInvestido*1.01;i+=1;}MessageBox.Show("Valorinvestidoagoraé"+valorInvestido);

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoC#eOrientaçãoaObjetos

No C# quando utilizamos o while, a condição do loop é checada antes de todas as voltas

(iterações)dolaço,masesequiséssemosgarantirqueocorpodolaçosejaexecutadopelomenosumavez?Nessecaso,podemosutilizarumoutrotipodelaçodoC#queéodowhile:

do{//corpodoloop}while(condição);

Comodowhile a condiçãodo loop só é checadano fimdavolta, ou seja, o corpodo loop é

executado e depois a condição é checada, então o corpo do do...while sempre é executado pelo

menosumavez.

VocêpodetambémfazerocursodatadessaapostilanaCaelum

5.2PARASABERMAISDOWHILE

5.3PARASABERMAISINCREMENTOEDECREMENTO

26 5.2PARASABERMAISDOWHILE

Page 34: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Quandoqueremosincrementarovalordeumavariávelinteiraemumaunidade,vimosquetemos2opções:

intvalor=1;

valor=valor+1;//ouvalor+=1;

Porém,comoincrementarovalordeumavariáveléumaatividadecomumnaprogramação,oC#nosofereceooperador++pararealizaressetrabalho:

intvalor=1;valor++;

Temosaindaooperador--querealizaodecrementodeumavariável.

1. Qualéovalorexibidonoseguintecódigo:

inttotal=2;for(inti=0;i<5;i+=1){total=total*2;}MessageBox.Show("Ototalé:"+total);

256

64

128

512

2. FaçaumprogramaemC#queimprimaasomadosnúmerosde1até1000.

3. FaçaumprogramaemC#queimprimatodososmúltiplosde3,entre1e100.

Parasaberseumnúmeroémúltiplode3,vocêpodefazerif(numero%3==0).

4. (Opcional) Escreva um programa em C# que some todos os números de 1 a 100, pulando osmúltiplosde3.OprogramadeveimprimiroresultadofinalemumMessageBox.

Qualoresultado?

5. (Opcional)EscrevaumprogramaemC#queimprimetodososnúmerosquesãodivisíveispor3oupor4entre0e30.

6. (Opcional)FaçaumprogramaemC#queimprimaosfatoriaisde1a10.

5.4EXERCÍCIOS

5.4EXERCÍCIOS 27

Page 35: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Ofatorialdeumnúmeronénn-1n-2...atén=1.

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++){

}

7. (Opcional)FaçaumprogramaemC#queimprimaosprimeirosnúmerosdasériedeFibonacciatépassarde100.AsériedeFibonacciéaseguinte:0,1,1,2,3,5,8,13,21etc...Paracalculá-la,oprimeiroelementovale0,osegundovale1,daípordiante,on-ésimoelementovaleo(n-1)-ésimoelementosomadoao(n-2)-ésimoelemento(ex:8=5+3).

8. (Opcional)Façaumprogramaqueimprimaaseguintetabela,usandoforsencadeados:

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

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

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

28 5.4EXERCÍCIOS

Page 36: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO6

Neste momento, queremos representar diversas contas em nosso banco. Uma conta bancária égeralmentecompostaporumnúmero,nomedotitularesaldo.Podemosguardaressasinformaçõesemvariáveis:

intnumeroDaConta1=1;stringtitularDaConta1="JoaquimJosé";doublesaldoDaConta1=1500.0;

Pararepresentaroutroscorrentistas,precisamosdenovasvariáveis:

intnumeroDaConta2=2;stringtitularDaConta2="SilvaXavier";doublesaldoDaConta2=2500.0;

Vejaque,comoasinformaçõesdascontasestãoespalhadasemdiversasvariáveisdiferentes,émuitofácilmisturarmosessasinformaçõesdentrodocódigo.Alémdisso,imaginequeantesdeadicionarmosacontanaaplicaçãoprecisamosfazerumavalidaçãodoCPFdotitular.Nessecasoprecisaríamoschamaruma função que executa essa validação, mas como podemos garantir que essa validação sempre éexecutada?

Esses pontos listados são alguns dos problemas do estilo de programação procedural. Quandotrabalhamoscomprogramaçãoprocedural,osdadosdaaplicaçãoficamseparadosdaimplementaçãodaslógicasdenegócioe,alémdisso,émuitodifícilgarantirasvalidaçõesdosdadosdaaplicação.

Paracomeçarmoscomaorientaçãoaobjetos,vamosinicialmentepensarquaissãoasinformaçõesquedescrevemumadeterminadaConta.Toda conta bancária possui umnúmero, titular e saldo.Pararepresentarmosacontacomessasinformaçõesdentrodoprojeto,noC#,precisamoscriarumaclasse.DentrodoC#adeclaraçãodaclasseéfeitautilizando-seapalavraclassseguidadonomedaclassequequeremosimplementar:

classConta{

}

OcódigodaclasseConta,porconvenção,deveficardentrodeumarquivocomomesmonomeda

classe,entãoaclasseContaserácolocadoemarquivochamadoConta.cs.

CLASSESEOBJETOS

6.1ORGANIZANDOOCÓDIGOCOMOBJETOS

6CLASSESEOBJETOS 29

Page 37: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Dentro dessa classe queremos armazenar as informações que descrevem as contas, fazemos issodeclarandovariáveisdentrodaclasse,essasvariáveissãoosatributos:

classConta{intnumero;stringtitular;doublesaldo;}

Porém,paraqueocódigodaaplicaçãopossalereescrevernessesatributos,precisamosdeclará-losutilizandoapalavrapublic:

classConta{//numero,titularesaldosãoatributosdoobjetopublicintnumero;publicstringtitular;publicdoublesaldo;}

Parautilizarmosaclassequecriamosdentrodeumaaplicaçãowindowsform,precisamoscriarumanovacontanocódigodoformulário,fazemosissoutilizandoainstruçãonewdoC#:

//códigodoformulárioprivatevoidbutton1_Click(objectsender,EventArgse){newConta();}

QuandoutilizamosonewdentrodocódigodeumaclasseestamospedindoparaoC#criaruma

novainstânciadeContanamemória,ouseja,oC#alocarámemóriasuficienteparaguardartodasas

informaçõesdaContadentrodamemóriadaaplicação.

Além disso, o new possuimais uma função, devolver a referência, uma seta que aponta para oobjeto emmemória, que será utilizada para manipularmos a Conta criada. Podemos guardar essa

referênciadentrodeumavariáveldotipoConta:

//códigodoformulárioprivatevoidbutton1_Click(objectsender,EventArgse){Contac=newConta();}

Namemóriadaaplicaçãoteremosumasituaçãoparecidacomailustradanaimagemaseguir:

30 6.1ORGANIZANDOOCÓDIGOCOMOBJETOS

Page 38: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

VejaqueaclassefuncionacomoumareceitaqueensinaqualéoformatodeumaContadentroda

aplicação.AContaquefoicriadanamemóriapelooperadornewéchamadadeinstânciaouobjeto.

E agora para definirmos os valores dos atributos que serão armazenados naConta, precisamos

acessaroobjetoquevivenamemória.Fazemosissoutilizandoooperador.doC#,informandoqualéoatributo que queremos acessar. Para, por exemplo, guardarmos o valor 1 comonúmero da conta quecriamos,utilizamosocódigoaseguir:

//códigodoformulárioprivatevoidbutton1_Click(objectsender,EventArgse){Contac=newConta();c.numero=1;}

Com esse código, estamos navegando na referência armazenada na variável c, e acessando o

campo número do objeto Conta que vive na memória. Dentro desse campo colocamos o valor 1.

PodemosfazeromesmoparaosoutroscamposdaConta:

privatevoidbutton1_Click(objectsender,EventArgse){Contac=newConta();c.numero=1;c.titular="victor";c.saldo=100;}

Depoisdaexecuçãodessecódigo,teremosaseguintesituaçãonamemóriadaaplicação:

6.1ORGANIZANDOOCÓDIGOCOMOBJETOS 31

Page 39: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Veja que, quando utilizamos um objeto para guardar informações, todos os atributos ficamagrupados dentro de um único objeto na memória, e não espalhados dentro de diversas variáveisdiferentes.

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

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Agoraqueconseguimoscriaraprimeiracontadaaplicação,vamostentarfazeralgumasoperações.Aprimeiraoperaçãoquequeremosimplementaréaoperaçãodetirardinheirodaconta.Paraisso,comovimosnocapítuloanterior,podemosutilizarooperador-=doC#:

Contac=newConta();c.numero=1;c.titular="victor";c.saldo=100;//acontaterminacomsaldode50.0

Agoraéamelhorhoradeaprenderalgonovo

6.2EXTRAINDOCOMPORTAMENTOSATRAVÉSDEMÉTODOS

32 6.2EXTRAINDOCOMPORTAMENTOSATRAVÉSDEMÉTODOS

Page 40: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

c.saldo-=50.0;

Masoqueaconteceriasetentássemostirarmais100.0dessaconta?

c.saldo-=100.0;

Ao executarmos essa segunda operação, a conta terminará com saldo de -50.0, porém nesse

sistemaascontasnãopodemficarcomsaldonegativo!Portanto,antesde tirarmosdinheirodaconta,precisamosverificarseelapossuisaldosuficiente.

if(c.saldo>=100.0){c.saldo-=100.0;}

Repare que teremos que copiar e colar essa verificação em todos os pontos da aplicação emquedesejamos fazer um saque,mas o que aconteceria se fosse necessário cobrar uma taxa em todos ossaques?Teríamosquemodificartodosospontosemqueocódigofoicopiado.SeriamaisinteressanteisolaressecódigodentrodeumcomportamentodaConta.

Alémdeatributos,osobjetos tambémpodempossuirmétodos.Osmétodos sãoblocosdecódigoqueisolamlógicasdenegóciodoobjeto.EntãopodemosisolaralógicadosaquedentrodeummétodoSacadaclasseConta.

ParadeclararummétodochamadoSacanaclasseConta,utilizamosaseguintesintaxe:

classConta{//declaraçãodosatributos

publicvoidSaca(){//Implementaçãodométodo}}

DentrodessemétodoSaca,colocaremosocódigodalógicadesaque.

publicvoidSaca(){if(c.saldo>=100.0){c.saldo-=100.0;}}

Porém, nesse código temos dois problemas: não podemos utilizar a variável c , pois ela foi

declaradanoformulárioenãodentrodométodoeovalordosaqueestáconstante.

NessemétodoSaca, queremos verificar o saldo da conta em que ométodo foi invocado. Para

acessarmos a referência em que um determinadométodo foi chamado, utilizamos a palavra this.

Entãoparaacessarmososaldodaconta,podemosutilizarthis.saldo:

6.2EXTRAINDOCOMPORTAMENTOSATRAVÉSDEMÉTODOS 33

Page 41: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

publicvoidSaca(){if(this.saldo>=100.0){this.saldo-=100.0;}}

PodemosutilizaroSacadentrodoformuláriocomoseguintecódigo:

Contac=newConta();//inicializaasinformaçõesdacontac.saldo=100.0;

//AgorachamaométodoSacaquefoidefinidonaclassec.Saca();

Agoravamosresolveroproblemadovalorfixodosaque.Quandoqueremospassarumvalorparaummétodo,precisamospassaressevalordentrodosparêntesesdachamadadométodo:

Contac=newConta();//inicializaasinformaçõesdacontac.saldo=100.0;

//AgorachamaométodoSacaquefoidefinidonaclassec.Saca(10.0);

PararecebermosovalorquefoipassadonachamadadoSaca,precisamosdeclararumargumentonométodo.Oargumentoéumavariáveldeclaradadentrodosparêntesesdométodo:

publicvoidSaca(doublevalor){if(this.saldo>=valor){this.saldo-=valor;}}

Ummétodopodeterqualquernúmerodeargumentos.Precisamosapenassepararadeclaraçãodasvariáveiscomumavírgula.

AgoraquecolocamosométodoSacadentrodaclasseConta,nãoprecisamosreplicarocódigode

validaçãodosaqueemtodosospontosdocódigo,podemossimplesmenteutilizarométodocriado,alémdisso, seprecisarmosmodificar a lógicado saque,podemos simplesmenteatualizarocódigodaquelemétodo,umúnicopontodosistema.

Masdaformaquefoi implementado,ousuáriodessemétodonãosabeseosaquefoiounãobemsucedido.Precisamosfazercomqueométododevolvaumvalorbooleanoindicandoseaoperaçãofoiounãobemsucedida.Devolveremostruecasoaoperaçãosejabemsucedidaefalsecasocontrário.

Quandoummétododevolveumvalor,otipodovalordevolvidodeveficarantesdonomedométodo

6.3DEVOLVENDOVALORESDEDENTRODOMÉTODO

34 6.3DEVOLVENDOVALORESDEDENTRODOMÉTODO

Page 42: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

emsuadeclaração.Quandoummétodonãodevolvevaloralgum,utilizamosotipovoid.

//EstamosdeclarandoqueométododevolveumvalordotipoboolpublicboolSaca(doublevalor){//implementaçãodométodo}

Dentrodaimplementaçãodométodo,devolvemosumvalorutilizamosapalavrareturnseguidadovalorquedeveserdevolvido.EntãoaimplementaçãodoSacaficadaseguinteforma:

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

Quando o C# executa um return, ele imediatamente devolve o valor e sai do método, então

podemossimplificaraimplementaçãodoSacapara:

publicboolSaca(doublevalor){if(this.saldo>=valor){this.saldo-=valor;returntrue;}returnfalse;}

Noformuláriopodemosrecuperarovalordevolvidoporummétodo.

Contac=newConta();//inicializaosatributos

//Seacontativersaldosuficiente,deuCertoconteráovalortrue//senão,elaconteráfalsebooldeuCerto=c.Saca(100.0);

if(deuCerto){MessageBox.Show("Saquerealizadocomsucesso");}else{MessageBox.Show("SaldoInsuficiente");}

Oupodemosutilizaroretornodométododiretamentedentrodoif:

Contac=newConta();//inicializaosatributos

6.3DEVOLVENDOVALORESDEDENTRODOMÉTODO 35

Page 43: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

if(c.Saca(100.0)){MessageBox.Show("Saquerealizadocomsucesso");}else{MessageBox.Show("SaldoInsuficiente");}

Agoraque terminamosde implementara lógicadesaquedaconta,vamos tambémimplementarométododedepósito.Essemétodonãodevolveránenhumvalorereceberáumdoublecomoargumento:

publicvoidDeposita(doublevalor){this.saldo+=valor;}

Noformulárioprincipaldaaplicação,podemosinicializarosaldoinicialcomométodoDeposita:

Contac=newConta();c.Deposita(100.0);

Nesse código estamos tentando depositar 100 reais em uma conta que acabou de ser criada e ométodoDepositatentasomaros100.0novalorinicialdoatributosaldodaconta.Masqualéovalor

inicialdeumatributo?

QuandodeclaramosumavariávelnoC#,elacomeçacomumvalor indefinido, logonãopodemosutilizá-laenquantoseuvalornãoforinicializado,porémalinguagemtrataosatributosdeumaclassedeforma diferenciada. Quando instanciamos uma classe, todos os seus atributos são inicializados paravalores padrão. Valores numéricos são inicializados para zero, o bool é inicializado para false e

atributosqueguardamreferênciassãoinicializadosparaareferênciavazia(valornulldoC#).

Então,noexemplo,quandodepositamos100reaisnacontarecém-criada,estamossomando100nosaldoinicialdaconta,queézero,edepoisguardandooresultadodevoltanosaldodaconta.

Podemos mudar o valor padrão de um determinado atributo colocando um valor inicial em suadeclaração.Parainicializarmosacontacomsaldoinicialde100reaisaoinvésdezero,podemosutilizaroseguintecódigo:

classConta{publicdoublesaldo=100.0;

//outrosatributosemétodosdaclasse}

Agoratodacontacriadajácomeçarácomumsaldoinicialde100.0.

6.4VALORPADRÃODOSATRIBUTOSDACLASSE

36 6.4VALORPADRÃODOSATRIBUTOSDACLASSE

Page 44: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

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

CasadoCódigo,ebookcompreçodeebook.

Agoravamostentarimplementaraoperaçãodetransferênciadedinheiroentreduascontas.DentrodaclasseContacriaremosmaisummétodochamadoTransfere,essemétodoreceberáovalorda

transferênciaeascontasqueparticiparãodaoperação:

publicvoidTransfere(doublevalor,Contaorigem,Contadestino){//implementaçãodatransferência}

Mas será que realmente precisamos receber as duas contas como argumento do métodoTransfere?Vamosvercomoessemétodoseráutilizadodentrodocódigodoformulário:

Contavictor=newConta();//inicializaçãodacontavictor.saldo=1000;

Contaguilherme=newConta();//inicializaçãodaconta

//Agoravamostransferirodinheirodacontadovictorparaadoguilhermevictor.Transfere(10.0,victor,guilherme);

Reparequenousodométodoestamosrepetindoduasvezesavariávelvictor,porémissonãoé

necessário. Podemos utilizar o this para acessar a conta de origem dentro do método, então na

verdadeométodoTransfereprecisareceberapenasacontadedestino:

publicvoidTransfere(doublevalor,Contadestino){//implementaçãodatransferência}

Antes de tirarmos dinheiro da conta de origem (this), precisamos verificar se ela tem saldo

EditoraCasadoCódigocomlivrosdeumaformadiferente

6.5MAISUMEXEMPLO:TRANSFERE

6.5MAISUMEXEMPLO:TRANSFERE 37

Page 45: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

suficiente, somentenessecasoqueremossacarodinheirodacontadeorigemedepositarnacontadedestino:

publicvoidTransfere(doublevalor,Contadestino){if(this.saldo>=valor){this.saldo-=valor;destino.saldo+=valor;}}

Masessecomportamentodeverificarseaconta temsaldosuficienteantesderealizarosaqueéocomportamentodométodoSacaquefoiimplementadoanteriormente,alémdisso,somarumvalorno

saldoéaoperaçãoDepositadaconta.Portanto,podemosutilizarosmétodosSaca eDeposita

existentesparaimplementaroTransfere:

publicvoidTransfere(doublevalor,Contadestino){if(this.Saca(valor)){destino.Deposita(valor);}}

Quando criamos uma classe, é importante lembrarmos que seu código será lido por outrosdesenvolvedoresdaequipee,porisso,érecomendávelseguirpadrõesdenomenclatura.

Quandocriamosumaclasse,arecomendaçãoéutilizaroPascalCasingparanomearaclasse:

Seonomedaclasseécompostoporumaúnicapalavra,colocamosaprimeiraletradessapalavraemmaiúscula(contasetornaConta);

Seonomeécompostopordiversaspalavras,juntamostodasaspalavrascolocandoaprimeiraletradecadapalavraemmaiúscula(segurodevidasetornaSeguroDeVida).

Nocasodonomedemétodos,aconvençãotambéméutilizaroPascalCasing(SacaeDeposita,porexemplo).

Paraargumentosdemétodos,arecomendaçãoéutilizaroPascalCasingporémcomaprimeiraletraemminúscula(valorDoSaque,porexemplo),umaconvençãochamadaCamelCasing.

VocêpodeencontrarasrecomendaçõesdaMicrosoftnesselink:http://msdn.microsoft.com/en-us/library/ms229040(v=vs.110).aspx

6.6CONVENÇÃODENOMES

6.7EXERCÍCIOS

38 6.6CONVENÇÃODENOMES

Page 46: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

1. Oqueumaclassetem?

Sóosatributosdeumaentidadedosistema;

Sóatributosousómétodosdeumaentidadedosistema;

Sóosmétodosdeumaentidadedosistema;

Atributosemétodosdeumaentidadedosistema.

2. VamoscriaraclasseContadentrodoprojetoinicialutilizandooVisualStudio.

No Visual Studio clique com o botão direito no nome do projeto e selecione a opção Add >

Class...

DentrodajanelaabertapeloVisualStudio,precisamosdefinirqualéonomedaclassequequeremoscriar.EscolhaonomeConta:

6.6CONVENÇÃODENOMES 39

Page 47: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Depoisdecolocaronomedaclasse, cliquenobotãoAdd.Com isso, oVisualStudio criará um

novoarquivodentrodoProjeto,oConta.cs.TodoocódigodaclasseContaficarádentrodesse

arquivo:

classConta{//Ocódigodaclasseficaaquidentro!}

Agora declare os seguintes atributos dentro da Conta:saldo (double), titular (string) e

numero(int).

3. QualdoscomandosaseguirinstanciaumanovaConta?

Contaconta=Conta();

Contaconta=newConta();

Contaconta=Conta.new();

4. Levandoemconsideraçãoocódigo:

Contac=newConta();c.saldo=1000.0;

Qualdaslinhasaseguiradiciona200reaisnessesaldo?

saldo+=200;

c.saldo+=200;

Contac.saldo+=200;

40 6.6CONVENÇÃODENOMES

Page 48: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Conta.saldo+=200;

5. AgoravamostestaraclasseContaqueacabamosdecriar.Coloqueumnovobotãonoformulário

da aplicação. Dê um duplo clique nesse botão para definirmos qual será o código executado nocliquedobotão.

privatevoidbutton1_Click(objectsender,EventArgse){//açãodobotãoaqui.}

Dentrodocódigodessebotão,instancieumanovaContaetentefazeralgunstestespreenchendoe

mostrandoseusatributosatravésdoMessageBox.Show.Porexemplo:

privatevoidbutton1_Click(objectsender,EventArgse){ContacontaVictor=newConta();contaVictor.titular="victor";contaVictor.numero=1;contaVictor.saldo=100.0;

MessageBox.Show(contaVictor.titular);}

Tente fazer testes com diversas contas e veja que cada instância de conta possui seus própriosatributos.

6. AgoravamosimplementarmétodosnaclasseConta.ComeçaremospelométodoDeposita,esse

métodonãodevolvenadaedeve receberumargumentodo tipodouble que é o valor que será

depositadonaConta.Asuaclassedeveficarparecidacomaquesegue:

//dentrodoarquivoConta.cs

classConta{//declaraçãodosatributos

publicvoidDeposita(doublevalor){//oquecolocaraquinaimplementação?}}

DepoisdeimplementarométodoDeposita, implemente tambémométodoSaca.Ele também

nãodevolvevaloralgumerecebeumdoublequeéovalorqueserásacadodaconta.

7. Agoravamostestarosmétodosqueacabamosdecriar.Naaçãodobotãoqueutilizamosparatestaraconta,vamosmanipularosaldoutilizandoosmétodosDepositaeSaca:

privatevoidbutton1_Click(objectsender,EventArgse){ContacontaVictor=newConta();contaVictor.titular="victor";contaVictor.numero=1;

6.6CONVENÇÃODENOMES 41

Page 49: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

contaVictor.Deposita(100);MessageBox.Show("Saldo:"+contaVictor.saldo);contaVictor.Saca(50.0);MessageBox.Show("Saldo:"+contaVictor.saldo);}

Tente fazer depósitos e saques em várias instâncias diferentes deConta, repare que dentro dos

métodosavariávelthispossuiovalordareferênciaemqueométodofoiinvocado.

8. Qualasaídadocódigoaseguir:

Contamauricio=newConta();mauricio.saldo=2000.0;

Contaguilherme=newConta();guilherme.saldo=5000.0;

mauricio.saldo-=200.0;guilherme.saldo+=200.0;

MessageBox.Show("mauricio="+mauricio.saldo);MessageBox.Show("guilherme="+guilherme.saldo);

mauricio=2200.0eguilherme=4800.0

mauricio=2200.0eguilherme=5200.0

mauricio=1800.0eguilherme=5000.0

mauricio=1800.0eguilherme=5200.0

9. Qualasaídadocódigoaseguir?

Contamauricio=newConta();mauricio.numero=1;mauricio.titular="Mauricio";mauricio.saldo=100.0;

Contamauricio2=newConta();mauricio2.numero=1;mauricio2.titular="Mauricio";mauricio2.saldo=100.0;

if(mauricio==mauricio2){MessageBox.Show("Ascontassãoiguais");}else{MessageBox.Show("Ascontassãodiferentes");}

Ascontassãoiguais

Ascontassãodiferentes

Nãoémostradonenhumamensagem

42 6.6CONVENÇÃODENOMES

Page 50: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

10. Qualasaídadocódigoaseguir:

Contamauricio=newConta();mauricio.saldo=2000.0;

Contacopia=mauricio;copia.saldo=3000.0;

MessageBox.show("mauricio="+mauricio.saldo);MessageBox.show("copia="+copia.saldo);

mauricio=2000.0ecopia=3000.0

mauricio=3000.0ecopia=2000.0

mauricio=2000.0ecopia=2000.0

mauricio=3000.0ecopia=3000.0

11. (Opcional) Implemente ométodo Transfere que recebe o valor da transferência e a conta de

destino.FaçacomqueelereutilizeasimplementaçõesdosmétodosSacaeDeposita.

12. (Opcional)Vamos adicionar uma validação nométodo Saca da Conta. Modifique o método

Saca para que ele não realize o saque caso o saldo atual da conta sejamenor do que o valor

recebidocomoargumento.

13. (Opcional)ModifiqueométodoSacacomvalidaçãoparaqueeledevolvaovalortrue casoo

saque tenha sido realizado com sucesso efalse caso contrário.Depoismodifique o código do

botãodetestedacontaparaqueeleutilizeovalordevolvidopelométodoSacaparamostraruma

mensagemparaousuário.Casoosaquesejabemsucedido,queremosmostraramensagem"Saquerealizadocomsucesso",senão,mostraremos"Saldoinsuficiente"

14. (Opcional)AgoraaltereométodoSacadaclasseConta.LimiteovalordosaqueparaR$200,00

casooclientesejamenordeidade.

Lembre-sequeaindaénecessáriovalidarseovalorasersacadoémenorouigualaosaldoatualdoclienteeémaiordoqueR$0,00.

6.6CONVENÇÃODENOMES 43

Page 51: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

Quandoabrimosumacontanobanco,temosquefornecerumasériedeinformações:nome,CPF,RGeendereço.

Vimosquequandoqueremosarmazenarinformaçõesemumaclasse,devemoscriaratributos.Masem qual classe colocar esses novos atributos? Claramente essas informações não pertencem a umaConta.Essesdadospertencemaotitulardaconta,ouseja,essasinformaçõespertencemaoclientedo

banco.

Entãodevemosarmazená-lasemumaclasseCliente.

classCliente{publicstringnome;publicstringcpf;publicstringrg;publicstringendereco;}

Sabemostambémquetodacontaestáassociadaaumcliente,ouseja,acontaguardaumareferênciaaoclienteassociado.

classConta{//outrosatributosdaConta

publicClientetitular;

//comportamentosdaconta}

Agora,quandovamoscriarumaconta,podemostambémcolocarseutitular.

Clientevictor=newCliente();

JáconheceoscursosonlineAlura?

6.8COMPOSIÇÃODECLASSES

44 6.8COMPOSIÇÃODECLASSES

Page 52: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

victor.nome="victor";

ContaumaConta=newConta();umaConta.titular=victor;

Vimos também que o atributo titular guarda uma referência(seta) para uma instância de

Cliente (objeto namemória). Logo, a atribuiçãoumaConta.titular=victor está copiando a

referênciadavariávelvictorparaoatributotitular.

PodemosmodificarosatributosdoClienteatravésdareferênciaguardadanoatributotitular

daConta.

Clientevictor=newCliente();victor.nome="victor";

ContaumaConta=newConta();umaConta.titular=victor;

umaConta.titular.rg="12345678-9";

//MostraonomevictorMessageBox.Show(umaConta.titular.nome);

//Mostraotexto12345678-9MessageBox.Show(victor.rg);

1. Crie a classe Cliente contendo os atributos nome (string), rg (string), cpf (string) e

endereco(string).ModifiqueaclasseContaefaçacomqueseuatributotitularsejadotipo

Clienteaoinvésdestring.

Tome cuidado.Após essamodificação não poderemos atribuir o nome do cliente diretamente aoatributotitulardaConta.Paradefinironomedotitular,precisaremosdeumcódigoparecido

comoquesegue:

Contaconta=newConta();Clientecliente=newCliente();conta.titular=cliente;conta.titular.nome="Victor";

2. Qualasaídaqueseráimpressaaoexecutaroseguintetrechodecódigo?

ContaumaConta=newConta();Clienteguilherme=newCliente();guilherme.nome="GuilhermeSilveira";umaConta.titular=guilherme;

MessageBox.Show(umaConta.titular.nome);

GuilhermeSilveira

Serámostradoumacaixademensagemsemnenhumamensagem

6.9EXERCÍCIOS

6.7EXERCÍCIOS 45

Page 53: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Ocódigonãocompila

3. Qualasaídaqueseráimpressaaoexecutaroseguintetrechodecódigo?

ContaumaConta=newConta();Clienteguilherme=newCliente();guilherme.rg="12345678-9";

umaConta.titular=guilherme;umaConta.titular.rg="98765432-1";

MessageBox.Show(guilherme.rg);

98765432-1

12345678-9

rg

Nãoseráimpressonada

4. (Opcional)CriemaisumatributonaclasseClientequeguardaaidadedapessoa.Nonossocaso,

aidadeéumnúmerointeiro.

Tambémcrieumcomportamento(método)comonomeEhMaiorDeIdadenaclasseClienteque

não recebenenhumargumentoe retornaumbooleano indicando seo cliente émaiorde idadeounão.QuandoumapessoaémaiordeidadenoBrasil?

46 6.9EXERCÍCIOS

Page 54: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO7

Nessemomento, nossa classe Conta possui um numero, saldo e cliente titular, além de

comportamentosquepermitemsacaredepositar:

classConta{publicintnumero;publicdoublesaldo;

publicClientetitular;

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

publicvoidDeposita(doublevalor){this.saldo+=valor;}}

SedesejamosefetuarumsaqueouumdepósitoemumaContaqualquer,fazemos:

conta.Saca(100.0);conta.Deposita(250.0);

Masoqueaconteceseummembrodaequipefaz:

conta.saldo-=100.0;

Nada nos impede de acessar os atributos diretamente. Em três partes distintas do nosso softwaretemostalcódigo:

//emumarquivoconta.saldo-=100.0;

//emoutroarquivoconta.saldo-=250.0;

//emoutroarquivoconta.saldo-=371.0;

Agoraimaginequeobancomudearegradesaque:agoraacadasaquerealizado,obancocobrará0.10centavos.Ouseja,seousuáriosacar10.0reais,énecessáriotirardesuaconta10.10reais.Temosque alterar todosos pontos denossa aplicaçãoque acessamesse atributo!Masnossabasede código

ENCAPSULAMENTOEMODIFICADORESDEACESSO

7ENCAPSULAMENTOEMODIFICADORESDEACESSO 47

Page 55: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

pode ser muito grande e é muito comum esquecermos onde e quem está acessando esse atributo,deixandobugstodavezqueesquecemosdealteraralgumlugar.Setivermosessalinhaespalhada300vezes em nosso sistema, precisaremos encontrar todas essas 300 linhas e fazer a alteração. Muitocomplicadoecustoso!

OqueaconteceriaaousarmosométodoSaca():

//emumarquivoconta.Saca(100.0);

//emoutroarquivoconta.Saca(250.0);

//emoutroarquivoconta.Saca(371.0);

Comorefletiríamosaalteraçãona regradosaquede tirar10centavos?PrecisamosalterarapenasumavezométodoSaca(),aoinvésdealterartodasaslinhasqueacessamoatributodiretamente!

Quando liberamos o acesso aos atributos da classe Conta, estamos permitindo que qualquer

programadorfaçaasuaprópriaimplementaçãonãoseguradalógicadesaquedaformaquequiser.Seamodificaçãodoatributoficasserestritaàclassequeodeclara, todosquequisessemsacaroudepositardinheironacontateriamdefazê-loatravésdemétodosdaclasse.Nessecaso,searegradesaquemudarnofuturo,modificaremosapenasométodoSaca.

Na orientação a objetos, esconder os detalhes de implementação de uma classe é um conceitoconhecido como encapsulamento. Como os detalhes de implementação da classe estão escondidos,todooacessodeveserfeitoatravésdeseusmétodospúblicos.NãopermitimosaosoutrossaberCOMOaclassefazotrabalhodela,mostrandoapenasOQUÊelafaz.

Vejaalinhaconta.Saca(100.0);.Sabemosoquêessemétodofazpeloseunome.Mascomoele

fazotrabalhodelesósaberemosseentrarmosdentrodesuaimplementação.Portanto,ocomportamentoestáencapsuladonessemétodo.

Mas ainda não resolvemos o problema de evitar que programadores façam uso diretamente doatributo.Qualquerumaindapodeexecutarocódigoabaixo:

conta.saldo-=371.0;

Para isso,precisamosesconderoatributo.Queremosdeixá-loprivadoparaquesomenteaprópriaclasseContapossautilizá-lo.Nessecasoqueremosmodificaroacessoaoatributoparaqueelesejaprivado,private:

classConta{

7.1ENCAPSULAMENTO

48 7.1ENCAPSULAMENTO

Page 56: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

//outrosatributosaquiprivatedoublesaldo;

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

publicvoidDeposita(doublevalor){this.saldo+=valor;}}

Atributos e métodos private são acessados apenas pela própria classe. Ou seja, o método

Saca(), por exemplo, consegue fazer alterações nele.Mas outras classes não conseguem acessá-lo

diretamente!Ocompiladornãopermite!

Osatributosdeumaclassesãodetalhesdeimplementação,portantomarcaremostodososatributosdacontacomapalavraprivate:

classConta{privateintnumero;privatedoublesaldo;privateClientetitular;

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

publicvoidDeposita(doublevalor){this.saldo+=valor;}}

Ótimo.Agoraoprogramadoréforçadoapassarpelosmétodosparaconseguirmanipularosaldo.

Setentarmos,porexemplo,escrevernosaldodaContaapartirdocódigodeumformulário,teremos

umerrodecompilação:

Contac=newConta();//Alinhaabaixogeraumerrodecompilaçãoc.saldo=100.0;

Mas agora temos outro problema. Se quisermos exibir o saldo não conseguiremos. O private

bloqueiatantoaescrita,quantoaleitura!

7.1ENCAPSULAMENTO 49

Page 57: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoC#eOrientaçãoaObjetos

VimosquepodemosproibiroacessoexternoaumatributoutilizandooprivatedoC#,masoprivatetambém bloqueia a leitura do atributo, logo para recuperarmos seu valor, precisamos de um novométododentrodaclassequenosdevolveráovaloratualdoatributo:

classConta{privatedoublesaldo;

privateintnumero;

//outrosatributosemétodosdaconta

publicdoublePegaSaldo(){returnthis.saldo;}}

Agoraparamostrarmososaldoparaousuário,utilizaríamososeguintecódigo:

Contaconta=newConta();//inicializaaconta

MessageBox.Show("saldo:"+conta.PegaSaldo());

Além disso, a conta precisa de um número, mas como ele foi declarado como private, não

podemosacessá-lodiretamente.Precisaremosdeumnovométodoparafazeressetrabalho:

classConta{privateintnumero;

//outrosatributosemétodosdaconta

publicvoidColocaNumero(intnumero){this.numero=numero;

VocêpodetambémfazerocursodatadessaapostilanaCaelum

7.2CONTROLANDOOACESSOCOMPROPERTIES

50 7.2CONTROLANDOOACESSOCOMPROPERTIES

Page 58: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

}}

Paracolocarmosonúmeronaconta,teríamosqueexecutaressecódigo:

Contaconta=newConta();

conta.ColocaNumero(1100);

//utilizaacontanocódigo

VejaquecomissonósconseguimoscontrolartodooacessoaclasseConta,masparaescrevermos

oulermosovalordeumatributoprecisamosutilizarosmétodos.Oidealseriautilizarmosumasintaxeparecidacomadeacessoaatributos,porémcomocontrolequeométodonosoferece.Para resolveresseproblema,oC#nosofereceasproperties(propriedades).

Adeclaraçãodeumapropriedadeéparecidacomadeclaraçãodeumatributo,porémprecisamosfalaroquedeveserfeitonaleitura(get)enaescrita(set)dapropriedade

classConta{privateintnumero;

publicintNumero{get{//códigoparalerapropriedade}

set{//códigoparaescrevernapropriedade}}}

Naleituradapropriedade,queremosdevolverovalordoatributonumerodaConta:

classConta{privateintnumero;

publicintNumero{get{returnthis.numero;}}}

Comisso,podemoslerapropriedadeNumerocomoseguintecódigo:

Contac=newConta();MessageBox.Show("numero:"+c.Numero);

Veja que o acesso ficou igual ao acesso de atributos, porémquando tentamos ler o valor de uma

7.2CONTROLANDOOACESSOCOMPROPERTIES 51

Page 59: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

propriedade estamos na verdade executando um bloco de código (get da propriedade) da classe

Conta.Paradefinirmosonúmerodaconta,utilizaremosocódigo:

Contac=newConta();c.Numero=1;

Quandotentamosescreveremumapropriedade,oC#utilizaoblocosetparaguardarseuvalor.

Dentrodoblocoset, o valor que foi atribuído à propriedade fica dentrodeumavariável chamada

value,entãopodemosimplementarosetdaseguinteforma:

classConta{privateintnumero;

publicintNumero{//declaraçãodogetset{this.numero=value;}}}

Podemos também declarar uma propriedade que tem apenas o get, sem o set. Nesse caso,

estamos declarando uma propriedade que pode ser lidamas não pode ser escrita. Com as propertiesconseguimoscontrolarcompletamenteoacessoaosatributosdaclasseutilizandoasintaxedeacessoaosatributos.

Utilizando as properties, conseguimos controlar o acesso às informações da classe, porém, comovimos,declararumapropertyébemtrabalhoso.Precisamosdeumatributoparaguardarseuvalor,alémdisso,precisamosdeclararogeteoset.

Para facilitar a declaração das properties, a partir do C# 3.0, temos as propriedades que sãoimplementadasautomaticamentepelocompilador,asauto-implementedproperties.Paradeclararmosumaauto-implementedpropertyparaexporonúmerodaconta,utilizamososeguintecódigo:

classConta{publicintNumero{get;set;}}

Essecódigofazcomqueocompiladordeclareumatributodotipoint(cujonomesóéconhecido

pelocompilador)egereocódigoparaapropriedadeNumerocomumget eumset que leeme

escrevemnoatributodeclarado.Reparequeaoutilizarmosasauto-implementedproperties,sópodemosacessarovalordoatributodeclaradoatravésdapropriedade.

7.3 SIMPLIFICANDO A DECLARAÇÃO DE PROPRIEDADES COMAUTO-IMPLEMENTEDPROPERTIES

52 7.3SIMPLIFICANDOADECLARAÇÃODEPROPRIEDADESCOMAUTO-IMPLEMENTEDPROPERTIES

Page 60: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Todavezquedeclaramosumauto-implementedproperty,precisamossempredeclararumget e

umsetparaapropriedade,porémpodemoscontrolaravisibilidadetantodogetquantodoset.

Porexemplo,nocasodosaldo,queremospermitirquequalquerumleiaosaldodaconta,porémapenasaprópriacontapodealterá-lo.Nessecaso,utilizamososeguintecódigo:

classConta{//outraspropriedades

//getépúblicoepodeseracessadoporqualquerclasse//setéprivadoeporissosópodeserusadopelaconta.publicdoubleSaldo{get;privateset;}

//restodocódigodaclasse.}

Agoravamosverumcódigoquetentalereescrevernaspropriedadesquedeclaramos:

Contac=newConta();

c.Numero=1;//funcionapoisosetdoNumeroépúblicoMessageBox.Show("numero:"+c.Numero);//funcionapoisogetdoNumeroépúblico

c.Saldo=100.0;//setdoSaldoéprivado,entãotemosumerroMessageBox.Show("saldo"+c.Saldo);//funcionapoisogetdoSaldoépúblico.

Veja que tanto declarando properties explicitamente quanto utilizando as auto-implementedproperties,temosocontroletotalsobrequaisinformaçõesserãoexpostaspelaclasse.

Entãodevemosutilizarpropertiestodavezquequeremosexporalgumainformaçãodaclasse.Nuncadevemosexporatributosdaclasse(utilizandoopublic),poisnuncaqueremosexporosdetalhesde

implementaçãodaclasse.

AconvençãodenomesdefinidaparapropertiesdoC#éamesmaconvençãodenomesutilizadaparaclasses,ouseja,utilizandooPascalCasing(Todasaspalavrasdonomesãoconcatenadasecadapalavratemainicialmaiúscula,porexemplo:numerodobanco=>NumeroDoBanco)

7.4CONVENÇÃODENOMEPARAPROPERTY

7.4CONVENÇÃODENOMEPARAPROPERTY 53

Page 61: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

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

CasadoCódigo,LivrosdeTecnologia.

1. Qualocomportamentodoatributoabaixo:

publicintNumero{get;privateset;}

Onúmeropodeserlido,masnãopodeseralteradoporoutrasclasses.

Onúmeronãopodeserlido,maspodeseralteradoporoutrasclasses.

Onúmeronãopodenemserlidonemseralteradoporoutrasclasses.

Onúmeropodeserlidoealteradoporoutrasclasses.

2. Sobreocódigoabaixoéválidoafirmarque...

Contac=newConta();doublevalorADepositar=200.0;c.Saldo+=valorADepositar;

Aoperaçãodedepósitofoiimplementadacorretamente.

Aoperaçãodedepósitonãoestáencapsulada,podendogerarproblemasfuturosdemanutenção.

Aoperaçãodedepósitonãoestáencapsulada,facilitandoamanutençãofuturadocódigo.

3. Oqueéencapsulamento?

ÉdeixarbemclaroparatodosCOMOaclassefazotrabalhodela.

ÉautilizaçãodePropertiesemqualquerumadesuasvariações.

Émanipularealteraratributosdiretamente,sempassarporummétodoespecífico.

Seuslivrosdetecnologiaparecemdoséculopassado?

7.5EXERCÍCIOS

54 7.5EXERCÍCIOS

Page 62: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

ÉesconderCOMOaclasse/métodofazsuatarefa.Casoaregramude,temosquealterarapenasumpontodocódigo.

4. Qualoproblemadoatributoabaixo:

publicdoubleSaldo{get;set;}

Nenhum.Eleestáencapsulado,afinalusamosProperties.

Aoinvésdepublic,deveríamosusarprivate.

O atributo Saldo pode ser manipulado por outras classes. Isso vai contra a regra do

encapsulamento. De nada adianta criar Properties e permitir que todos os atributos sejammodificadospelasoutrasclasses.

5. TransformeosatributosdaclasseContaempropriedades.Permitaqueosaldodacontasejalido,

porémnãosejaalteradoforadaclasse,alteretambémocódigodasclassesqueutilizamacontaparaqueelasacessemaspropriedadesaoinvésdosatributosdiretamente.

Quando escrevemos uma aplicação grande, muitas vezes utilizamos bibliotecas que sãodesenvolvidasporoutraspessoas, asDLLs (DynamicLinkLibrary).Emuitas vezes a aplicação

precisacompartilharclassescomadllimportadanocódigo.

QuandodeclaramosumaclassenoC#,porpadrãoela sópodeservistadentrodopróprioprojeto(visívelapenasnoassemblyqueadeclarou),esseéumníveldevisibilidadeconhecidocomointernal.Quandoqueremostrabalharcombibliotecasexternasaoprojeto,nossasclassesprecisamserdeclaradascomavisibilidadepublic:

publicclassAtualizadorDeContas{//Implementaçãodaclasse}

Comessamodificação,aclasseAtualizadorDeContasévisívelinclusiveforadoassemblyque

adeclarou,ouseja,podemosutilizá-laemqualquerpontodocódigo.

DentrodessaclasseAtualizadorDeContas,vamosdeclararummétodochamadoAtualizaque

recebeumaContacomoargumento.

publicclassAtualizadorDeContas{publicvoidAtualiza(Contaconta){

}}

7.6PARASABERMAIS:VISIBILIDADEINTERNAL

7.6PARASABERMAIS:VISIBILIDADEINTERNAL 55

Page 63: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Comoesseéummétodopúblicodentrodeumaclassepública,elepodeserutilizadoemqualquerponto do código, inclusive em outros assemblies. Porém se a classe Conta for uma classe com

visibilidadeinternal, teremos ummétodo que pode ser visto em todos os pontos do código, que

recebe um argumento visível apenas dentro do assembly que o declarou, ou seja, temos uma

inconsistêncianasvisibilidades.

Quando o compilador do C# detecta uma inconsistência de visibilidade, ele gera um erro decompilação avisando quais são os métodos e classes que estão inconsistentes. Para corrigirmos oproblema de inconsistência do exemplo do AtualizadorDeContas , precisamos declarar a classe

Contacomopublic:

publicclassConta{//implementaçãodaclasse}

Ou alternativamente, podemos deixar a classe AtualizadorDeContas ou ométodo Atualiza

comvisibilidadeinternal:

//internaléavisibilidadepadrãoparaaclasse,//portantoapalavrainternaléopcionalinternalclassAtualizadorDeContas{//implementaçãodaclasse}

56 7.6PARASABERMAIS:VISIBILIDADEINTERNAL

Page 64: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO8

Comoquevimosnoscapítulosanteriores,nósprecisamoslembrardecolocaronomeapóscriarmosumnovoclienteemnossosistema.Issopodeservistonocódigoaseguir:

Clienteguilherme=newCliente();guilherme.Nome="Guilherme";

Eseesquecermosdechamarasegundalinhadessecódigo,teremosumclientesemnome.Mas,seráquefazsentidoexistirumclientesemnome?

Paraevitarisso,aoconstruirnossoobjetotemosqueobrigarodesenvolvedorafalarqualonomedoCliente.Istoé,queremossercapazesdealterarocomportamentodaconstruçãodoobjeto.

Queremosdefinirumnovocomportamentoquedirácomoseráconstruídooobjeto.Algocomo:

Clienteguilherme=newCliente("GuilhermeSilveira");

Note que esse comportamento que desejamos lembra um comportamento normal, passandoargumentos,mas com a característica especial de ser quem constrói um objeto. Esse comportamentorecebeonomedeconstrutor.Ecomodefini-lo?Similarmenteaumcomportamentoqualquer:

classCliente{//OutrosatributosdaclasseClientepublicstringNome{get;set;}

publicCliente(stringnome){this.Nome=nome;}}

Vimosquequandocriamosumconstrutornaclasse,oC#usaoconstrutorcriadoparainicializaroobjeto,porémoqueacontecequandonãotemosnenhumconstrutornaclasse?Quandoumaclassenãotemnenhumconstrutor,oC#colocaumconstrutorpadrãodentrodaclasse.Esseconstrutornãorecebeargumentosenãoexecutanenhumaação,ouseja,umconstrutorquenãorecebenenhumargumentoetemocorpovazio.

Na seção anterior definimos um construtor dentro da classe cliente que inicializa a propriedade

CONSTRUTORES

8.1MÚLTIPLOSCONSTRUTORESDENTRODACLASSE

8CONSTRUTORES 57

Page 65: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

nome,masesequiséssemosinicializartambémaidadedoClienteduranteaconstruçãodoobjeto?

Nessecaso,precisaríamosdeumconstrutoradicionalnaclasseCliente:

classCliente{publicstringNome{get;set;}

publicintIdade{get;set;}

//construtorquesórecebeonomepublicCliente(stringnome){this.Nome=nome;}//construtorquerecebeonomeeaidadepublicCliente(stringnome,intidade){this.Nome=nome;this.Idade=idade;}}

Veja que definimos duas versões diferentes do construtor da classe, uma que recebe apenas astringnomeeoutraquerecebestringnomeeintidade.Quandocolocamosdiversasversões

doconstrutordentrodeumaclasse,estamosfazendoumasobrecargadeconstrutores.

VALORPADRÃOPARAOSPARÂMETROS

NoC#, ao invés de fazermos sobrecarga de construtores para podermos passar informaçõesadicionaisnacriaçãodoobjeto,podemosutilizarosparâmetrosopcionaiscomvalorespadrão.

Você pode ler sobre os parâmetros opcionais no blog da caelum:http://blog.caelum.com.br/parametros-opcionais-e-nomeados-do-c/

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

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Agoraéamelhorhoradeaprenderalgonovo

58 8.1MÚLTIPLOSCONSTRUTORESDENTRODACLASSE

Page 66: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Vimosquepodemosutilizarumconstrutorparapedirinformaçõesobrigatóriasparaaclasse.Mas,por exemplo, temos a classeCliente e apenas seu nome é obrigatório, então podemos pedir essa

informaçãonoconstrutordaclasse.

Clientecliente=newCliente("VictorHarada");

MasoclientetambémpossuiCPF,RGeidade.Paracolocarmosessasinformaçõesnoclientequecriamosprecisamosdocódigo:

Clientecliente=newCliente("VictorHarada");cliente.Cpf="123.456.789-01";cliente.Rg="21.345.987-x";cliente.Idade=25;

Vejaqueemtodasas linhasestamosrepetindoonomedavariávelqueguardaa referênciaparaocliente.Para evitar essa repetição, podemosutilizaros initializersdoC#.O Initializer éumblocodecódigoqueserveparainicializaraspropriedadespúblicasdoobjeto.

Clientecliente=newCliente("VictorHarada"){//blocodeinicializaçãoCpf="123.456.789-01",Rg="21.345.987-x",Idade=25};

1. Ao modelar um sistema de controle de aviões em um aeroporto, todos os aviões possuem,obrigatoriamente,umcódigoeumaempresa,alémdisso,opcionalmente,umacidadedeentradaesaída.

Qualsoluçãoparecesermaisfácildemanter?

Criar um construtor para código e empresa, e quatro propriedades: código, empresa, cidade deentradaedesaída.

Criarumconstrutorparacódigo,empresa,entradaesaídaenãocriarpropriedades.

Criarquatropropriedades:código,empresa,cidadedeentradaedesaída.

Criarumconstrutorparacódigoeempresa,eduaspropriedadescidadedeentradaedesaída.

2. QualdasopçõesaseguirrepresentaumconstrutordaclasseClientequerecebeonomeeorg?

classCliente{//OutrosatributosdaclasseClientepublicstringNome{get;set;}

8.2PARASABERMAIS—INITIALIZER

8.3EXERCÍCIOS

8.2PARASABERMAIS—INITIALIZER 59

Page 67: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

publicstringRg{get;set;}publicCliente(stringnome,stringrg){this.Nome=nome;this.Rg=rg;}//Outrosmétodoseconstrutores}

classCliente{//OutrosatributosdaclasseClientepublicstringNome{get;set;}publicstringRg{get;set;}publicCliente(stringnome){this.Nome=nome;this.Rg=rg;}//Outrosmétodoseconstrutores}

classCliente{//OutrosatributosdaclasseClientepublicstringNome{get;set;}publicstringRg{get;set;}publicvoidCliente(stringnome,stringrg){this.Nome=nome;this.Rg=rg;}//Outrosmétodoseconstrutores}

classCliente{//OutrosatributosdaclasseClientepublicstringNome{get;set;}publicstringRg{get;set;}publicintCliente(stringnome,stringrg){this.Nome=nome;this.Rg=rg;}//Outrosmétodoseconstrutores}

3. Façacomqueonomepossa,opcionalmente,serpassadonaconstruçãodaclasseCliente.

60 8.3EXERCÍCIOS

Page 68: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO9

Agora que já sabemos os conceitos básicos deOrientação aObjetos, chegou a hora de aprendermoscomoganhar produtividade utilizando oVisual Studio para desenvolver uma interface gráfica para oprojetodobanco.Vamoscriarumnovoprojetoutilizandooatalho"Ctrl+Shift+N"doVisualStudio.Esse atalho abrirá a janela de novo projeto.Nessa janela escolheremos novamente o tipo "WindowsFormApp".Onomedessenovoprojetoserá"Banco".

Dentrodesseprojeto,queremoscolocarcamposdetextoparamostrarasinformaçõesdaconta,paraisso utilizaremos um novo componente do Windows form chamado TextBox . Colocaremos três

TextBoxdentrodoformulário.

INTRODUÇÃOAOVISUALSTUDIOCOMWINDOWSFORM

9INTRODUÇÃOAOVISUALSTUDIOCOMWINDOWSFORM 61

Page 69: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

62 9INTRODUÇÃOAOVISUALSTUDIOCOMWINDOWSFORM

Page 70: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Paradefiniro textoqueseráexibidonoTextBox, precisaremosdeumavariável queguardará a

referência para o componenteTextBox. Para definir o nome dessa variável, devemos clicar com o

botãodireitonoTextBoxeescolheraopçãoProperties

OVisualC#colocaráajanelaPropertiesemdestaque:

DentrodaProperties,procureocampo(Name).Onomequeforcolocadonessecamposeráo

nomedavariávelqueconteráareferênciaparaainstânciadeTextBox.Vamos,porexemplo,definir

queonomedocamposerátextoTitular.

PodemosutilizarareferênciaparaoTextBoxparadefinirotextoqueseráexibido:

textoTitular.Text="Textodaminhacaixadatexto";

VamoschamarosoutrosTextBoxdetextoNumeroetextoSaldo.Agoraprecisamosdefiniro

9INTRODUÇÃOAOVISUALSTUDIOCOMWINDOWSFORM 63

Page 71: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

códigodoformulárioqueseráutilizadoparapreencherasinformaçõesdoformulário.

Para fazer com que o formulário comece preenchido com a informação do titular da conta,precisamoscriarummétodono formulárioque será responsávelpor sua inicialização.Podemos criaressemétododandoumduplocliquenoformulário:

privatevoidForm1_Load(objectsender,EventArgse){//carregueoscamposdeseuformulárioaqui}

Dentrodessemétodo,queremospreencherasinformaçõesdoformuláriocomosdadosdeumacontaqueseráinstanciada.Vamosinicialmenteinstanciaracontaqueserágerenciadapelaaplicação:

privatevoidForm1_Load(objectsender,EventArgse){Contac=newConta();}

Porém esse código gera um erro de compilação pois nesse projeto ainda não criamos a classeConta.FaremosoVisualStudiogeraradeclaraçãodessaclasse.Coloqueocursordotecladosobreo

nomedaclasseContaeaperteoatalhoCtrl+.,oVisualStudiodaráaopçãoGenerateclass

for'Conta':

Não precisamos nos preocupar em criar cada classe do projeto manualmente, podemos deixar opróprioVisualStudiofazerotrabalho!Mudeavisibilidadedaclassegeradaparapublic.

//ArquivoConta.cspublicclassConta{

}

Agora vamos voltar ao código do formulário e inicializar a propriedade Numero da conta da

9.1INTRODUÇÃOPRÁTICAAOSATALHOSDOVISUALSTUDIO

64 9.1INTRODUÇÃOPRÁTICAAOSATALHOSDOVISUALSTUDIO

Page 72: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

variávelc:

privatevoidForm1_Load(objectsender,EventArgse){Contac=newConta();c.Numero=1;}

Ao adicionarmos essa linha, teremos novamente um erro de compilação, pois a conta ainda nãopossuiapropriedadeNumero.ColoqueocursorsobreapropriedadeNumero e aperte novamenteo

Ctrl+..Dessa vez o visual studiomostrará a opçãoGenerate property stub for 'Numero' in'Banco.Conta',escolhaessaopção.

ComissoapropriedadeserácriadaautomaticamentedentrodaclasseConta.

publicclassConta{publicintNumero{get;set;}}

VamostambémdeclararapropriedadeSaldodentrodaConta,para issoutilizaremosumnovo

atalhodovisualstudio.AbaixodapropriedadeNumeroquefoideclaradaanteriormente,digiteprope

depoisaperteateclatabduasvezes:

publicclassConta{publicintNumero{get;set;}

prop+<tab>+<tab>}

Esseéoatalhoparadeclararumanovapropriedadepúblicadentrodocódigo.

publicclassConta{publicintNumero{get;set;}

publicintMyProperty{get;set;}}

9.1INTRODUÇÃOPRÁTICAAOSATALHOSDOVISUALSTUDIO 65

Page 73: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Vejaque,napropriedadecriadapelovisualstudio,otipodapropriedadeeseunomeestãomarcadoscom uma cor de fundo diferente porque ainda não falamos qual será o tipo e o nome da novapropriedade.Comoestamoscriandoapropriedadeparaosaldodaconta,colocaremosotipodouble.

Depoisdedefinirotipodapropriedade,aperteateclatab,issomudaráofocodoeditorparaonome

dapropriedade.DigiteonomeSaldo:

publicclassConta{publicintNumero{get;set;}

publicdoubleSaldo{get;set;}}

MasapenasacontapodealteraroSaldo,asoutrasclassesdevemconseguirfazerapenasaleitura.

Porissomarcaremososetdapropriedadecomapalavraprivate.

publicdoubleSaldo{get;privateset;}

Damesma forma que criamos a propriedade com o atalho prop + <tab> + <tab>, também

podemoscriarumconstrutorparaaclasseutilizandooctor+<tab>+<tab>.

Paraterminaradeclaraçãodaspropriedadesdaconta,vamoscolocaroTitular.Volteàclassedo

formulário principal da aplicação. Dentro do código da inicialização formulário, instancie um novoclientepassandoseunomecomoargumentodoconstrutor:

privatevoidForm1_Load(objectsender,EventArgse){Contac=newConta();c.Numero=1;Clientecliente=newCliente("victor");}

Isso novamente fará o Visual Studio apontar erros de compilação no código e, novamente,utilizaremosoCtrl+. para corrigir esse erro.Coloque o cursor do teclado sobre o tipo cliente,

aperteCtrl+.eselecioneaopçãoGenerateclassfor'Cliente'.Modifiqueavisibilidadeda

classecriadaparapublicevoltenovamenteàclassedoformulário.

OcódigodoformulárioaindapossuioerrodecompilaçãoporqueaclasseClientequeacabamos

decriarnãopossuiumconstrutorquerecebeumastringcomoargumento.Entãovamosnovamente

colocar o cursor do teclado sobre o erro de compilação, apertar Ctrl + . e escolher a opção

Generateconstructorstubin'Banco.Cliente'.

66 9.1INTRODUÇÃOPRÁTICAAOSATALHOSDOVISUALSTUDIO

Page 74: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

ComissocriamosautomaticamenteoconstrutordentrodaclasseCliente.

publicclassCliente{privatestringp;

publicCliente(stringp){this.p=p;}}

Vejaquenocódigodoconstrutorovalordoargumentopassadoéguardadodentrodeumatributoque foi declarado automaticamente, porém queremos guardar esse valor dentro de uma propriedadechamadaNomedoCliente.Apagueoatributoquefoicriadoautomaticamentepelovisualstudioe

depoismodifiqueocódigodoconstrutorpara:

publicclassCliente{publicCliente(stringp){this.Nome=p;}}

Quandomodificarmosocódigo,oVisualStudioautomaticamentemostraráumerrodecompilaçãonaclasseClienteporqueapropriedadeNomeaindanãofoideclarada,entãovamoscriá-la.Dentrodo

códigodoconstrutor,coloqueseucursorsobreapalavraNomeedepoisaperteCtrl+.,escolhaa

opçãoGenerate property stub for 'Nome' in 'Banco.Cliente'. Com isso, o Visual Studio

criaráautomaticamenteapropriedadeNomedentrodaclasseCliente:

publicclassCliente{publicCliente(stringp){this.Nome=p;}

publicstringNome{get;set;}}

Agoravoltandoaocódigodoformulário,precisamosguardaroclientequefoicriadonapropriedadeTitulardaConta:

9.1INTRODUÇÃOPRÁTICAAOSATALHOSDOVISUALSTUDIO 67

Page 75: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

privatevoidForm1_Load(objectsender,EventArgse){Contac=newConta();c.Numero=1;Clientecliente=newCliente("victor");c.Titular=cliente;}

Comessecódigotemosnovamenteumerrodecompilação,entãoutilizaremosoCtrl+. para

criarapropriedadeTitulardentrodaConta.

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

CasadoCódigo,ebookcompreçodeebook.

Depois de criarmos a classeConta, precisamosmostrar seus dados nosTextBox's que foram

adicionados.Comovimos,paracolocarotextoqueserámostradoemumTextBox,precisamosapenas

escrever na propriedade Text do objeto. Então paramostrarmos o nome do titular, precisamos do

seguintecódigo:

privatevoidForm1_Load(objectsender,EventArgse){Contac=newConta();//inicializaaContac

textoTitular.Text=c.Titular.Nome;}

No caso do número da conta, precisamos convertê-lo para uma string antes de escrevê-lo na

propriedadeText.

Quandoqueremos fazer conversões entre os tipos básicos doC#, utilizamos uma classe chamadaConvertdoC#.Dentrodessaclasse,podemosutilizarométodoToStringparaconverterum tipo

primitivodalinguagemparaumastring.OcódigoparamostraraspropriedadesNumeroeSaldo

dacontaficadaseguinteforma:

EditoraCasadoCódigocomlivrosdeumaformadiferente

9.2ACLASSECONVERT

68 9.2ACLASSECONVERT

Page 76: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

textoNumero.Text=Convert.ToString(c.Numero);textoSaldo.Text=Convert.ToString(c.Saldo);

Agora vamos implementar botões no formulário quemanipulam a conta que está sendo exibida.Vamos inicialmente implementar aoperaçãodedepósito.Para isso, arrasteparadentrodo formulárioumanovacaixadetextoefaçacomqueonomedavariáveldessacaixasejatextoValor.Alémdessa

caixa,arrasteumnovobotãoparaoformulário.Quandoousuárioclicarnessebotão,ocódigodevelerovalordigitadonacaixatextoValoreconvertê-loparaumdoublequeserápassadoparaométodo

Deposita.

Dêumduplocliquenobotãoparaassociarumaaçãoemseueventodeclique.Dentrodaaçãodobotão,parapegarmosotextoquefoidigitadonotextoValor,precisamosapenaslerasuapropriedade

Text:

privatevoidbutton1_Click(objectsender,EventArgse){stringvalorDigitado=textoValor.Text;}

AgoraprecisamosfazeraconversãodovalorDigitadoparaotipodoubledoC#.Pararealizar

essaconversão,utilizaremosométodoToDoubledaclasseConvert:

privatevoidbutton1_Click(objectsender,EventArgse){stringvalorDigitado=textoValor.Text;doublevalorOperacao=Convert.ToDouble(valorDigitado);}

E agora que temos o valor da operação no tipo correto, vamos utilizar ométodoDeposita da

classeConta:

privatevoidbutton1_Click(objectsender,EventArgse){stringvalorDigitado=textoValor.Text;doublevalorOperacao=Convert.ToDouble(valorDigitado);c.Deposita(valorOperacao);}

Mas a ação desse botão não pode acessar uma variável que foi declarada dentro do métodoForm1_Load. Para que amesma conta possa ser utilizada emdiferentesmétodosdo formulário, ela

precisaserdeclaradacomoumatributodaclassedoformulárioquefoigeradapeloVisualStudio:

publicclassForm1:Form{privateContac;

//restodaclassedoformulário.}

9.3OPERAÇÕESNACONTA:SAQUEEDEPÓSITO

9.3OPERAÇÕESNACONTA:SAQUEEDEPÓSITO 69

Page 77: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

DentrodoForm1_Load,guardaremosacontacriadadentrodonovoatributodoformulário:

privatevoidForm1_Load(objectsender,EventArgse){//Criaumanovacontaeguardasuareferêncianoatributodoformuláriothis.c=newConta();

//inicializaemostraacontanoformulário}

Comoacontaéumatributodoformulário,podemosacessá-laapartirdométodobutton1_Click.

Masainda temosumerrodecompilaçãoporqueométodoDeposita não existe na classeConta.

Entãovamoscriá-loutilizandooVisualStudio.Dentrodométodobutton1_Click,coloqueocursor

dotecladosobreométodoDepositaeaperteCtrl+.,edepoisescolhaaopçãoGenerateMethod

stubfor'Deposita'in'Banco.Conta'.

Comisso,oVisualStudioautomaticamentecolocaráométododentrodaclasseConta.

internalvoidDeposita(doublep){thrownewNotImplementedException();}

Apagueaimplementaçãopadrãodessemétodo,mudesuavisibilidadeparapublice,porfim,faça

asuaimplementaçãoparaalógicadedepósito.Ocódigodeveficarparecidocomoquesegue:

publicvoidDeposita(doublevalorOperacao){this.Saldo+=valorOperacao;}

Para terminar a lógica de depósito, precisamos apenas atualizar o valor do saldo na interface dousuário. Abra novamente a ação do botão de depósito dentro do código do formulário principal daaplicação(métodobutton1_ClickdaclasseForm1).Dentrodessemétodo,vamosatualizarotexto

mostradonocampotextoSaldocomovalordosaldodaconta:

privatevoidbutton1_Click(objectsender,EventArgse){stringvalorDigitado=textoValor.Text;doublevalorOperacao=Convert.ToDouble(valorDigitado);this.c.Deposita(valorOperacao);textoSaldo.Text=Convert.ToString(this.c.Saldo);}

70 9.3OPERAÇÕESNACONTA:SAQUEEDEPÓSITO

Page 78: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Para finalizarmos essa ação, podemos avisar o usuário que a operação foi realizada com sucessoutilizandoummessagebox.Colocaremosacaixademensagemutilizandooatalhombox+<tab>+

<tab>,esseatalhodeclaraocódigodoMessageBox.Show:

privatevoidbutton1_Click(objectsender,EventArgse){stringvalorDigitado=textoValor.Text;doublevalorOperacao=Convert.ToDouble(valorDigitado);this.c.Deposita(valorOperacao);textoSaldo.Text=Convert.ToString(this.c.Saldo);MessageBox.Show("Sucesso");}

Comovimos,aaçãodeumbotãodoformulárioéummétododeclaradonaclassedoformulárioquecontém o botão. Vimos também que o Visual Studio gera o nome dos métodos na formabutton<numero>_Click.Esseéumnomequepodefacilmentecausarconfusãoegerarproblemasde

manutençãodocódigo.

EssenomegeradopeloVisualStudionaverdadeébaseadonapropriedade(Name)docomponente

Button. Então, para que o Visual Studio gere nomes mais amigáveis para os botões, podemos

simplesmentemudaro(Name)dobotãonajanelaProperties.

Vamos colocar umnovobotão no formulário que implementará a operação de saque.Arraste umnovobotãoparaoformulárioecomo(Name)dessebotãoutilizebotaoSaque.Agoradêumduplo

cliquenonovobotãoparagerarocódigodesuaaçãodeclique.IssocriaráumnovométodochamadobotaoSaque_Click:

privatevoidbotaoSaque_Click(objectsender,EventArgse){stringvalorDigitado=textoValor.Text;doublevalorOperacao=Convert.ToDouble(valorDigitado);this.c.Saca(valorOperacao);textoSaldo.Text=Convert.ToString(this.c.Saldo);MessageBox.Show("Sucesso");}

RestaapenasimplementarmosométodoSacadaConta:

publicvoidSaca(doublevalor){this.Saldo-=valor;}

Mude também o (Name) do botão de depósito para botaoDeposito . Na próxima seção

aprenderemoscomorenomearonomedaaçãodobotãosemcausarproblemasdecompilação.

9.4CONTROLANDOONOMEDAAÇÃODEUMBOTÃO

9.4CONTROLANDOONOMEDAAÇÃODEUMBOTÃO 71

Page 79: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

TEXTODOBOTÃO

O texto de um botão do Windows Form também pode ser customizado através de suapropriedadeText.EssapropriedadepodesermodificadanajanelapropertiesdoVisualStudio.

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

VamosolharocódigodoconstrutordoClientequeimplementamosanteriormente:

publicclassCliente{publicCliente(stringp){this.Nome=p;}}

Veja que nesse código estamos recebendo um parâmetro chamado p, mas o que esse nome p

significa?Quando criamos uma variável, é sempre importante utilizarmos nomes que descrevem suafunçãodentrodocódigo,senãopodemosacabardificultandoasualeituraecompreensãofuturas.

Masrenomearumavariávelexistenteéuma tarefaárdua,poisnãoadiantaapenas renomearmosadeclaraçãodavariável,precisamos tambémmudar todosos lugaresqueautilizam.Quandoqueremosfazeruma renomeaçãodevariáveis, podemosutilizaroprópriovisual studiopara fazer esse trabalhoatravésdoatalhoCtrl+R,Ctrl+R(Ctrl+Rduasvezes).

VamosutilizaressenovoatalhopararenomearoparâmetroprecebidonoconstrutordoCliente.

JáconheceoscursosonlineAlura?

9.5 RENOMEANDO VARIÁVEIS, MÉTODOS E CLASSES COM OVISUALSTUDIO

72 9.5RENOMEANDOVARIÁVEIS,MÉTODOSECLASSESCOMOVISUALSTUDIO

Page 80: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Paraisso,coloqueocursordotecladosobreadeclaraçãodoparâmetropousobreumdeseususose

depoisaperteCtrl+R,Ctrl+R.Issoabriráumanovajanelaondepodemosdigitarqualéonovo

nomeque queremos utilizar para essa variável.Digitenome na caixa de texto e depois confirme a

mudança.ComissooVisualStudiofaráorenameautomáticodavariáveldentrodocódigo.Omesmoatalhopodeserusadopararenomearmosclasses,métodos,atributosepropriedadesdocódigo.

AgorautilizaremosesseatalhoderenameparamodificaronomedaaçãodobotãodedepósitoparabotaoDeposito_Click.Coloqueocursordo tecladosobreonomedométodobutton1_Click da

classeForm1EaperteCtrl+R,Ctrl+RerenomeieométodoparabotaoDeposito_Click.

Podemostambémrenomearargumentodemétodosutilizandoesseatalho.AbraométodoSacada

classeContaecoloqueocursordotecladosobreavariávelvalorOperacaoedepoisaperteoCtrl

+R,Ctrl+R,mudeonomedavariávelparavalor.FaçaomesmocomométodoDeposita.

Noformulárioprincipal,acontaprincipaldaaplicaçãoestáutilizandoccomonomedevariável,

porémcnãoéumbomnome,poiselenãoéumnomedescritivo.Tenteutilizaressenovoatalhoque

aprendemosparamudaronomedesseatributoparaconta,vejaqueoVisualStudiorenomearátantoa

declaraçãodoatributoquantoseususos.

Nestecapítuloconseguimosmostrarasinformaçõesdacontaatravésdainterfacedaaplicação,comissoousuárioconseguesaberoqueestáacontecendocomsuaconta,porémumacaracterísticamuitoimportantedeprogramascominterfacegráficaéaorganizaçãodasinformações.

Noformulárioquecriamos,comoousuáriosabequaissãooscamposquerepresentamosaldo,onúmero e o titular da conta?Precisamos de alguma forma para indicar qual é a informação que estáarmazenadadentrodeumTextBox,para issoutilizaremosumnovocomponentedoWindowsForm

chamadoLabel.Olabel funciona como uma etiqueta para nossos campos de texto.Através da

propriedadeTextdaLabel,quepodesermodificadapelajanelaproperties,podemosdefinirqual

éotextoqueseráexibido.Vejacomoficaaaplicaçãoquandoutilizamosolabel:

9.6 PARA SABER MAIS — ORGANIZANDO O FORMULÁRIO COMLABELEGROUPBOX

9.6PARASABERMAIS—ORGANIZANDOOFORMULÁRIOCOMLABELEGROUPBOX 73

Page 81: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Mas e quando temos uma interface gráfica muito complexa? Nesses casos, podemos ter muitasfuncionalidadesouinformaçõesdentrodeumaúnicateladaaplicação.Paraessasituação,éumapráticacomum criar grupos de elementos com funcionalidades semelhantes. Para organizar os grupos decomponentes de um formulário, no Windows Form possuímos mais um componente chamadoGroupBox

UtilizandooGroupBox,podemosagrupardiversoscomponentesdiferentessobumúnicotítulo.O

formuláriodonossoprojeto,porexemplo,ficariadaseguinteforma:

74 9.6PARASABERMAIS—ORGANIZANDOOFORMULÁRIOCOMLABELEGROUPBOX

Page 82: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

ParafacilitaraconsultadosatalhosdoVisualStudio,nessaseçãovamoslistarosatalhosvistosnocapítulo:

Ctrl+Shift+N:criaumnovoprojetodentrodoVisualStudio;

Ctrl+.:utilizadoparafazerconsertosrápidosnocódigo.Quandoestamosutilizandoumaclassequenãoexiste,eledeclaraaclassedentrodoprojeto.Aoutilizarmosumapropriedadeoumétodoinexistente,oatalhocriaautomaticamenteocódigoparaapropriedadeoumétodo;

Ctrl+R,Ctrl+R:renomeiaclasses,métodos,propriedades,atributosouvariáveisutilizadasnocódigo;

Ctrl+:autocomplete;

ctor++:declaraumconstrutordentrodaclasse;

prop++:declaraumapropriedadedentrodaclasse;

mbox++:declaraocódigodoMessageBox.Show().

9.7RESUMODOSATALHOSDOVISUALSTUDIO

9.7RESUMODOSATALHOSDOVISUALSTUDIO 75

Page 83: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoC#eOrientaçãoaObjetos

1. Monteumformulárioquemostreoscampostitular,saldoenumerodeumaConta.Façacomqueavariável queguardao campo titular seja chamadadetextoTitular, a que guarda o saldo seja

textoSaldoeaqueguardaonumerosejatextoNumero.

Noloaddoformulário,escrevaumcódigoquecriaumacontacomtitularVictorenumero1.MostreosdadosdessacontanoscampostextoTitular,textoSaldoetextoNumerodoformulário.

2. Crieumnovocampode textono formuláriochamadotextoValor.Adicione tambémumnovo

botão que quando clicado executará a lógica de depósito utilizando o valor digitado no campocriado.Depoisdeexecutaralógica,atualizeosaldoatualqueéexibidopeloformulário.

3. Coloqueumnovobotãonoformulário.FaçacomqueaaçãodocliquedessebotãoexecuteumsaquenacontausandoovalordocampotextoValor.Apóso saque, atualize as informaçõesque são

exibidasparaousuário.

Umclienteprecisasermaiordeidadeouemancipadoparaabrirumacontanobanco.Alémdisso,ele tambémprecisa de umCPF. Para verificar isso, o sistema possui ummétodo que verifica se umclientepodeounãoabrirumaconta:

publicboolPodeAbrirContaSozinho{get{return(this.idade>=18||this.documentos.contains("emancipacao"))&&!string.IsNullOrEmpty(this.cpf);}}

VocêpodetambémfazerocursodatadessaapostilanaCaelum

9.8EXERCÍCIOS

9.9PARASABERMAIS—TIPOSIMPLÍCITOSEAPALAVRAVAR

76 9.8EXERCÍCIOS

Page 84: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Percebaquepodemoscriartrêsvariáveisparaquenossoifnãofiquemuitocomplexo:

publicboolPodeAbrirContaSozinho{get{boolmaiorDeIdade=this.idade>=18;boolemancipado=this.documentos.contains("emancipacao");boolpossuiCPF=!string.IsNullOrEmpty(this.cpf);return(maiorDeIdade||emancipado)&&possuiCPF;}}

Desse jeito,ocódigo ficamais limpoe fácildeentender.Porém, tivemosque ficardeclarandoostiposdasvariáveiscomobool.NãoseriaóbvioparaoC#queessasvariáveissãodotipobool.Sim!

Eeleéespertoosuficienteparainferirisso:

publicboolPodeAbrirContaSozinho{get{varmaiorDeIdade=this.idade>=18;varemancipado=this.documentos.contains("emancipacao");varpossuiCPF=!string.IsNullOrEmpty(this.cpf);return(maiorDeIdade||emancipado)&&possuiCPF;}}

Variáveisdentrodemétodospodemserdeclaradascomovar emC#queo seu tipo é inferidoautomaticamente.Paraocompiladoracertarqualotipodavariáveleladeveserinicializadanomesmoinstantequeédeclaradaenãopodeseratribuídoovalornull.

publicboolPodeAbrirContaSozinho{get{varmaiorDeIdade;//estalinhanãocompilamaiorDeIdade=this.idade>=18;//...}}

Porfim,umavariáveldeclaradacomovarpossuiumtipobemdefinidoenãopodeseralterado.A

tipageméinferida,masotipodavariávelnãopodeseralteradaàmedidaqueocódigoéexecutado,oquefazcomqueocódigoseguintenãofaçasentidoenãocompile:

varguilherme=newCliente();guilherme=newConta();

1. Observeocódigoaseguireassinaleaalternativacorreta.

varconta=newConta();conta.Titular=newCliente();

9.10EXERCÍCIOSOPCIONAIS

9.10EXERCÍCIOSOPCIONAIS 77

Page 85: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Nãocompilapoisavariávelédeumtipodinâmico.

Compilaefazcomqueavariávelcontapossareferenciarqualquertipodeobjeto.

Nãocompilapoiselenãotemcomoadivinharsevaréumacontanovaoujáexistente.

CompilaefazcomqueavariávelcontasejadotipoConta.

2. Oqueaconteceaotentarcompilarerodarocódigoaseguir?

varsimples=newConta();//linha1simples=newConta();//linha2simples=newCliente();//linha3

Alinha2nãocompilapoisnãopodemosreatribuirumavariável.

Alinha3nãocompilapoisotipodeumavariávelnãopodesertrocadoeeleéinferidoaodeclararavariável.

Compilaenofimdas3linhasdecódigoavariávelsimplesapontaráparaumCliente.

Alinha1nãocompiladevidoaocódigodalinha2e3.

3. Oqueaconteceaocompilarerodarocódigoaseguir?

varconta;conta=newConta();conta.Deposita(300);

Nãocompilapoiscontanãoteveumvaloratribuídojánaprimeiralinha.

Compilamasnãoroda,dandoerrodeexecuçãonalinha2poistentamosacessarumavariávelsemvalor.

Compilaeroda.

4. Oqueaconteceaocompilareexecutarocódigoadiante?

vartamanho=5;tamanho=tamanho/2.0;MessageBox.Show(tamanho);

Ocódigonãocompilanalinha2.

Ocódigocompilaerodaimprimindo2.

Ocódigocompilamasnãorodapois5nãoédivisívelpor2.0.

Ocódigocompilaeroda,imprimindotamanho=2.5

78 9.10EXERCÍCIOSOPCIONAIS

Page 86: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

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

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

9.10EXERCÍCIOSOPCIONAIS 79

Page 87: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO10

Imagineagoraquenossobancorealizedepósitosesaquesdeacordocomotipodaconta.Seacontaforpoupança,oclientedevepagar0.10porsaque.Seacontaforcorrente,nãohátaxa.

Paraimplementaressaregradenegócio,vamoscolocarumifnométodoSaca:

publicvoidSaca(doublevalor){if(this.Tipo==???????????){this.Saldo-=valor+0.10;}else{this.Saldo-=valor;}}

PodemoscriarumatributonaConta,queespecificaotipodacontacomo,porexemplo,uminteiro

qualquerondeonúmero1representaria"contapoupança"e2"contacorrente".

Aimplementaçãoseriaalgocomo:

publicclassConta{publicintNumero{get;set;}publicdoubleSaldo{get;privateset;}

publicClienteTitular{get;set;}

publicintTipo{get;set;}

publicvoidSaca(doublevalor){if(this.Tipo==1){this.Saldo-=valor+0.10;}else{this.Saldo-=valor;}}

publicvoidDeposita(doublevalor){this.Saldo+=valor;}}

HERANÇA

80 10HERANÇA

Page 88: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Vejaqueuma simples regra denegócio comoessa fez nosso código crescermuito.Epoderia serpior:imaginesenossobancotivesse10tiposdecontasdiferentes.Esseifseriamaiorainda.

Precisamosencontrarumamaneiradefazercomqueacriaçãodenovostiposdecontanãoimpliqueemumaumentodecomplexidade.

UmasoluçãoseriaterclassesseparadasparaConta(queéacorrente)eContaPoupanca:

publicclassConta{publicintNumero{get;set;}publicdoubleSaldo{get;privateset;}

publicClienteTitular{get;set;}

publicvoidSaca(doublevalor){this.Saldo-=valor;}

publicvoidDeposita(doublevalor){this.Saldo+=valor;}}

publicclassContaPoupanca{publicintNumero{get;set;}publicdoubleSaldo{get;privateset;}

publicClienteTitular{get;set;}

publicvoidSaca(doublevalor){this.Saldo-=(valor+0.10);}

publicvoidDeposita(doublevalor){this.Saldo+=valor;}}

Ambasasclassespossuemcódigobemsimples,masagoraoproblemaéoutro:arepetiçãodecódigoentreambasasclasses.Seamanhãprecisarmosguardar"CPF",porexemplo,precisaremosmexeremtodasasclassesquerepresentamumacontanosistema.Issopodesertrabalhoso.

Aideiaé,portanto,reaproveitarcódigo.Vejaque,nofim,umaContaPoupancaéumaConta,pois

ambostemNumero,SaldoeTitular.Aúnicadiferençaéocomportamentonomomentodosaque.

PodemosfalarqueumaContaPoupancaéumaConta:

publicclassContaPoupanca:Conta

10.1REAPROVEITANDOCÓDIGOCOMAHERANÇA

10.1REAPROVEITANDOCÓDIGOCOMAHERANÇA 81

Page 89: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

{

}

Quandoumaclasseédefinidacomo:,dizemosqueelaherdadaoutra(Conta)eporissoelaganhatodososatributosemétodosdaoutraclasse.Porexemplo,seContaPoupancaherdardeConta,isso

querdizerqueelateráNumero,Saldo,Titular,Saca()eDeposita()automaticamente,sem

precisarfazernada.DizemosqueaclasseContaPoupancaéumasubclasseouclassefilha da classeContaequeContaéumaclassebaseouclassepaidaContaPoupanca.Vejaocódigoaseguir:

//ArquivoContaPoupanca.cspublicclassContaPoupanca:Conta{

}

//CódigonoformulárioqueutilizaaContaPoupancaContaPoupancac=newContaPoupanca();c.Deposita(100.0);

Bastausaranotação:eoC#automaticamenteherdaosmétodoseatributosdaclassepai.Masa

ContaPoupanca tem o comportamento de Saca() diferente. Para isso, basta reescrever o

comportamentonaclassefilha,usandoapalavraoverrideemudandoaclassepaiparaindicarqueo

métodopodesersobrescrito(virtual):

//ArquivoConta.cspublicclassConta{publicvirtualvoidSaca(doublevalor){this.Saldo-=valor;}

//Restodocódigodaclasse}

//ArquivoContaPoupanca.cspublicclassContaPoupanca:Conta{publicoverridevoidSaca(doublevalor){this.Saldo-=(valor+0.10);}}

//CódigodoformuláriodaaplicaçãoContaPoupancac=newContaPoupanca();

//chamaocomportamentoescritonopai//OSaldoterminaem100.0depoisdessalinhac.Deposita(100.0);

//chamaocomportamentoescritonaContaPoupanca//OSaldoterminacomovalor49.90c.Saca(50);

82 10.1REAPROVEITANDOCÓDIGOCOMAHERANÇA

Page 90: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

VejanessecódigoqueinvocamostantoDeposita()quantoSaca().Nodepósito,comoaclasse

filhanãoredefiniuocomportamento,ométodoescritonaclassepaiseráutilizado.

Jánosaque,ocomportamentousadoéoquefoisobrescritonaclassefilha.

Mas o código anterior ainda não compila. Repare que o método Saca() da ContaPoupanca

manipulaoSaldo.MasSaldo é privado!Atributos privados só sãovisíveis para a classe queos

declarou.Osfilhosnãoenxergam.

Queremos proteger nosso atributo mas não deixá-lo privado nem público. Queremos proteger osuficienteparaninguémdeforaacessar,masapenasquemherdateracesso.Pararesolver,alteraremosomodificador de acesso para protected. Atributos/métodos marcados como protected são visíveisapenasparaaprópriaclasseeparaasclassesfilhas:

publicclassConta{publicintNumero{get;set;}publicdoubleSaldo{get;protectedset;}

//...}

AclasseContaaindapodeserinstanciadasemproblemas:

Contac=newConta();c.Deposita(100.0);

Vejaquecomherançaconseguimossimplificarereutilizarcódigoaomesmotempo.Aherançaéummecanismopoderosomasdeveserutilizadocomcuidado.

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

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

ObserveasimplementaçõesdosmétodosSacadasclassesContaeContaPoupanca:

Agoraéamelhorhoradeaprenderalgonovo

10.2REAPROVEITANDOAIMPLEMENTAÇÃODACLASSEBASE

10.2REAPROVEITANDOAIMPLEMENTAÇÃODACLASSEBASE 83

Page 91: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

publicclassConta{//outrosatributosemétodospublicdoubleSaldo{get;protectedset;}

publicvirtualvoidSaca(doublevalor){this.Saldo-=valor;}}

publicclassContaPoupanca:Conta{publicoverridevoidSaca(doublevalor){this.Saldo-=(valor+0.10);}}

Asimplementaçõesdosdoismétodossãopraticamenteiguais,aúnicadiferençaéquenoSacada

ContaPoupanca colocamos this.Saldo -= (valor + 0.10); ao invés de this.Saldo -=

valor;.

Quando fazemos a sobrescrita de métodos em uma classe filha, muitas vezes, queremos apenasmudarlevementeocomportamentodaclassebase.Nessassituações,nocódigodaclassefilha,podemosreutilizar o código da classe pai com a palavra base chamando o comportamento que queremosreaproveitar.EntãoocódigodoSacadaContaPoupancapoderiaserreescritodaseguinteforma:

publicclassContaPoupanca:Conta{publicoverridevoidSaca(doublevalor){base.Saca(valor+0.10);}}

Comessaimplementação,oSacadaContaPoupancachamaométododaclassebasepassando

como argumento valor + 0.10. Repare também que, como a classe filha não está utilizando a

propriedadeSaldodaConta,elapoderiavoltaraserprivate:

publicclassConta{publicdoubleSaldo{get;privateset;}

//outraspropriedadesemétodos}

Nossobancotemrelatóriosinternosparasabercomoestáasaúdefinanceiradainstituição,alémderelatórios sobreosclientesecontas.Emumdeles, énecessáriocalculara somadosaldode todasascontas(correntes,poupanças,entreoutras)queexistemnobanco.Começandocom"zeroreais":

10.3POLIMORFISMO

84 10.3POLIMORFISMO

Page 92: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

publicclassTotalizadorDeContas{publicdoubleValorTotal{get;privateset;}}

PermitimosadicionarContaaonossorelatórioeacumularseusaldo:

publicclassTotalizadorDeContas{publicdoubleValorTotal{get;privateset;}

publicvoidSoma(Contaconta){ValorTotal+=conta.Saldo;}}

Contac1=newConta();Contac2=newConta();

TotalizadorDeContast=newTotalizadorDeContas();t.Soma(c1);t.Soma(c2);

Ótimo.Masoproblemaéquetemosclassesquerepresentamdiferentestiposdecontas,equeremosacumularosaldodelastambém.UmaprimeirasoluçãoseriaterummétodoSoma()paracadaclasse

específica:

publicclassTotalizadorDeContas{publicdoubleValorTotal{get;privateset;}

publicvoidSoma(Contaconta){/*...*/}publicvoidSoma(ContaPoupancaconta){/*...*/}publicvoidSoma(ContaEstudanteconta){/*...*/}//maisummontedemétodosaqui!}

Novamentecaímosnoproblemadarepetiçãodecódigo.

VejaqueContaPoupancaéumaConta.Issoéinclusiveexpressoatravésdarelaçãodeherança

entre as classes. E, já que ContaPoupanca é uma Conta , o C# permite que você passe

ContaPoupancaemlugaresqueaceitamreferênciasdotipoConta!Linguagensorientadasaobjetos,

comoC#,possuemessasoluçãoelegantepraisso.

Vejaocódigoaseguir:

publicclassTotalizadorDeContas{publicdoubleValorTotal{get;privateset;}

publicvoidSoma(Contaconta){ValorTotal+=conta.Saldo;}}

10.3POLIMORFISMO 85

Page 93: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Contac1=newConta();ContaPoupancac2=newContaPoupanca();

TotalizadorDeContast=newTotalizadorDeContas();t.Soma(c1);t.Soma(c2);//funciona!

Ocódigofunciona!Podemospassarc2aliparaométodoSoma().

Mascomoissofunciona?OC#sabequeContaPoupancaherda todososatributosemétodosde

Conta, e portanto, tem a certeza de que existe o atributoSaldo, e que ele poderá invocá-lo sem

maioresproblemas!

Agora,umaContaPoupancatemumnovocomportamento,quepermitecalcularseusrendimentos.

ParaissoodesenvolvedorcriouumcomportamentochamadoCalculaRendimento():

classContaPoupanca:Conta{publicvoidCalculaRendimento(){//...}}

VejaométodoSoma().EleinvocatambémoCalculaRendimento():

publicclassTotalizadorDeContas{publicdoubleValorTotal{get;privateset;}

publicvoidSoma(Contaconta){ValorTotal+=conta.Saldo;conta.CalculaRendimento();//nãocompila!}}

O código anterior não compila. Por quê? Porque o C# não consegue garantir que o que virá navariável conta será uma ContaPoupanca. Naquela "porta" entra Conta ou qualquer filho de

Conta.Portanto,tudooqueoC#conseguegarantiréqueoobjetoqueentraralitemtudoqueConta

tem.Porisso,sópodemosusarmétodoseatributosdefinidospelotipodavariável(nocaso,Conta.)

Essa ideiadeumavariavelconseguir referenciarseupróprio tipooufilhosdesse tipoéconhecidopor polimorfismo. Veja que, com o uso de polimorfismo, garantimos que a classeTotalizadorDeContasfuncionaráparatodonovotipodeContaqueaparecer.

Seno futuroumnovo tipode conta, comoconta investimento, for criada, bastaque elaherdedeContaenãoprecisaremosnuncamodificaressaclasse!Elafuncionaránaturalmente!

Umprogramadorqueconhecebemorientaçãoaobjetosfazusoconstantedepolimorfismo.Veremosmais pra frente como continuar usando polimorfismo para escrever código de qualidade, tomando

86 10.3POLIMORFISMO

Page 94: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

cuidadoparanãoabusardessaideia.

1. Qualadiferençaentreprivateeprotected?

Nenhuma.Emambos,oatributo/métodoévisívelparatodos.

Só a própria classe enxerga atributos/métodos private enquanto protected é visto pela

própriaclassemaisasclassesfilhas.

Só a própria classe enxerga atributos/métodos protected enquanto private é visto pela

própriaclassemaisasclassesfilhas.

2. Paraqueserveapalavraoverride?

Paraindicarqueométodoestásobrescrevendoummétododaclassepai.

Paranãopermitiracessoaoatributoporoutrasclasses.

Paraindicarqueessemétodonãodeveserutilizado.

3. Praqueserveapalavravirtual?

Parapermitirqueométodosejasobrescrito.

Paraindicarqueessemétodonãodevesersobrescrito.

Parasobrescreverummétododaclassepai.

Paranãopermitiracessoaoatributoporoutrasclasses.

4. AdicioneaclasseContaPoupancanaaplicação.EssaclassedeveherdardaContaesobrescrever

ocomportamentodométodoSacaparaquetodosossaquesrealizadosnacontapoupançapaguem

umataxadeR$0.10.

Nãoseesqueçadeutilizaraspalavrasvirtualeoverrideparasobrescreverosmétodos.

5. Oqueaconteceaoexecutarmosocódigoaseguir:

Contac1=newContaPoupanca();c1.Deposita(100.0);c1.Saca(50.0);MessageBox.Show("contapoupança="+c1.Saldo);

Contac2=newConta();c2.Deposita(100.0);c2.Saca(50.0);MessageBox.Show("conta="+c2.Saldo);

10.4EXERCÍCIOS

10.4EXERCÍCIOS 87

Page 95: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

contapoupanca=49.9econta=49.9

contapoupança=49.9econta=50.0

contapoupança=50.0econta=50.0

contapoupança=50.0econta=49.9

6. FaçacomqueométodoForm1_Load,instancieumaContaPoupancaaoinvésdaConta:

publicpartialclassForm1:Form{//EssaéamesmadeclaraçãoquecolocamosnocapítuloanteriorprivateContaconta;privatevoidForm1_Load(objectsender,EventArgse){this.conta=newContaPoupanca();//restodocódigocontinuaigual}

//códigodorestodoformuláriotambémcontinuaigual}

Reparequenãoprecisamosmodificarotipodavariávelconta,poiscomoaContaPoupancaherda

deConta,podemosutilizaropolimorfismoparaatribuirumareferênciadotipoContaPoupanca

emumavariáveldotipoConta.

Depois demodificar o programa, execute-o e teste a operação de depósito.Repare que na classeContaPoupancanãodeclaramosométodoDeposita,masmesmoassimconseguimosinvocá-lo

dentrodocódigo,issoépossívelpoisquandoutilizamosherança,todoocomportamentodaclassepaiéherdadopelaclassefilha.

Testetambémobotãodesaque.ComoaContaPoupancasobrescreveométodoSacadaConta,

ao apertarmos o botão de saque, estamos invocando o comportamento especializado que foiimplementadonaContaPoupancaaoinvésdeusaroquefoiherdadodaConta.

7. CrieaclasseContaCorrentedentrodoprojetoefaçacomqueelaherdedaclasseConta.

TodasasoperaçõesnaContaCorrenteserãotarifadas,emtodoSaque,precisamospagarumataxa

deR$0.05eparaosdepósitos,R$0.10,ouseja,naContaCorrente, precisaremos sobrescrever

tantoométodoSacaquantooDeposita.Nãoseesqueçadeusarovirtualeoverridepara

fazerasobrescritanocódigo.

Depois de criar a ContaCorrente, modifique novamente o formulário para que ele mostre as

informaçõesdeumaContaCorrenteaoinvésdeumaContaPoupanca.

8. (Opcional) Implemente a classe TotalizadorDeContas com uma propriedade chamada

SaldoTotaleummétodochamadoAdicionaquedevereceberumacontaesomarseusaldoao

88 10.4EXERCÍCIOS

Page 96: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

saldototaldototalizador.Escrevaumcódigoquetestaototalizador.

PodemospassarumainstânciadeContaCorrenteparaoAdicionadototalizador?Porquê?

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

CasadoCódigo,ebookcompreçodeebook.

Nestecapítulo,vimosquequandofazemosaclasseContaPoupancaherdardaclasseConta,ela

recebeautomaticamentetodososatributos,propriedadesemétodosdaclassepai,porémosconstrutoresdaclassepainãosãoherdados.Entãoseaclassefilhaprecisadeumconstrutorqueestánaclassepai,eladeveexplicitamentedeclararesseconstrutoremseucódigo.

Imagineporexemplo,queparaconstruirmosacontaprecisamospassaropcionalmenteseunúmero:

publicclassConta{publicintNumero{get;set;}//ConstrutorsemargumentospublicConta(){}

publicConta(intnumero){this.Numero=numero;}}

Agora na classe ContaPoupanca queremos passar o número na construção do objeto, como o

construtornãoéherdado,precisamoscolocaradeclaraçãoexplicitamente:

publicclassContaPoupanca:Conta{publicContaPoupanca(intnumero){//ApropriedadeNumeroveioherdadadaclasseContathis.Numero=numero;}

EditoraCasadoCódigocomlivrosdeumaformadiferente

10.5PARASABERMAIS—OQUEÉHERDADO?

10.5PARASABERMAIS—OQUEÉHERDADO? 89

Page 97: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

}

Nesse construtor que acabamos de declarar na classe ContaPoupanca , fizemos apenas a

inicializaçãodapropriedadenúmero,exatamenteomesmocódigoquetemosnoconstrutordaclassepai,entãoaoinvésderepetirmosocódigo,podemossimplesmentechamaroconstrutorquefoideclaradonaclasseContaapartirdoconstrutordaclasseContaPoupancautilizandoapalavrabase:

publicclassContaPoupanca:Conta{//Estamoschamandooconstrutordaclassepaiquejáfazainicialização//donúmeroeporissoocorpodoconstrutorpodeficarvazio.publicContaPoupanca(intnumero):base(numero){}}

Naverdade,dentrodoC#,semprequeconstruímosumainstânciadeContaPoupanca,oC#sempre

precisachamarumconstrutordaclasseContaparafazera inicializaçãodaclassebase.Quandonão

invocamosexplicitamenteoconstrutordaclassepai,oC#colocaimplicitamenteumachamadaparaoconstrutorsemargumentosdaclassepai:

publicclassContaPoupanca:Conta{//nessecódigooc#chamaráoconstrutorsemargumentosdaclasseConta.publicContaPoupanca(intnumero){this.Numero=numero;}}

SeaclasseContanãodefiniroconstrutorsemargumentos,temosumerrodecompilaçãosenão

invocarmosexplicitamenteumconstrutordaclassepai.

90 10.5PARASABERMAIS—OQUEÉHERDADO?

Page 98: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO11

Queremos guardar uma lista de contas de nosso banco para poder trabalhar com elas.Uma primeiraalternativa seria criar um conjunto de variáveis, no qual cada variável aponta para uma Conta

diferente:

Contac1=newConta();Contac2=newContaPoupanca();Contac3=newConta();//...

Mas,esequisermosimprimirosaldodetodaselas?PrecisaremosescreverNlinhas,umaparacadaConta:

MessageBox.Show(c1.Titular.Nome);MessageBox.Show(c2.Titular.Nome);MessageBox.Show(c3.Titular.Nome);

Muitotrabalho!CriarumanovaContaseriaumcaos!

Quando queremos guardar diversos objetos, podemos fazer uso de Arrays. Um array é umaestruturadedadosqueconsegueguardarvárioselementoseaindanospossibilitapegaresseselementosdemaneirafácil!

Criarumarrayémuitoparecidocominstanciarumaclasse.Paracriarmos5posiçõesdenúmerosinteiros:

int[]numeros=newint[5];

Acabamosdedeclararumarraydeinteiros,com5posições.Repareanotação[5].Paraguardar

elementosnessasposições,fazemos:

numeros[0]=1;numeros[1]=600;numeros[2]=257;numeros[3]=12;numeros[4]=42;MessageBox.Show("número="+numeros[1]);

Vejaqueaprimeiraposiçãodeumarrayé0(zero).Logo,asposiçõesdeumarrayvãode0(zero)

até(tamanho-1).

VamosagoracriarumarraydeContas:

TRABALHANDOCOMARRAYS

11TRABALHANDOCOMARRAYS 91

Page 99: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Conta[]contas=newConta[5];contas[0]=newConta();

A sintaxe é a mesma. Os elementos guardados pelo array são iguais aos de uma variávelconvencional,quevocêjáestáacostumado.Issoquerdizerquetemospolimorfismotambém!Ouseja,podemosguardar,emumarraydeConta,qualquerfilhodela:

contas[1]=newContaPoupanca();

Sequisermos imprimir todasasContasarmazenadas,podemos fazerum loopnessearray.O loopcomeçaráem0evaiatéotamanhodoarray(contas.Length):

for(inti=0;i<contas.Length;i++){MessageBox.Show("saldo="+contas[i].Saldo);}

PodemosaindausarumaoutrasintaxedoC#,afinalqueremosirparacadaContacemcontas:

foreach(Contacincontas){MessageBox.Show("saldo="+c.Saldo);}

OC#pegacadaelementodoarrayecolocaautomaticamentenavariávelc,imprimindooresultado

quequeremos.

Emmuitassituações,estamosinteressadosemcriarelogoemseguidainicializaroconteúdodeumarray,paraisso,comovimosnessecapítulo,precisaríamosdeumcódigoparecidocomoquesegue:

int[]inteiros=newint[5];inteiros[0]=1;inteiros[1]=2;inteiros[2]=3;inteiros[3]=4;inteiros[4]=5;

Veja que esse código é repetitivo e fácil de ser escrito de forma incorreta. Para facilitar nossotrabalho,oC#nosofereceumatalhoparacriare inicializaroconteúdodoarray.Sequiséssemosumarraydeinteirospreenchidocomosnúmerosde1a5,poderíamosutilizaroseguintecódigo:

int[]umAoCinco=newint[]{1,2,3,4,5};

Essasintaxepodeserutilizadaemarraysdequalquertipo.

11.1PARASABERMAIS—INICIALIZAÇÃODEARRAYS

92 11.1PARASABERMAIS—INICIALIZAÇÃODEARRAYS

Page 100: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

1. Qualdaslinhasaseguirinstanciaumarrayde10elementos?

int[]numeros=newint[9];

int[]numeros=newint[10];

int[]numeros=newint["dez"];

int[10]numeros=newint[10];

2. Imagineoarrayabaixo:

int[]numeros=newint[15];

Comoacessaroquintoelementonessalista?

numeros[3]

numeros[4]

numeros["quinto"]

numeros[5]

3. Dadoumarraynumero,comodescobrirseutamanho?

numero.Length

numero.Size

numero.Size()

JáconheceoscursosonlineAlura?

11.2EXERCÍCIOS

11.1PARASABERMAIS—INICIALIZAÇÃODEARRAYS 93

Page 101: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

numero.Length()

numero.Capacity()

4. Agoravamosutilizararraysnoprojetodobancoparatrabalharmoscomdiversascontasaomesmotempo.Dentro da classe do formulário da aplicação, a classeForm1 criada peloVisual Studio,

vamosguardarumarraydecontasaoinvésdeumaúnicaconta.

publicpartialclassForm1:Form{//vamossubstituircontaporumarraydecontas.//Apaguealinha://privateContaconta;//Ecoloqueadeclaraçãodoarrayemseulugar:privateConta[]contas;

//restodaclasse}

NométodoForm1_Load,vamosinicializaroarraydecontasdoformulárioe,aoinvésdecriarmos

umaúnicaconta,vamoscriardiversascontaseguardá-lasdentrodoarray.

privatevoidForm1_Load(objectsender,EventArgse){//criandooarrayparaguardarascontascontas=newConta[3];

//vamosinicializaralgumasinstânciasdeConta.this.contas[0]=newConta();this.contas[0].Titular=newCliente("victor");this.contas[0].Numero=1;

this.contas[1]=newContaPoupanca();this.contas[1].Titular=newCliente("mauricio");this.contas[1].Numero=2;

this.contas[2]=newContaCorrente();this.contas[2].Titular=newCliente("osni");this.contas[2].Numero=3;}

Noformulário,parasabermosqualéacontaquedeveserexibida,colocaremosumnovocampodetextoondeousuárioescolheráqualéoíndicedaContaqueseráutilizada.Chameessecampode

textodetextoIndice.Alémdo campo de texto, adicione tambémumnovo botão que quando

clicadomostraráacontadoíndicequeousuárioselecionou.

Oseuformuláriodeveficarparecidocomodaimagem:

94 11.1PARASABERMAIS—INICIALIZAÇÃODEARRAYS

Page 102: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

UtilizebotaoBuscacomo(Name)dessenovobotão.

QuandoousuárioclicarnobotaoBusca,precisamosmostraracontaquefoiselecionada:

privatevoidbotaoBusca_Click(objectsender,EventArgse){intindice=Convert.ToInt32(textoIndice.Text);Contaselecionada=this.contas[indice];textoNumero.Text=Convert.ToString(selecionada.Numero);textoTitular.Text=selecionada.Titular.Nome;textoSaldo.Text=Convert.ToString(selecionada.Saldo);}

No botão de depósito, precisamos depositar o valor na conta que foi escolhida pelo usuário notextoIndice.Emnossoexemplo,seousuáriodigitar1notextoIndice,precisamosfazero

depósitonacontadotitularmauricio(queestánaposição1doarray).

privatevoidbotaoDeposito_Click(objectsender,EventArgse){//primeiroprecisamosrecuperaroíndicedacontaselecionadaintindice=Convert.ToInt32(textoIndice.Text);

//edepoisprecisamosleraposiçãocorretadoarray.Contaselecionada=this.contas[indice];

doublevalor=Convert.ToDouble(textoValor.Text);selecionada.Deposita(valor);textoSaldo.Text=Convert.ToString(selecionada.Saldo);}

Faça o mesmo para a ação do botão de Saque. Depois de fazer todas as modificações, teste aaplicaçãofazendo,porexemplo,umdepósitonacontaqueestánoíndice0.

Tentefazeroperaçõesemdiferentes tiposdeconta.Vejaquedependendodotipodecontaquefoicadastradanoarray,teremosumresultadodiferenteparaasoperaçõesdesaqueedepósito.Notequeo código do formulário não precisa conhecer as contas que estão gravadas no array, ele precisa

11.1PARASABERMAIS—INICIALIZAÇÃODEARRAYS 95

Page 103: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

apenasutilizarosmétodosqueestãonainterfacedeusodaconta.

Naaplicação,estamosgerenciandoascontascadastradasatravésdeumcampodetexto.Essaéumaabordagembemsimples,masquepossuidiversosproblemas:

Ocódigoesperaqueousuáriodigiteumnúmeronocampode texto.Seeledigitaruma letraouqualqueroutrocaracterenãonumérico,teremosumerro;Onúmerodigitadodeveserumíndiceválidodoarrayounovamenteteremosumerronocódigo.

Seria muito melhor se o usuário pudesse escolher uma conta cadastrada a partir de uma listagerenciada pela aplicação. Para implementarmos essa ideia, vamos utilizar um novo componente doWindowsFormchamadoComboBox.

Paraadicionarumcomboboxnoformulário,precisamosapenasabrirajanelaToolbox(Ctrl+W,

X)earrastarocomboboxparadentrodoformulário.

Para inserir os elementos que serão exibidos no combo box, precisaremos de uma variável queguardaareferênciaparaocomponente.Assimcomonocampodetexto,podemosdefinironomedessavariávelatravésdajanelaproperties.

Paraacessarajanelapropertiesdocombobox,cliquecomobotãodireitodomousenocombo

boxeselecioneaopçãoProperties.

Dentrodajanelaproperties,utilizaremosnovamenteocampo(Name)paradefinironomeda

variávelqueguardaráareferênciaparaocombobox.VamosutilizarcomboContas.

Agoraprecisamosmostrarostitularesdascontascomoitensdocombobox.Paraadicionarumnovoitemnocombobox,utilizamososeguintecódigo:

comboContas.Items.Add("Textoqueapareceránocombobox");

11.3ORGANIZANDOASCONTASCOMOCOMBOBOX

96 11.3ORGANIZANDOASCONTASCOMOCOMBOBOX

Page 104: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Logo,paramostrarostitularescomoitensdocombobox,utilizamososeguintecódigo;

comboContas.Items.Add(contas[0].Titular.Nome);comboContas.Items.Add(contas[1].Titular.Nome);

Oupodemosutilizarumforeach:

foreach(Contacontaincontas){comboContas.Items.Add(conta.Titular.Nome);}

Agoraquejáconseguimosmostrarocombobox,queremosqueaescolhadeumaopçãonocombo,façacomqueoformuláriomostreacontadotitularselecionado.

Para associar uma ação ao evento demudança de seleção do combo, precisamos apenas dar umduplocliquenocombobox.IssocriaráumnovométodonaclasseForm1:

privatevoidcomboContas_SelectedIndexChanged(objectsender,EventArgse){

}

Podemosrecuperarqualéo índice(começandodezero)do itemquefoiselecionadopelousuáriolendoapropriedadeSelectedIndexdocomboContas:

intindice=comboContas.SelectedIndex;

Esseíndicerepresentaqualéoelementodoarraydecontasquefoiselecionado,logo,podemosusá-lopararecuperaracontaquefoiescolhida:

Contaselecionada=contas[indice];

Depoisdedescobrirqualéacontaescolhida,vamosmostrá-lanoformulário:

textoTitular.Text=selecionada.Titular.Nome;textoSaldo.Text=Convert.ToString(selecionada.Saldo);textoNumero.Text=Convert.ToString(selecionada.Numero);

OcódigocompletodocomboContas_SelectedIndexChangedficadaseguinteforma:

11.3ORGANIZANDOASCONTASCOMOCOMBOBOX 97

Page 105: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

privatevoidcomboContas_SelectedIndexChanged(objectsender,EventArgse){intindice=comboContas.SelectedIndex;Contaselecionada=contas[indice];textoTitular.Text=selecionada.Titular.Nome;textoSaldo.Text=Convert.ToString(selecionada.Saldo);textoNumero.Text=Convert.ToString(selecionada.Numero);}

1. Vamossubstituirocampodetextoqueselecionaacontaparaasoperaçõesporumcombobox.Noformulário da aplicação apague o campo textoIndice , o botaoBusca e o método

botaoBusca_Click.Essesdoiscomponentesserãosubstituídospelocombobox.

Agora abra a janelaToolboxdoVisualStudio e arraste umComboBox para a aplicação.Chame

componentedecomboContas.Seuformuláriodeveficarcomooaseguir:

Naaçãodecarregamentodoformulário,vamoscadastrarascontasdoarraydentrodocombobox.Paraisso,precisamoschamarométodoAdddapropriedadeItemsdocomboContas passando

qualéotextoquequeremosmostrarcomoopçãodocombobox.

privatevoidForm1_Load(objectsender,EventArgse){//códigodeinicializaçãodoarraydecontas

foreach(Contacontaincontas){comboContas.Items.Add("titular:"+conta.Titular.Nome);}}

Quando o usuário modificar o valor do combo box, queremos mudar a conta que é exibida no

11.4EXERCÍCIOS

98 11.2EXERCÍCIOS

Page 106: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

formulário. Para criarmos o método que cuidará do evento de mudança de item selecionado docombo box, dê um duplo clique no componente. Isso criará dentro do Form1 o método

comboContas_SelectedIndexChanged:

privatevoidcomboContas_SelectedIndexChanged(objectsender,EventArgse){intindice=comboContas.SelectedIndex;Contaselecionada=this.contas[indice];textoNumero.Text=Convert.ToString(selecionada.Numero);textoTitular.Text=selecionada.Titular.Nome;textoSaldo.Text=Convert.ToString(selecionada.Saldo);}

Agora faça com que os botões Depositar e Sacar (métodos botaoDeposito_Click e

botaoSaque_Click,respectivamente)operemnacontaselecionadapelocombobox.

2. (Opcional)Vamosagoraadicionaralógicadetransferêncianoformulário.AdicioneumnovocomboboxnoformuláriochamadocomboDestinoTransferenciaeumnovobotãoque,quandoclicado,

transfere dinheiro da conta selecionada no comboContas para a conta selecionada no

comboDestinoTransferencia.

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoC#eOrientaçãoaObjetos

VocêpodetambémfazerocursodatadessaapostilanaCaelum

11.4EXERCÍCIOS 99

Page 107: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO12

Atéagora,temosemnossaaplicaçãoumcaixaeletrônicocomumnúmerofixodecontas,nessecapítulo,vamosfazerumnovoformulárioparacadastrarascontasnocaixaeletrônico.

Paranãocolocarmosaindamaiscamposnoformulárioprincipal,vamoscriarumnovoformulárionoprojeto.AbraoSolutionExplorer,cliquecomobotãodireitonoprojetoBancoeselecioneAdd

>NewItem.

Nanovajanela,selecioneaopçãoWindowsFormecoloqueFormCadastroConta.csnocampo

Name.Emseguida,cliquenobotãoAdd.

CADASTRODENOVASCONTAS

100 12CADASTRODENOVASCONTAS

Page 108: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Agoraqueterminamosdecriaronovoformulário,vamosadicionarumcampodetextoparaotitulardaconta (chamadotextoTitular) e umparaonúmeroda conta (chamadotextoNumero).Além

desses campos,precisaremos tambémdeumbotãoque, quandoclicado, realizaráo cadastrodanovaconta.Adicioneobotãoechame-odebotaoCadastro

Vamosdefiniraaçãodobotãodecadastrodessenovoformulário.Dêumduplocliquenobotãoqueacabamosdecriar.IssoabriránovamenteoeditordoVisualStudio:

publicpartialclassFormCadastroConta:Form{publicFormCadastroConta(){InitializeComponent();}

privatevoidbotaoCadastro_Click(objectsender,EventArgse){

}

12CADASTRODENOVASCONTAS 101

Page 109: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

}

Naaçãodobotão,queremoscriarumanova instânciadeconta,ContaCorrente por exemplo, e

depoispreencherosseusdados:

privatevoidbotaoCadastro_Click(objectsender,EventArgse){ContanovaConta=newContaCorrente();novaConta.Titular=newCliente(textoTitular.Text);novaConta.Numero=Convert.ToInt32(textoNumero.Text);}

Agora que inicializamos a conta, precisamos cadastrá-la no array que está na classe Form1 .

Precisamos, portanto, acessar a instância de Form1 a partir de FormCadastroConta. Queremos

garantirque,naconstruçãodoFormCadastroConta, teremosainstânciadeForm1,portantovamos

modificaroconstrutordaclasseparareceberoformulárioprincipal:

publicpartialclassFormCadastroConta:Form{privateForm1formPrincipal;

publicFormCadastroConta(Form1formPrincipal){this.formPrincipal=formPrincipal;InitializeComponent();}

//Açãodecadastrodeconta}

Precisamos colocar a conta criada no array que contém todas as contas cadastradas que está noformulárioprincipaldaaplicação.

Parafazerisso,podemosmudaravisibilidadedoatributo(deixarocontaspúblico),masissoéumaviolaçãodeencapsulamento,estamosclaramentevendoosdetalhesdeimplementaçãodaclasseForm1.

Portanto, precisamos colocar ummétodo que adiciona uma nova conta na interface de uso da classeForm1.

publicpartialclassForm1{//Esseéomesmoarrayquecolocamosnocapítulodearrays.privateConta[]contas;

//outrosmétodosdeForm1

publicvoidAdicionaConta(Contaconta){//implementaçãodométodoadicionaconta}}

Inicialmente,temoszerocontascadastradasnosistemaeaprimeiracontaserácolocadanaposiçãozero, no cadastro da segunda, temos 1 conta já cadastrada e a próxima será colocada na posição 1.Repare que sempre colocamos a conta na posição equivalente ao número de contas que já estãocadastradas. Então para implementarmos o AdicionaConta, precisaremos de um novo atributo no

102 12CADASTRODENOVASCONTAS

Page 110: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

formulárioquerepresentaonúmerodecontasquejáforamcadastradas.

publicpartialclassForm1{privateConta[]contas;//guardaonúmerodecontasquejáforamcadastradasprivateintnumeroDeContas;

//outrosmétodosdeForm1

publicvoidAdicionaConta(Contaconta){this.contas[this.numeroDeContas]=conta;this.numeroDeContas++;}}

Alémdecolocaracontanoarray,precisamostambémregistraracontanocomboContas.

publicvoidAdicionaConta(Contaconta){this.contas[this.numeroDeContas]=conta;this.numeroDeContas++;comboContas.Items.Add("titular:"+conta.Titular.Nome);}

Precisamosutilizaressenovométododentrodoformuláriodecadastroparacadastraranovaconta:

privatevoidbotaoCadastro_Click(objectsender,EventArgse){ContanovaConta=newContaCorrente();novaConta.Titular=newCliente(textoTitular.Text);novaConta.Numero=Convert.ToInt32(textoNumero.Text);

this.formPrincipal.AdicionaConta(novaConta);}

Agoraquetemostodaalógicapronta,precisamosapenascolocarumbotãonoformulárioprincipalqueabreoformuláriodecadastrodenovaconta.Chamá-lo-emosdebotaoNovaConta:

12CADASTRODENOVASCONTAS 103

Page 111: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Na ação desse botão, precisamos instanciar o FormCadastroConta passando a instância do

formulário principal. Dê um duplo clique no botão que acabamos de incluir no formulário paraimplementarsuaação:

privatevoidbotaoNovaConta_Click(objectsender,EventArgse){//thisrepresentaainstânciadeForm1queestásendoutilizadapelo//WindowsFormFormCadastroContaformularioDeCadastro=newFormCadastroConta(this);}

Paramostraroformulário,utilizaremosométodoShowDialogdoFormCadastroConta

privatevoidbotaoNovaConta_Click(objectsender,EventArgse){FormCadastroContaformularioDeCadastro=newFormCadastroConta(this);formularioDeCadastro.ShowDialog();}

Comissoterminamosocadastrodenovascontasnaaplicação.

TemososeguintecódigonométodoqueéexecutadonoLoaddoformulárioprincipal:

privatevoidForm1_Load(objectsender,EventArgse){this.contas=newConta[3];

//vamosinicializaralgumasinstânciasdeConta.this.contas[0]=newConta();this.contas[0].Titular=newCliente("victor");this.contas[0].Numero=1;

this.contas[1]=newContaPoupanca();this.contas[1].Titular=newCliente("mauricio");this.contas[1].Numero=2;

this.contas[2]=newContaCorrente();this.contas[2].Titular=newCliente("osni");this.contas[2].Numero=3;

foreach(Contacontaincontas){comboContas.Items.Add(c.Titular.Nome);}}

Veja que estamos colocando as contas diretamente na posição correta do array,mas não estamosatualizando o atributo numeroDeContas que incluímos no formulário. Além disso, inicializamos o

arraycomapenas3posições,logonãotemosmaisespaçoparacadastrarasnovascontas.

Para resolvero segundoproblema,precisamos simplesmentemodificaro tamanhodoarrayque éalocadopara,porexemplo,aceitaratédezcontas:

12.1UTILIZANDOOADICIONACONTANOLOADDOFORMULÁRIO

104 12.1UTILIZANDOOADICIONACONTANOLOADDOFORMULÁRIO

Page 112: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

privatevoidForm1_Load(objectsender,EventArgse){this.contas=newConta[10];

//restodocódigodométodo}

Pararesolveroprimeiroproblema,odeatualizarovalordoatributonumeroDeContas,precisamos

apenasdeumincrementodepoisdeadicionarcadaumadascontasnoarray:

privatevoidForm1_Load(objectsender,EventArgse){this.contas=newConta[10];

//vamosinicializaralgumasinstânciasdeConta.this.contas[0]=newConta();this.contas[0].Titular=newCliente("victor");this.contas[0].Numero=1;this.numeroDeContas++;

this.contas[1]=newContaPoupanca();this.contas[1].Titular=newCliente("mauricio");this.contas[1].Numero=2;this.numeroDeContas++;

this.contas[2]=newContaCorrente();this.contas[2].Titular=newCliente("osni");this.contas[2].Numero=3;this.numeroDeContas++;

foreach(Contacontaincontas){comboContas.Items.Add(c.Titular.Nome);}}

Vejaquenocódigodométodoestamoscadastrandoacontanoarray, incrementandoonúmerodecontase,porfim,adicionandoacontanocomboContas.Essecódigofazexatamenteomesmotrabalho

queométodoAdicionaContaquecriamosnessecapítulo.Então,podemosreutilizá-lo:

privatevoidForm1_Load(objectsender,EventArgse){this.contas=newConta[10];

//vamosinicializaralgumasinstânciasdeConta.Contac1=newConta();c1.Titular=newCliente("victor")c1.Numero=1;this.AdicionaConta(c1);

Contac2=newContaPoupanca();c2.Titular=newCliente("mauricio");c2.Numero=2;this.AdicionaConta(c2);

Contac3=newContaCorrente();c3.Titular=newCliente("osni");c3.Numero=3;this.AdicionaConta(c3);}

12.1UTILIZANDOOADICIONACONTANOLOADDOFORMULÁRIO 105

Page 113: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

ReparequecomessecódigoométodoForm1_Loadnãoprecisamaissepreocuparcomosdetalhes

de comoas contas são armazenadas e nemde comoadicionar a conta nocomboContas.Todo esse

conhecimentoficaencapsuladonométodoAdicionaConta.

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

CasadoCódigo,LivrosdeTecnologia.

1. Vamos criar um novo formulário que será responsável por fazer o cadastro de novas contas naaplicação.NajaneladoSolutionExplorer,cliquecomobotãodireitononomedoprojetoeescolhaaopçãoAdd>NewItem.

Najaneladenovoitem,escolhaaopçãoWindowsFormeutilizeFormCadastroContacomonome

do novo formulário que será criado.Dentro desse formulário, coloque dois campos de texto, umchamadotextoNumeroeoutrochamadotextoTitular.Alémdisso,adicionetambémumnovo

botão nesse formulário. Esse será o botão que cadastrará a nova conta. Chame o botão debotaoCadastro.

2. Vamos agora implementar a ação do botão de cadastro desse novo formulário (oFormCadastroConta).Dêumduplocliquenobotãoqueacabamosdeadicionar.Dentrodaaçãodo

botão, leia as informações que foram digitadas no formulário e utilize-as para criar uma novaContaCorrente:

privatevoidbotaoCadastro_Click(objectsender,EventArgse){ContaCorrentenovaConta=newContaCorrente();novaConta.Titular=newCliente(textoTitular.Text);novaConta.Numero=Convert.ToInt32(textoNumero.Text);}

AgoralocalizeoconstrutordoFormCadastroConta:

Seuslivrosdetecnologiaparecemdoséculopassado?

12.2EXERCÍCIOS

106 12.2EXERCÍCIOS

Page 114: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

publicFormCadastroConta(){InitializeComponent();}

Faça comque esse construtor recebaumargumentodo tipoForm1 chamadoformPrincipal.

Guardeovalorquefoipassadodentrodeumnovoatributo.Seucódigodeveficarparecidocomoquesegue:

publicpartialclassFormCadastroConta:Form{privateForm1formPrincipal;

publicFormCadastroConta(Form1formPrincipal){this.formPrincipal=formPrincipal;InitializeComponent();}

privatevoidbotaoCadastro_Click(objectsender,EventArgse){ContaCorrentenovaConta=newContaCorrente();novaConta.Titular=newCliente(textoTitular.Text);novaConta.Numero=Convert.ToInt32(textoNumero.Text);}}

3. Dentrodaclassedoformulárioprincipal,arquivoForm1.cs,adicioneumnovoatributochamado

numeroDeContas e umnovométodo chamadoAdicionaConta que receberá uma conta como

argumentoeacadastraránoarraydecontasdoformulário:

publicpartialclassForm1:Form{privateintnumeroDeContas;

//EssearrayjáestavadeclaradonaclasseprivateConta[]contas;

//implementaçãodasaçõesdoformulário

publicvoidAdicionaConta(Contaconta){this.contas[this.numeroDeContas]=conta;this.numeroDeContas++;comboContas.Items.Add("titular:"+conta.Titular.Nome);}}

4. Abranovamenteocódigodobotãodoformuláriodecadastrodenovascontas.DentrodométodobotaoCadastro_Click,utilizeoAdicionaContadoformPrincipalpassandoacontaquefoi

criadaanteriormente.

privatevoidbotaoCadastro_Click(objectsender,EventArgse){ContaCorrentenovaConta=newContaCorrente();novaConta.Titular=newCliente(textoTitular.Text);novaConta.Numero=Convert.ToInt32(textoNumero.Text);

12.2EXERCÍCIOS 107

Page 115: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

this.formPrincipal.AdicionaConta(novaConta);}

5. Dentro do formulário principal da aplicação (Form1.cs), coloque um novo botão que quando

clicadomostraráoformuláriodecadastro.ChameessenovobotãobotaoNovaConta.

privatevoidbotaoNovaConta_Click(objectsender,EventArgse){FormCadastroContaformularioCadastro=newFormCadastroConta(this);formularioCadastro.ShowDialog();}

6. Antesdetestarocadastrodecontasqueacabamosdeimplementar,abraométodoForm1_Loaddo

formulárioprincipalecadastreascontaspadrãodosistemautilizandoométodoAdicionaConta

quecriamosemumexercícioanterior:

privatevoidForm1_Load(objectsender,EventArgse){this.contas=newConta[10];

//vamosinicializaralgumasinstânciasdeConta.Contac1=newConta();c1.Titular=newCliente("victor")c1.Numero=1;this.AdicionaConta(c1);

Contac2=newContaPoupanca();c2.Titular=newCliente("mauricio");c2.Numero=2;this.AdicionaConta(c2);

Contac3=newContaCorrente();c3.Titular=newCliente("osni");c3.Numero=3;this.AdicionaConta(c3);}

Depoisdefazeressamodificaçãofinal,executeaaplicaçãoetesteocadastro.

7. (Opcional)Noformuláriodecadastro,adicioneumcombobox(chamadocomboTipoConta) que

permitaaescolhadotipodecontaqueserácadastrado.

8. (Desafio)Noprojetoestamosatualmenteutilizandoumarraydecontascomumtamanhofixoeporissosópodemoscadastrarumnúmerolimitadodecontas.ModifiqueométodoAdicionaContada

classeForm1paraqueeleaceiteumnúmeroilimitadodecontas.

108 12.2EXERCÍCIOS

Page 116: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO13

Em nosso banco os clientes podem ter dois tipos de conta até o momento: conta corrente ou contapoupança.Parainstanciarestestiposdeconta,poderíamosusaroseguintecódigo:

//InstanciarumanovacontacorrenteContaCorrentecontaCorrente=newContaCorrente();

//InstanciaumanovacontapoupançaContaPoupancacontaPoupanca=newContaPoupanca();

Nos capítulos anteriores, aprendemos que essas duas classes têm muito em comum, ambas sãocontas.Nãoapenastêmatributosemcomum,mastambémcomportamentos.Paraevitararepetiçãodocódigoemambasasclasses,vimoscomoisolarestecódigorepetidoemumaclasseConta,efazercom

queasclassesContaCorrenteeContaPoupancaherdemdessaclassemãetodoocódigoemcomum.

Além da reutilização de código, também vimos a possibilidade de escrever métodos que podemreceber argumentos tanto do tipo ContaCorrente quanto do tipo ContaPoupanca , utilizando

polimorfismo.Bastafazermososmétodosreferenciaremotipomaisgenérico,nocaso,Conta:

publicclassTotalizadorDeContas{//...publicvoidSoma(Contaconta){//...}}

Masoqueacontecequandoexecutamosaseguintelinha:

Contac=newConta();

CriamosumnovoobjetodotipoConta.Masesseobjetofazalgumsentidoparanossasregrasde

negócio?Éumacontagenérica,nãosendonemcontacorrenteenempoupança.

Nestecaso,nãodeveríamospermitirainstanciaçãodeobjetosConta.

Contaéapenasumaideiaemnossodomínio,umaformagenéricadereferenciarmososdoistipos

de conta que realmente existem em nosso sistema, ContaCorrente e ContaPoupanca. Podemos

evitaracriaçãodeobjetosdotipoContadefinindoaclassecomoabstrata:

publicabstractclassConta

CLASSESABSTRATAS

13CLASSESABSTRATAS 109

Page 117: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

{//...}

Destaforma,nãopodemosmaiscriarobjetosdotipoConta,maspodemosaindausarvariáveisdo

tipoconta,parareferenciarobjetosdeoutrostipos:

Contaconta=newConta();//nãocompila,nãopodecriarobjetosabstratos

Contacc=newContaCorrente();//pode,objetoédotipoContaCorrente

Contacp=newContaPoupanca();//pode,objetoédotipoContaPoupanca

ReparequeocalculonecessáriopararealizarumsaqueédiferenteemcadaumdostiposdeConta.

SabemosqueumacontadeveterummétodoSaca,masa implementaçãodestemétododependede

regras específicas de cada tipo diferente de conta em nosso sistema. Uma solução possível seriaimplementá-losemfazernada,masdizendoqueelepodesersobrescrito(virtual):

publicabstractclassConta{publicvirtualvoidSaca(doublevalor){//nãofaznada}//...}

EmanterocódigoSacaoriginalnasclassesfilhas,dizendoqueelessobrescrevem(override)o

métodonaclassepai:

publicclassContaCorrente:Conta{publicoverridevoidSaca(doublevalor){this.Saldo-=(valor+0.10);}//...}

publicclassContaPoupanca:Conta{publicoverridevoidSaca(doublevalor){this.Saldo-=valor;}//...}

Desejamosquetodaclassefilhaimplementesuaprópriaversãodométodo,comocomportamentoreferenteaotipodaconta.MasseesquecermosdesobrescreverométodoSacaemumasubclasse,o

métodoherdadoda classeConta será executado, que não faz nada.Não queremos isso!Queremos

obrigarasclassesfilhaaimplementarométodoSaca.

Podemosobrigartodasasclassesfilhasasobrescreveremummétodonaclassemãe,bastadeclararessemétodocomomodificadorabstractaoinvésdevirtual.Todavezquemarcamosummétodo

110 13CLASSESABSTRATAS

Page 118: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

comomodificadorabstract,eleobrigatoriamentenãopodeterumaimplementaçãopadrão:

publicabstractclassConta//marcandoqueaclasseestáincompleta{publicabstractvoidSaca(doublevalor);//marcandoqueométodoestáincompleto}

Comessamodificação,ométodoSacapassaarepresentarapenasumaideia,queprecisadeuma

implementação concreta nas classes filhas. Caso não implementemos esse método na classe filha, ocompilador emitirá um erro, avisando da obrigatoriedade de sobrescrever este método. Então seimplementássemos,porexemplo,aclasseContaPoupancasemdefiniraimplementaçãodoSaca, o

códigodaclassenãocompilará:

publicclassContaPoupanca:Conta{//EssaclassenãocompilapoisnãocolocamosaimplementaçãoparaoSaca}

Podemosterumaclasseabstratasemnenhummétodoabstrato,masnãoocontrário.Seaclassetempelomenosummétodoabstrato,eladeveserabstratatambémpoiscomoométodoestáincompleto,aclassenãoestácompleta.

1. Transforme a classe Conta em uma classe abstrata. Repare que agora teremos um erro de

compilação em todos os pontos do código em que tentamos instanciar o tipo Conta. Por quê?

Modifiqueocódigodasuaaplicaçãoparaqueacontanãoseja instanciada,assimcorrigiremososerrosdecompilação.Nãoseesqueçadesempretestaroseucódigo.

2. ReparequeherdamososmétodosSacaeDepositadaclasseConta,porémcadatipodeConta

sobrescreve essesmétodos, logo eles são bons candidatos paramétodos abstratos. Transforme osmétodosSacaeDepositaemmétodosabstratos,reparequecomissotodasasclassesfilhassão

obrigadasadarumaimplementaçãoparaessesmétodos.

13.1EXERCÍCIOS

13.1EXERCÍCIOS 111

Page 119: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

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

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Agoraéamelhorhoradeaprenderalgonovo

112 13.1EXERCÍCIOS

Page 120: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO14

Nosso banco agora suporta Contas de Investimento. Já sabemos como fazer: basta herdar da classeConta:

publicclassContaInvestimento:Conta{//comportamentosespecíficosdacontainvestimento}

Por lei, uma vez por ano devemos pagar um tributo ao governo relacionado às contas deinvestimentoecontasdepoupança.OmesmonãoacontececomumasimplesContaCorrente.

Para resolver esse problema, podemos criar ummétodo em ambas as classes que calcula o valordessetributo.Porexemplo:

publicclassContaPoupanca:Conta{//outrosmetodos

publicdoubleCalculaTributo(){returnthis.Saldo*0.02;}}publicclassContaInvestimento:Conta{//outrosmetodos

publicdoubleCalculaTributo(){returnthis.Saldo*0.03;}}

Excelente.OsmétodossóficamnasContasquerealmentesofremessetributo.

Agora, a próxima funcionalidade é a geração de um relatório, no qual devemos imprimir aquantidade total de tributos pagos por todas as Contas Investimento ou Poupanca do nosso banco.Precisamosdeumaclassequeacumulaovalordetodosostributosdetodasascontasdobanco.Esseéumproblemaparecidocomoquejátivemosantes:

publicclassTotalizadorDeTributos{publicdoubleTotal{get;privateset;}

publicvoidAcumula(ContaPoupancacp){Total+=cp.CalculaTributo();}

INTERFACES

14INTERFACES 113

Page 121: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

publicvoidAcumula(ContaInvestimentoci){Total+=ci.CalculaTributo();}}

Pronto.AgorabastapassarmosContaInvestimentoouContaPoupancaenossaclasseacumulará

ovalordotributo.Reparequetodavezqueumanovacontasofrerumtributo,precisaremoslembrardevoltarnaclasseTotalizadorDeTributosecriarumnovométodoAcumula().

Noscapítulosanteriores,resolvemosissousandopolimorfismo.Seaclassepaipossuirométodoemcomum,entãobastarecebermosumareferênciaprotipopai:

publicclassTotalizadorDeTributos{publicdoubleTotal{get;privateset;}

publicvoidAcumula(Contac){Total+=c.CalculaTributo();}}

MasseráquefazsentidocolocarométodoCalculaTributo()naclasseConta?

publicabstractclassConta{//restodaclasseaquipublicabstractdoubleCalculaTributo();}

Nem todas as Contas são tributáveis. Se fizermos isso, a classe ContaCorrente ganhará esse

método,maselanãosofretributo!

Precisamos achar umamaneira de "achar um pai em comum" apenas para aContaCorrente e

ContaInvestimento.ClassesemC#nãopodemterdoispais.Masoquepodemosfazerédizerparao

compilador quegarantiremos a existência dométodoCalculaTributo() nas classes que chegarem

paraométodoAcumula().

Comofazemosisso?Simples.Fazemosaclasse"assinar"umcontrato!Nessecaso,queremosassinaro contrato que fala que somos Tributáveis. Contratos no C# são conhecidos como interfaces. Adeclaração de uma interface é praticamente igual a de uma classe, porém utilizamos a palavrainterfaceaoinvésdeclass.

publicinterfaceTributavel{//códigodainterface}

AconvençãodenomesdoC#paraumainterfaceéseguiramesmaconvençãodenomenclaturadeclassesporémcomumInocomeçodonome:

publicinterfaceITributavel{

}

114 14INTERFACES

Page 122: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Éumaboapráticacolocarocódigodainterfacedentrodeumarquivoseparadocomomesmonomedainterface.Porexemplo,ainterfaceITributavelficarianoarquivoITributavel.cs.Dentroda

interface,queremoscolocaradeclaraçãodométodoCalculaTributo().Métodosdeclaradosemuma

interface nunca possuem implementação e sempre são públicos. A declaração da interfaceITributavelcomométodoCalculaTributo()ficadaseguinteforma:

//ArquivoITributavel.cs

publicinterfaceITributavel{doubleCalculaTributo();}

QueremosfazercomqueacontapoupançaassineocontratoITributavelqueacabamosdecriar,

paraisso,precisamoscolocaronomedainterfacequequeremosimplementarlogoapósadeclaraçãodaclassepai:

//ArquivoContaPoupanca.cs

publicclassContaPoupanca:Conta,ITributavel{//ImplementaçãodosmétodosdaContaPoupanca}

ComoainterfaceITributaveldeclaraométodoCalculaTributo(), toda classe que assina a

interface é obrigada a dar uma implementação para essa funcionalidade, se não implementarmos ométododainterface,aclassenãocompilará.

publicclassContaPoupanca:Conta,ITributavel{//restodaclasseaqui

//métodoquesouobrigadoaimplementarpublicdoubleCalculaTributo(){returnthis.Saldo*0.02;}}

Repare que, para implementarmos o método da interface, não podemos utilizar a palavraoverride , ela é reservada para a sobrescrita de métodos da Herança. A mesma coisa para a

ContaInvestimento:

publicclassContaInvestimento:Conta,ITributavel{//restodaclasseaqui

//métodoquesouobrigadoaimplementarpublicdoubleCalculaTributo(){returnthis.Saldo*0.03;}}

14INTERFACES 115

Page 123: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Alémdisso,podemosfazercomqueumaclasseassineumainterfacesemherdardeoutraclasse.Porexemplo, o banco também trabalha com seguros de vida que também são tributáveis, logo podemosrepresentaressaclassecomoseguintecódigo:

publicclassSeguroDeVida:ITributavel{publicdoubleCalculaTributo(){//implementaçãodoCalculaTributo}}

Dessa forma, podemos dizer que a classe TotalizadorDeTributos recebe um ITributavel

qualquer.Opolimorfismofuncionacominterfaces!

publicclassTotalizadorDeTributos{publicdoubleTotal{get;privateset;}

publicvoidAcumula(ITributavelt){Total+=t.CalculaTributo();}}

Excelente!Vejaquecominterfacesconseguimosfazercomqueumconjuntodeclassesimplementeosmesmosmétodos.

Interfaces são bemmais simples do que classes. Elas não tem atributos e seusmétodos não temimplementação.Ainterfaceapenasnosgarantequeométodoexistiránaquelaclasse.Poressemotivo,apesardeC#não suportar herançamúltipla (ser filhodemaisdeumaclasse), podemos implementarquantasinterfacesquisermos.Bastacolocarumanafrentedaoutra:

publicclassContaInvestimento:Conta,ITributavel,OutraInterfaceQualquer{//implementaosmétodosdasinterfacesTributaveleOutraInterfaceQualquer}

Quando uma classe utiliza tanto herança quanto interfaces, precisamos sempre declarar qual é aclassepaiedepoisasinterfaces,assimcomofizemosnaContaPoupanca:

//Reparequeprimeirocolocamosaclassepai(Conta)edepoisasinterfaces.//Semudarmosaordem,ocódigonãocompilará.publicclassContaPoupanca:Conta,ITributavel{//implementação}

Acostume-secominterfaces.Daquiprafrente,veremosasváriasinterfacesqueexistemnoC#!

1. O banco precisa gerenciar os impostos que serão pagos por seus produtos. Para resolver esseproblema,criaremosumanovainterfacechamadaITributavel.Paracriarainterface,cliquecom

14.1EXERCÍCIOS

116 14.1EXERCÍCIOS

Page 124: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

obotãodireitodomousenonomedoprojetoeescolhaaopçãoAdd>NewItem(omesmoque

utilizamos para criar o formulário de cadastro). Na janela de novo item, escolha a opçãoInterfaceecoloqueonomeITributavel:

Faça com que essa interface declare um método chamado CalculaTributos que não recebe

nenhumargumentoedevolveumdoublequerepresentaovalordoimpostoquedeveserpago.

Ocódigodainterfacedeveficarparecidocomoseguinte:

publicinterfaceITributavel{doubleCalculaTributos();}

2. Oqueacontecesetentarmosinstanciarumainterface?

ITributavelt=newITributavel();

Errodecompilação.Interfacesnãotemimplementaçãoe,logo,nãopodemserinstanciadas.

Ocódigocompila,masoobjetonãofaznada.

OC#buscaaleatoriamenteumaclassequeimplementaessainterfaceeainstancia.

3. FaçacomqueaclasseContaCorrente implementea interfaceITributavel que acabamosde

criar,porémaindanãoimplementeométodoCalculaTributos.Tenteexecutarocódigo.Oque

aconteceu?4. ComoaContaCorrenteassinaainterfaceITributavel,precisamoscolocarumaimplementação

14.1EXERCÍCIOS 117

Page 125: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

para ométodo CalculaTributos dentro da classe, se não o código do projeto não compilará.

ImplementeométodoCalculaTributosdaContaCorrente, façacomqueaContaCorrente

pague5%deseusaldocomoimposto.5. CrieumanovaclassenobancochamadaSeguroDeVidaefaçacomqueessaclasseimplementea

interfaceITributavel.OmétodoCalculaTributosdoSeguroDeVidadevedevolverumvalor

constantede42reais.

6. Agoravamosadicionarumnovobotãonoformulárioquecalcularáosimpostosdobanco.Chame-odebotaoImpostos. No código desse botão, teste o método CalculaTributos em diferentes

situações,porexemplo:

privatevoidbotaoImpostos_Click(objectsender,EventArgse){ContaCorrenteconta=newContaCorrente();conta.Deposita(200.0);

MessageBox.Show("impostodacontacorrente="+conta.CalculaTributos());ITributavelt=conta;

MessageBox.Show("impostodacontapelainterface="+t.CalculaTributos());

SeguroDeVidasv=newSeguroDeVida();MessageBox.Show("impostodoseguro="+sv.CalculaTributos());

t=sv;MessageBox.Show("impostodoseguropelainterface"+t.CalculaTributos());}

Depoisdeimplementarseustestes,tenteclicarnobotãoparaveroqueacontece.

7. (Opcional) Crie uma nova classe chamada TotalizadorDeTributos, que será responsável por

acumularosimpostosdediferentesprodutostributáveisdobanco:

publicclassTotalizadorDeTributos{publicdoubleTotal{get;privateset;}

publicvoidAdiciona(ITributavelt){this.Total+=t.CalculaTributos();}}

Depoisdecriaressaclasse,modifiqueocódigodobotãodoexercíciopassadoparaqueeleutilizeaclassequeacabamosdecriarparacalcularototaldeimpostos.Porexemplo:

privatevoidbotaoImpostos_Click(objectsender,EventArgse){ContaCorrenteconta=newContaCorrente();conta.Deposita(200.0);

SeguroDeVidasv=newSeguroDeVida();

TotalizadorDeTributostotalizador=newTotalizadorDeTributos();totalizador.Adiciona(conta);

118 14.1EXERCÍCIOS

Page 126: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

MessageBox.Show("Total:"+totalizador.Total);totalizador.Adiciona(sv);MessageBox.Show("Total:"+totalizador.Total);}

8. (Desafio) Pesquise sobre a palavra is do C# no seguinte link http://msdn.microsoft.com/en-us/library/scekt9xw.aspx e depois tente modificar o código o botão para que ele seja capaz decalcularautomaticamenteoimpostodetodasascontascorrentesqueestãocadastradasnoarraydecontasdaaplicação.

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

CasadoCódigo,ebookcompreçodeebook.

EditoraCasadoCódigocomlivrosdeumaformadiferente

14.1EXERCÍCIOS 119

Page 127: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO15

Precisamosagoraguardaraquantidadedecontascorrenteexistentesnosistema.Umadasmaneirasdefazerissoégerenciarototaldecontaseadicionar1unidadenessetotaltodavezquecriarmosumanovaconta:

inttotalDeContasCorrente=0;

//...

ContaCorrentenovaConta=newContaCorrente();totalDeContasCorrente++;

Contudo, utilizando essa abordagem, um desenvolvedor pode esquecer de alterar a variáveltotalDeContasCorrente apóscriarumanovaContaCorrente, gerandoumerrono sistema.Para

evitarisso,seriamelhorqueaprópriaclassecontrolasseototaldecontascriadas.Umaprimeiraideiaseriaguardarumatributocomototaldecontascriadasnaclassee,noseupróprioconstrutor,adicionarumaunidadenesseatributo:

publicclassContaCorrente:Conta{//OutrosatributosdaclasseprivateinttotalDeContas=0;

publicContaCorrente(){this.totalDeContas++;}

//Métodosdaclasse}

QualseriaovalordoatributototalDeContassefossemcriadasduascontas?

ContaCorrenteprimeira=newContaCorrente();ContaCorrentesegunda=newContaCorrente();

Ambasascontasapresentariamovalor1noseuatributototalDeContas.Issoaconteceporqueo

atributototalDeContas é diferente para cadaobjetoque instanciamos, isto é, o atributopertence a

cadaobjeto.

Oquedesejamoséquequetivéssemosumatributocompartilhadoemtodososobjetosdaclasse,ouseja,queoatributopertençaàclasseaoinvésdosobjetos.

MÉTODOSEATRIBUTOSESTÁTICOS

120 15MÉTODOSEATRIBUTOSESTÁTICOS

Page 128: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Estesatributosrecebemonomedeatributosdaclasseouatributosestáticose,emC#,paracriarumatributoestáticobastacolocarapalavrastaticnadeclaraçãodoatributo:

publicclassContaCorrente:Conta{privatestaticinttotalDeContas=0;//restodocódigoexistente}

Comisso,onossoconstrutorficaria:

publicclassContaCorrente:Conta{privatestaticinttotalDeContas=0;publicContaCorrente{ContaCorrente.totalDeContas++;}//restodocódigoexistente}

Opróximopassoécriarumcontrolequemostraqualonúmerodapróximacontadisponível,istoé,ototaldecontasmaisum.Comisso,criaríamosummétodopúblicoquedevolvaototalDeContas+

1:

publicclassContaCorrente:Conta{privatestaticinttotalDeContas=0;publicContaCorrente{ContaCorrente.totalDeContas++;}publicintProximaConta(){returnContaCorrente.totalDeContas+1;}//restodocódigoexistente}

Mascomoométodopertenceaoobjeto (nãoéestático)enãoàclasse, temosque instanciarumacontaparapoderacessá-lo:

//aquiototalé0,imprimiria1,quedesejamos

ContaCorrenteconta=newContaCorrente();conta.ProximaConta();//imprime2,poisjácriamosuma

PercebaqueprecisamoscriarumnovoobjetoparachamarométodoProximaConta.Mas,aocriar

umanovaconta,ovalordototalDeContasjáfoialterado.Paraevitarisso,ométodoprecisapertencer

àclasseaoinvésdoobjeto.Demaneirasemelhanteaumatributoestático,colocandoapalavrastatic

aodeclararummétodo,estesetornaestático:

publicclassContaCorrente:Conta{//restodocódigoexistente

15MÉTODOSEATRIBUTOSESTÁTICOS 121

Page 129: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

publicstaticintProximaConta(){returnContaCorrente.totalDeContas+1;}}

Eparausaressenovométodo:

intproxima=ContaCorrente.ProximaConta();

1. Nocadastrodecontas,estamospedindoonúmeroqueserácadastradonanovaconta,masemnossobanco,duascontasnãopodemteromesmonúmero.Paragarantirmosqueonúmerodascontasseráúnico,podemosutilizarostaticdoC#paracriarumcontadordeinstânciasdecontasqueforam

criadas.

DeclarenaclassecontaumnovoatributoestáticochamadonumeroDeContasquecontaráquantas

contasforamcriadasnaaplicação.AdicioneumconstrutornaclassContaquenãorecebenenhum

argumentoegeraoNumeroutilizandoovalordoatributoestáticonumeroDeContas:

publicabstractclassConta{privatestaticintnumeroDeContas;

publicConta(){Conta.numeroDeContas++;this.Numero=Conta.numeroDeContas;}

//Restodaclassecontinuaigual}

2. Abraoformuláriodecadastrodenovascontas.Procurenocódigodesseformulárioaaçãodobotãoque cadastra a nova conta utilizando os dados digitados pelo usuário, métodobotaoCadastro_Click.Dentrodessemétodo,apaguea linhaqueatribuionúmerodacontaque

serácriada.Essenúmeroagoraégeradopelaprópriaclasseconta.

3. Agoraqueacontageraseunúmero,nãoémaispossívelparaousuáriosaberqualseráonúmerodacontaqueserácadastrada.Pararesolvermosesseproblema,vamosmostrarqualseráonúmerodapróximacontanocampotextoNumerodoformuláriodecadastro.

OnumeroDeContaséumatributoestáticoeprivadodentrodaclasseConta, logoo formulário

não pode acessar o valor desse atributo paramostrá-lo. Crie um novométodo estático na classeContachamadoProximoNumeroqueseráresponsávelpordevolveronúmerodapróximaConta

queserácriadapelaaplicação.

ComoovalordoatributonumeroDeContaséincrementadoapenasquandooconstrutordaConta

15.1EXERCÍCIOSOPCIONAIS

122 15.1EXERCÍCIOSOPCIONAIS

Page 130: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

é executado, para exibir qual será o próximo número da conta que será criada, retorne onumeroDeContas+1:

publicstaticintProximoNumero(){returnnumeroDeContas+1;}

4. Agoravamosfazeroformuláriodecadastromostraronúmerodapróximacontaparaousuário.DêumduplocliquenoformuláriodecadastroparafazercomqueoVisualStudiocrieométodoqueserá executado no load do formulário. Dentro desse método, mostre o resultado do métodoConta.ProximoNumero()nocampotextoNumero.

privatevoidFormCadastroConta_Load(objectsender,EventArgse){textoNumero.Text=Convert.ToString(Conta.ProximoNumero());}

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

Algumasvezescriamosclassesquecontêmapenasmétodosauxiliaresestáticos.Comoessasclassesnão possuem métodos nem propriedades de instâncias, não queremos permitir que elas sejaminstanciadas. Nessas situações, podemos utilizar as classes estáticas do C#. Para criar uma classeestática,precisamosapenasutilizarapalavrastaticemsuadeclaração:

publicstaticclassFunções{//implementação}

Quando uma classe é declarada como estática, ela não pode ser instanciada e nem herdada e,portanto,sópodepossuirmembrosestáticos.

publicstaticclassFuncoes

JáconheceoscursosonlineAlura?

15.2PARASABERMAISCLASSESESTÁTICAS

15.2PARASABERMAISCLASSESESTÁTICAS 123

Page 131: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

{//Essemétodoéválidodentrodeumaclasseestática.publicstaticboolMetodoEstatico(){//implementação}

//Essemétodonãoéválidodentrodeumaclasseestática.publicboolMetodoInstancia(){//implementação}}

124 15.2PARASABERMAISCLASSESESTÁTICAS

Page 132: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO16

VoltandoànossaclasseContaPoupanca,umdosseusmétodoséoSaca.Setentarmossacarumvalor

superior ao saldodo cliente, ométodonãopermitirá o saque.Contudo, quemchamouométodonãosaberáseosaque foi realizadoounão.Comonotificarqueminvocouométodoqueosaque foi feitocomsucessoounão?

UmaprimeirasoluçãoseriaalterarométodoSacapararetornarumbooleanoindicandoseosaque

foiounãoefetuado:

publicclassContaPoupanca:Conta{publicoverrideboolSaca(doublevalor){if(valor+0.10<=this.Saldo){this.Saldo-=valor+0.10;returntrue;}else{returnfalse;}}//Restodocódigodaclasse}

Assim,podemossaberseosaquefoiefetuadoaochamarométodo:

Contaconta=newContaPoupanca();//Inicializaacontaif(conta.Saca(100.0)){MessageBox.Show("Saqueefetuado");}

Essaabordageméimportante,porexemplo,nocasodeumcaixaeletrônico.Nósprecisamossaberseosaquefoiefetuadoounãoantesdeliberarmosodinheiroparaocliente.Contudo,umadesvantagemdessaabordageméque,seesquecermosdetestaroretornodométodoSaca,podemosliberardinheiro

paraoclientesempermissão.

Emesmoinvocandoométodoetratandooseuretornodemaneiraadequada,oquefaríamossefosse

EXCEÇÕES

16.1RETORNODOMÉTODOPARACONTROLARERROS

16EXCEÇÕES 125

Page 133: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

necessáriosinalizarexatamentequalfoiotipodeerroqueaconteceu,comoquandoousuáriopassouumvalornegativocomoquantidade?

Umasoluçãoseriaalteraroretornodebooleanparanúmerointeiroeretornarocódigodoerroqueocorreu. Isso é considerado umamá prática, pois o valor devolvido é "mágico" e só legível peranteextensadocumentação(magicnumbers),alémdenãoobrigaroprogramadoratrataresseretorno,oquepodelevaroprogramaacontinuarexecutandoemumestadoinconsistente.

Umoutroproblemaaconteceriaseométodojáretornassealgumvalor.Dessejeito,nãodariaparaalteraroretornoparaindicarseosaquefoirealizadoounão.

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoC#eOrientaçãoaObjetos

Para evitar esses problemas, o C# nos permite tratar essas exceções à regra de uma maneiradiferente:atravésdeexceptions.Emvezde retornarmosumvalor dizendo se umaoperação foi bemsucedida,nós lançamosumaexceçãoà regrapadrão, aocomportamentopadrão,dizendoquealgodeerradoaconteceu.Nonossocaso,utilizaremosaexceçãoException,indicandoquehouveumerrona

operaçãodesaque:

publicclassContaPoupanca:Conta{publicoverridevoidSaca(doublevalor){if(valor+0.10>this.Saldo){thrownewException("Valordosaquemaiorqueosaldo");}else{this.Saldo-=valor+0.10;}}}

VocêpodetambémfazerocursodatadessaapostilanaCaelum

16.2CONTROLANDOERROSCOMEXCEÇÕES

126 16.2CONTROLANDOERROSCOMEXCEÇÕES

Page 134: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Atéomomento,aprendemoscomolançarumaexceptionquandoalgumcomportamentoocorreudeforma fora do comum.Mas, o que essa exception influencia na classe que o chamou? Por exemplo,vamos ver o que acontece quando tentamos sacar umvalor superior ao saldo do cliente.Rode a suaaplicaçãocomF5etentesacarumvalorsuperioraosaldodeumcliente.

Aoclicarnobotãodesaque,aexecuçãodocódigoseráinterrompidanalinhaemqueaexceçãoélançada.IssoocorreporqueoF5rodaonossoprogramaemmododebug.SerodarmosoprogramaforadomododebugcomCtrl+F5,comosefosseumusuáriorodandooprograma,veríamosumajanela

dizendoqueocorreuumerro:

Mas, nós não queremos que o usuário receba talmensagemna tela.Então, não podemos chamardiretamenteummétodoquepodelançarumaexceção.Aoinvésdisso,devemostentarchamarométodo:senãoforlançadanenhumaexceção,ok;casocontrário,devemospegaraexceçãoeexecutarumtrechodecódigoreferenteàexceção.

Paratentarexecutarumtrechodecódigoquepodelançarumaexceção,devemoscolocá-lodentrodeumblocotry.Nonossocaso,colocaremosdentrodoblocoquetrataocliquedobotãosaque:

privatevoidbotaoSaque_Click(objectsender,EventArgse){intindice=comboContas.SelectedIndex;doublevalor=Convert.ToDouble(textoValor.Text);Contaselecionada=this.contas[indice];try{selecionada.Saca(valor);textoSaldo.Text=Convert.ToString(selecionada.Saldo);MessageBox.Show("DinheiroLiberado");}}

Eparapegaraexceçãocasosejalançadaetratá-la,devemospôrocódigodentrodeumblockcatch:

privatevoidbotaoSaque_Click(objectsender,EventArgse){intindice=comboContas.SelectedIndex;doublevalor=Convert.ToDouble(textoValor.Text);Contaselecionada=this.contas[indice];try{selecionada.Saca(valor);

16.2CONTROLANDOERROSCOMEXCEÇÕES 127

Page 135: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

textoSaldo.Text=Convert.ToString(selecionada.Saldo);MessageBox.Show("DinheiroLiberado");}catch(Exceptionex){MessageBox.Show("Saldoinsuficiente");}}

Nessebloco,casoométodoSaca lanceumaexceção,oblococatchseráexecutadomostrandoa

mensagemSaldoInsuficiente.Nocasodeumaexceção,amensagemDinheiroLiberadonãoé

exibida.

Uma outra situação exceptional ocorre quando o usuário da classeConta tenta sacar um valor

negativo,claramenteumvalorinválidoparaosaque.Nessecasotambémqueremoslançarumaexceção:

publicoverridevoidSaca(doublevalor){if(valor<0.0){thrownewException();}if(valor+0.10>this.Saldo){thrownewException("Valordosaquemaiorqueosaldo");}else{this.Saldo-=valor+0.10;}}

QuandopassamosumvalornegativoparaométodoSaca, ométodo lançará umaException,

portantoo códigodoblococatch do caixa eletrônico será executadopara tratar a exceçãogerada,

exibindoparaousuárioamensagemSaldoInsuficiente. Porémessamensagemestá claramente

errada.

Repareque,parajogarmosaexceção,precisamosexecutarumnew,ouseja,aExceptionéuma

classedoC#!Podemoscriarumahierarquiadeexceçõesutilizandoaherançaparaindicarqualfoiotipodeerroqueocorreu.

Para criarmos um novo tipo de exceção, precisamos apenas criar uma nova classe que herde deException.Vamoscriarumaexceçãoqueindicaqueocorreuumerroporsaldoinsuficientenaconta,

aSaldoInsuficienteException:

publicclassSaldoInsuficienteException:Exception{}

16.3TRATANDOMÚLTIPLASEXCEÇÕES

128 16.3TRATANDOMÚLTIPLASEXCEÇÕES

Page 136: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

EvamosutilizaroSaldoInsuficienteExceptionnométodoSacadaclasseContaPoupanca:

publicoverridevoidSaca(doublevalor){if(valor<0.0){thrownewException();}if(valor+0.10>this.Saldo){thrownewSaldoInsuficienteException();}else{this.Saldo-=valor+0.10;}}

Quandoousuáriopassaumargumentonegativo ainda lançamosuma exceçãogenérica.Podemoscriarumnovotipodeexceçãoqueindicaqueoargumentopassadoéinválido.Porém,oC#jápossuiumconjunto de exceções padrão na linguagem (http://msdn.microsoft.com/pt-br/library/system.exception.aspx#inheritanceContinued). Dentre essas exceções, existe aArgumentException, que indica que o argumento de um método é inválido. Vamos utilizar essa

exceçãononossocódigo:

publicoverridevoidSaca(doublevalor){if(valor<0.0){thrownewArgumentException();}if(valor+0.10>this.Saldo){thrownewSaldoInsuficienteException();}else{this.Saldo-=valor+0.10;}}

Agoraocódigodocaixaeletrônicopodetratardeformadiferentecadaumdostiposdeexceção:

privatevoidbotaoSaque_Click(objectsender,EventArgse){intindice=comboContas.SelectedIndex;doublevalor=Convert.ToDouble(textoValor.Text);Contaselecionada=this.contas[indice];try{selecionada.Saca(valor);textoSaldo.Text=Convert.ToString(selecionada.Saldo);MessageBox.Show("DinheiroLiberado");}catch(SaldoInsuficienteExceptionex){MessageBox.Show("Saldoinsuficiente");}

16.3TRATANDOMÚLTIPLASEXCEÇÕES 129

Page 137: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

catch(ArgumentExceptionex){MessageBox.Show("Nãoépossívelsacarumvalornegativo");}}

Mas o que deve ser colocado dentro de um bloco try? Será que devemos colocar apenas a

execuçãodométodoquelançaaexceção?

privatevoidbotaoSaque_Click(objectsender,EventArgse){intindice=comboContas.SelectedIndex;doublevalor=Convert.ToDouble(textoValor.Text);Contaselecionada=this.contas[indice];try{selecionada.Saca(valor);}catch(SaldoInsuficienteExceptionex){MessageBox.Show("Saldoinsuficiente");}catch(ArgumentExceptionex){MessageBox.Show("Nãoépossívelsacarumvalornegativo");}textoSaldo.Text=Convert.ToString(selecionada.Saldo);MessageBox.Show("DinheiroLiberado");}

Ao executar o código, vemos que ométodo Saca lança a exceção de saldo insuficiente. Mas,

mesmoassim,ocaixaliberadinheiroparaousuário.IssoaconteceporqueaexceçãolançadanométodoSacajáfoitratadanosblocoscatcheaexecuçãodoprogramacontinuanormalmente.

Oblocotry deveconter todaa lógicadenegócioque será executadaemumasituaçãonormal,

quando não ocorrem casos excepcionais. Assim, podemos nos preocupar apenas com a lógica denegóciosedepoisnospreocupamoscomoserrosqueaconteceram.

Nocasodosaque,queremosexecutarométodoSacaedepoisemitirodinheirodentrodobloco

try.

privatevoidbotaoSaque_Click(objectsender,EventArgse){intindice=comboContas.SelectedIndex;doublevalor=Convert.ToDouble(textoValor.Text);Contaselecionada=this.contas[indice];try{selecionada.Saca(valor);textoSaldo.Text=Convert.ToString(selecionada.Saldo);MessageBox.Show("DinheiroLiberado");}catch(SaldoInsuficienteExceptionex){MessageBox.Show("Saldoinsuficiente");}catch(ArgumentExceptionex)

130 16.3TRATANDOMÚLTIPLASEXCEÇÕES

Page 138: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

{MessageBox.Show("Nãoépossívelsacarumvalornegativo");}}

Vejaqueotratamentodoserrosficoutotalmenteisoladodalógicadenegócios.Utilizandoexceções,podemosnospreocuparapenascoma lógicadenegóciodosistemae sódepoiscomo tratamentodeerros.Nãoexistemisturadecódigo!

1. Quaisdasopçõesaseguirrepresentaolançamentodeumanovaexceçãoemnossosistema?

csharpthrownewException();

csharpreturnException();

csharpreturnnewException();

csharpthrowException();

2. Analiseocódigoaseguireassinaleaalternativacorreta:

varconta=newConta();varcaixa=newCaixa();conta.Deposita(100.0);conta.Saca(500.0);caixa.Libera(500.0);

Sealinha4lançarumaexceção,alinha5nãoseráexecutada.

Aúltimalinhanãoseráexecutadamesmoseocódigonãolançarexceções.

Sealinha4lançarumaexceção,nenhumadaslinhasseráexecutada.

Todasaslinhassãoexecutadasmesmoquandoalgumadelaslançaumaexceção.

3. Ondedevemoscolocarum trechodecódigoquepode lançarumaexceçãoparaquandoqueremostratá-la?

Dentrodeumblocotry

Dentrodeumblococatch

Nãoprecisaestaremnenhumblocoemespecífico.

4. Ondedevemoscolocarocódigoquetrataumaexceção?

Dentrodeumblococatch

16.4EXERCÍCIOS

16.4EXERCÍCIOS 131

Page 139: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Dentrodeumblocotry

Nãoprecisaestaremnenhumblocoemespecífico.

5. Modifique o método Deposita da classe ContaPoupanca para que ele lance um

ArgumentExceptionquandooargumentopassadoparaométodofornegativo.Oseumétododeve

ficarparecidocomoseguinte:

publicclassContaPoupanca:Conta{//restodocódigodaContaPoupancapublicoverridevoidDeposita(doublevalor){if(valor<0.0){thrownewArgumentException();}//restodométodocontinuaigual}}

Depoisdefazeressamodificação,executeaaplicaçãoetentedepositarumvalornegativoemumacontapoupançaevejaoqueacontece.

6. Agorautilizeumtry/catchnaaçãodobotãoquerealizaumdepósito,botaoDeposito_Clickda

classeForm1,paratrataraexceçãoquepodeserlançadapeloDeposita.QuandooDeposita

lançarumaexceção,mostreumMessageBoxcomamensagem"ArgumentoInválido".

7. (Opcional)VamosagoracriarumanovaexceçãochamadaSaldoInsuficienteExceptionqueserá

lançadatodavezquetentarmossacarumvalorqueésuperioraosaldoatualdaconta.EssaclassedevesimplesmenteherdardaclasseExceptiondoC#:

publicclassSaldoInsuficienteException:Exception{}

Agora modifique o método Saca da classe ContaPoupanca para que ele jogue a

SaldoInsuficienteExceptiontodavezqueousuáriotentarsacarumvalormaiordoqueosaldo

daconta.

Modifique também o método botaoSaque_Click para que ele mostre a mensagem "Saldo

Insuficiente"casoométodoSacalanceaexceçãoSaldoInsuficienteException.

8. (Opcional)FaçaasmesmasmodificaçõesparaaContaCorrente.

9. (Opcional) Um outro bloco que existe é o finally . Pesquise sobre ele em

http://msdn.microsoft.com/pt-br/library/fk6t46tz(v=vs.71).aspxedigaquandoumcódigodentrodeumblocofinallyéexecutado.

Sempre

132 16.4EXERCÍCIOS

Page 140: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Sóseumaexceçãoforlançada.

Nunca

Sósenenhumaexceçãoforlançada

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

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

16.4EXERCÍCIOS 133

Page 141: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO17

Comocrescimentodosistema,passamosaterdiversasclassesnele.Porexemplo,asqueenvolvemomodelodenossosistemacomoasclassesligadasaconta:

publicabstractclassConta{//ImplementaçãodaclasseConta}

publicclassContaCorrente:Conta{//ImplementaçãodaclasseContaCorrente}

publicclassContaPoupanca:Conta{//ImplementaçãodaclasseContaPoupanca}

Asclassesvoltadasaorelacionamentocomocliente:

publicclassCliente{//ImplementaçãodaclasseCliente}

publicclassGerente{//ImplementaçãodaclasseGerente}

Asclassesligadasaosempréstimosfeitospelocliente:

publicclassCredito{//ImplementaçãodaclasseCredito}

publicclassCreditoImobiliario:Credito{//ImplementaçãodaclasseCreditoImobiliario}

Easclassesreferentesaosinvestimentos:

publicclassFundo{//ImplementaçãodaclasseFundo}

publicclassCDB

NAMESPACES

134 17NAMESPACES

Page 142: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

{//ImplementaçãodaclasseCDB}

Ograndeproblemaquesurgecomossistemasgrandeséaorganizaçãodetodasassuasclasses.Paraevitar que o sistema fique caótico, podemos agrupar as classes por características comuns e dar umnome para cada um desses grupos. Isto é, agruparíamos um conjunto de classes em um espaço emcomum e lhe daríamos um nome, como por exemplo Caelum.Banco.Investimentos. Esse espaço

definidoporumnomeéchamadodenamespace.

Segundo a convenção de nomes adotada pela Microsoft (http://msdn.microsoft.com/en-us/library/893ke618.aspx), os namespaces devem ter a forma:NomeDaEmpresa.NomeDoProjeto.ModuloDoSistema.

Nonossocaso,osnamespacesficariamdaseguinteforma:

namespaceCaelum.Banco.Usuarios{publicclassCliente{//ImplementaçãodaclasseCliente}}

namespaceCaelum.Banco.Usuarios{publicclassGerente{//ImplementaçãodaclasseGerente}}

namespaceCaelum.Banco.Investimentos{publicclassFundo{//ImplementaçãodaclasseFundo}}

namespaceCaelum.Banco.Investimentos{publicclassCDB{//ImplementaçãodaclasseCDB}}

Antes de realizar essa separação de nossas classes em namespaces, elas estavam no mesmonamespace:onamespacedonomedoprojeto.Assim,paradefiniroclientereferenteauminvestimentoprecisaríamosapenascriarumnovoatributonaclasseInvestimento:privateClientecliente.

Contudo,comousodosnamespaces,aclasseCliente não estámais nomesmonamespaceda

classeInvestimento. Para poder referenciar qualquer uma das quatro classes anteriores devemos

indicaroseunamespace:

17NAMESPACES 135

Page 143: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Caelum.Banco.Usuarios.Gerenteguilherme=newCaelum.Banco.Usuarios.Gerente();Caelum.Banco.Usuarios.Clientemauricio=newCaelum.Banco.Usuarios.Cliente();Caelum.Banco.Investimentos.Fundoacoes=newCaelum.Banco.Investimentos.Fundo();Caelum.Banco.Investimentos.CDBcdb=newCaelum.Banco.Investimentos.CDB();

Onomecompletodeuma classe agora envolve adicionar uma referência aonamespacedela.Porisso, deixamos de acessar Gerente diretamente e passamos a acessar

Caelum.Banco.Usuarios.Gerente.

Umexemplodecódigo já existentenaplataformaC#queusanamespacesenvolve imprimirumaúnicalinhanoconsoleusandoométodoWriteLinedeSystem.Console:

System.Console.WriteLine("Minhacontabancaria");

Notecomoousodenamespacesparaorganizarsuasclassesacabaimplicandoemmaiscódigonahora de utilizar as mesmas. Por isso, podemos criar atalhos ao dizer que usaremos as classes quepertencemaumnamespace.Porexemplo,podemoscitarqueusaremosonamespaceSysteme,apartir

de então, podemos escrever nosso código como se tudo o que está dentro do namespace System

estivessenomesmonamespaceemqueestamos:

usingSystem;

Console.WriteLine("Minhacontabancaria");

Podemostambémusarváriosnamespacesdentrodomesmoarquivo:

usingSystem;usingCaelum.Banco.Usuarios;

Console.WriteLine("MinhaContaBancaria");Clientecliente=newCliente();

Autilizaçãodapalavrachaveusingpermitenotificaraocompiladorqueusaremosclassesdaquele

namespace. Com isso, obtemos a vantagem da organização do código através de namespace econtinuamoscomumcódigoenxuto.

NoC#,podemoscriarumnamespacedentrodeoutronamespacejáexistente.Porexemplo:

namespaceCaelum.Banco{//dentrodonamespaceCaelum.Banco

//agorapodemoscriarumnamespaceaninhadonamespaceContas{

17.1 PARA SABER MAIS - DECLARAÇÃO DE NAMESPACEANINHADOS

136 17.1PARASABERMAIS-DECLARAÇÃODENAMESPACEANINHADOS

Page 144: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

//onomedessenamespaceéCaelum.Banco.Contas}}

OnamespaceContasdocódigoacimatambémpoderiaserdeclaradodaseguinteforma:

namespaceCaelum.Banco.Contas{//tambémdeclaraonamespaceCaelum.Banco.Contas}

ParaalinguagemC#,asduasdeclaraçõessãoequivalentes.

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

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Emaplicaçõesgrandes,podemosternamespacescomnomesmuitograndes,porexemplo:

namespaceCaelum.Banco.Produtos.Contas{publicabstractclassConta{//Implementação}}

Vimos que, no códigoC#, podemos utilizar ousing para não digitarmos o nome completo da

classetodavezqueelaforutilizada,masoqueaconteceriasetivéssemosoutraclassechamadaConta?

Porexemplo,obancotemumsistemadeautenticaçãoeaclassequeguardainformaçõessobreousuárioéchamadaConta:

namespaceCaelum.Banco.Seguranca{publicclassConta{//Implementação}}

Agoraéamelhorhoradeaprenderalgonovo

17.2PARASABERMAIS-ALIASPARANAMESPACES

17.2PARASABERMAIS-ALIASPARANAMESPACES 137

Page 145: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Claramente, as classes são diferentes pois possuemnamespaces diferentes,mas no código que asutiliza,nãopodemosimportarasduasclassespoisocompiladordoC#nãosaberáqualdasduasestamosutilizando.

usingCaelum.Banco.Produtos.Contas;usingCaelum.Banco.Seguranca;

namespaceBanco.Sistema{publicclassControleAutenticacao{//ContadousuárioouContadobanco?publicvoidAutentica(Contaconta){//implementação}}}

Nessa situação, precisamos escolher qual é o namespace que vamos importar. Se colocarmos umusingparaCaelum.Banco.Produtos.Contas,porexemplo,parautilizarmosaConta dousuário

precisamos do nome completo da classe,Caelum.Banco.Seguranca.Conta, um nome bem grande.

Nessa situação, podemos dar um apelido (alias) menor para um namespace do C# com a palavrausing:

usingCaelum.Banco.Produtos.Contas;usingSegurancaDoBanco=Caelum.Banco.Seguranca;

namespaceBanco.Sistema{publicclassControleAutenticacao{//ContaéadonamespaceCaelum.Banco.Produtos.Conta//parausarmosacontadousuáriofazemos://SegurancaDoBanco.ContapublicvoidAutentica(SegurancaDoBanco.ContacontaUsuario){//implementação}}}

Podemostambémdefinirumaliasparaumaclassedonamespace:

usingCaelum.Banco.Produtos.Contas;usingContaDoUsuario=Caelum.Banco.Seguranca.Conta;

namespaceBanco.Sistema{publicclassControleAutenticacao{//ContaéadonamespaceCaelum.Banco.Produtos.Conta//parausarmosacontadousuário,utilizamosContaDoUsuariopublicvoidAutentica(ContaDoUsuarioconta){//implementação}}

138 17.2PARASABERMAIS-ALIASPARANAMESPACES

Page 146: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

}

1. ComoinstanciaraclasseContaaseguir,queestádentrodeumnamespace?

namespaceCaelum.Banco{publicclassConta{//classeaqui}}

newConta();

newConta.Caelum.Banco();

newConta()inCaelum.Banco;

newCaelum.Banco.Conta();

2. Comoimportaraclasseaseguir,usandousing?

namespaceCaelum.Banco{publicabstractclassConta{//codigoaqui}}

usingCaelum;

usingCaelum.Banco;

usingCaelum.Banco.Conta;

3. FaçacomqueonamespacedascontasdaaplicaçãosejaBanco.Contas,porexemplo,paraaclasse

Conta,teríamos:

//arquivoConta.csnamespaceBanco.Contas{publicclassConta{//implementaçãodaclasseConta}}

Depoisde fazermosessamodificação,asclassesqueutilizamaconta terãoque importá-lacomousingdoC#.Noformulárioprincipaldaaplicação,classeForm1,porexemplo,teríamos:

usingBanco.Contas;

namespaceBanco{

17.3EXERCÍCIOS

17.3EXERCÍCIOS 139

Page 147: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

publicclassForm1:Form{//implementaçãodoformulário}}

Repare que o namespace é completamente separado da estrutura de pastas do projeto, ou seja,podemosorganizarosarquivosdoprojetodaformaquedesejarmos.

4. (Opcional) Mesmo que a estrutura de diretórios seja completamente separada do namespace, ésemprebomdefinirmosregrasparaaestruturadepastasdoprojeto.Umaestruturamuitoutilizadano .Net é colocar todas as classes de um determinado namespace dentro de um diretório com omesmonomedonamespace.Paraascontasdaaplicação,porexemplo,teríamosaseguinteestrutura:

Vamosmoverosarquivosdoprojetoparaseguirmosessaestrutura.DentrodoprojetoBanco,crie

umanovapastachamadaContasedentrodessapastacoloquetodasascontasdosistema.Vejaque

podemosmoverlivrementeosarquivossemquebrarocódigodaaplicação.

140 17.3EXERCÍCIOS

Page 148: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO18

Emcapítulosanterioresvimosautilizaçãodopolimorfismoparareferenciarmaisdeumtipodeclasse,comoéocasodasclassesContaCorrenteeContaPoupanca.Ambaspodemserreferenciadascomo

objetosdaclasseConta.

MasseráqueContaherdadealguém?Eseherdar,todasasoutrasclassestambémherdariam.Isto

é,umaclassequerepresentaabaseparatodososobjetosdosistema...umaclasseObject.Ocódigoa

seguiréomesmoqueadefiniçãoantigadeConta:

publicabstractclassConta:Object{//código}

ÉdesnecessáriodizermosqueContaherdadeObject.Écomoseoprópriocompiladorfizesseo

códigoanterioraodigitarmos:

publicabstractclassConta{//código}

Assim,podemosdizerque todaclasseemC#éumObject.UmavezqueConta éObject,

ContaCorrenteeContaPoupancapassamaserObjectindiretamente.

Vimos no primeiro capítulo sobre orientação a objetos que quando fazemos uma comparação deduasvariáveisdotipoConta,oquecomparamosnarealidadesãoasreferênciasqueestãoarmazenadas

nasvariáveis:

Contac1=newContaCorrente();c1.Numero=1;

Contac2=newContaCorrente();c2.Numero=1;

if(c1==c2){MessageBox.Show("iguais");}else

CLASSEOBJECT

18.1IMPLEMENTANDOACOMPARAÇÃODEOBJETOS

18CLASSEOBJECT 141

Page 149: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

{MessageBox.Show("diferentes");}

Nessecódigo,asduascontascriadasguardamexatamenteasmesmasinformações,porémcomoc1

ec2guardamreferências,quandofazemosc1==c2,estamoscomparandoareferênciadavariável

c1comareferênciadavariávelc2e,comoelasapontamparaobjetosdiferentes,ocódigomostraa

mensagem"diferentes".

Paracorrigiresseproblema,precisamoscompararosvaloresdaspropriedadesdacontaaoinvésdovalor das variáveis c1 e c2 . Por exemplo, no sistema que desenvolvemos, duas contas são

consideradasiguaisapenasquandoseusnúmerossãoiguais,entãoocódigodacomparaçãodeveriaficardaseguinteforma:

if(c1.Numero==c2.Numero){MessageBox.Show("iguais");}else{MessageBox.Show("diferentes");}

Portanto,em todosospontosdosistemaemqueprecisamoscomparardoisobjetosdo tipoconta,precisamosrepetiroifacima.Masoqueaconteceriaseprecisássemosmudararegradecomparação

deduascontas?Nessecasoteríamosquebuscartodasascomparaçõesdecontasdaaplicaçãoeatualizararegra,oquepodesermuitotrabalhoso.

Pararesolveroproblemadacomparaçãodeobjetos,aMicrosoftintroduziunaclasseObject um

métodoespecializadoemfazeracomparaçãodedoisobjetos,ométodoEquals.Comoemtodaherançaa classe filha ganha os comportamentos da classe pai, podemos utilizar o Equals para fazer a

comparaçãoentredoisobjetos:

if(c1.Equals(c2)){MessageBox.Show("iguais");}else{MessageBox.Show("diferentes");}

Porém,aoexecutarmosocódigo,aaplicaçãoaindamostraamensagem"diferentes".Issoocorre

porqueaimplementaçãopadrãodoEqualsquevemherdadadaclasseObjectfazacomparaçãodas

referências,ouseja,oifdocódigoanterioraindafazacomparaçãoc1==c2.

PodemosmudarocomportamentopadrãodométodoEqualsherdadodaclasseObjectutilizando

asobrescrita:

publicabstractclassConta

142 18.1IMPLEMENTANDOACOMPARAÇÃODEOBJETOS

Page 150: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

{//outraspropriedadesemétodos

//NessemétodoimplementamosaregradeigualdadeentreduascontaspublicoverrideboolEquals(Objectoutro){//Implementaçãodaigualdadedecontas.}}

ReparequeométodoEquals recebeumargumentodo tipoObject, entãopodemosutilizá-lo

paracompararumacontacomqualquervalordoC#.

Dentroda implementaçãodométodoEquals, queremos implementar a regra de igualdade entre

contas—duascontassãoiguaisseosseusnúmerosforemiguais:

publicabstractclassConta{//outraspropriedadesemétodos

//NessemétodoimplementamosaregradeigualdadeentreduascontaspublicoverrideboolEquals(Objectoutro){returnthis.Numero==outro.Numero;}}

Porém,reparequeavariáveloutroédotipoObject,quenãopossuiumapropriedadechamada

Numero,apenasaContapossuiessapropriedade.Então,antesdefazermosacomparaçãoprecisamos

converteravariáveloutroparaotipoContautilizandoocast:

publicabstractclassConta{//outraspropriedadesemétodos

//NessemétodoimplementamosaregradeigualdadeentreduascontaspublicoverrideboolEquals(Objectoutro){ContaoutraConta=(Conta)outro;returnthis.Numero==outraConta.Numero;}}

DepoisdecolocarmosessaimplementaçãodométodoEqualsnaclasseConta,podemostentar

executarnovamenteacomparaçãodecontas:

if(c1.Equals(c2)){MessageBox.Show("iguais");}else{MessageBox.Show("diferentes");}

Dessavez,oC#utilizaráa implementaçãodoEquals quecolocamosdentrodaclasseConta,

18.1IMPLEMENTANDOACOMPARAÇÃODEOBJETOS 143

Page 151: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

fazendoacomparaçãopelosnúmeros.Portanto,teremosamensagem"iguais".

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoC#eOrientaçãoaObjetos

ReparequeométodoEqualsrecebeotipoObject.Sendoassim,podemoscompararacontacom

qualqueroutroobjetodosistema,porexemplo,astring:

Contac=newContaCorrente();

if(c.Equals("Mensagem"))

EnaimplementaçãodoEquals,fazemosocastdoargumentopassadoparaotipoConta,poréma

string não é uma conta. Como o cast é inválido, o C# lança uma exceção do tipo

InvalidCastException . Para evitarmos essa exceção precisamos verificar que o argumento do

Equalsé realmentedo tipoContaantesde fazermosaoperaçãodecast.Para fazeresse trabalho,

podemosutilizarooperadorisdoC#:

publicoverrideboolEquals(Objectoutro){if(outroisConta){//outroédotipoConta,entãopodemosfazerocast}}

Nessecódigo,seavariáveloutroguardarumareferênciaparaumobjetoqueédotipoConta

(instânciadeContaouclassefilha),oisdevolvetrue,senãoeledevolvefalse.

SeoutronãoforumaConta,entãoométododeveriadevolverfalse, do contrário ele deve

fazerocastecompararosnúmeros.Assim,oEqualspodeserimplementadocomoseguintecódigo:

publicoverrideboolEquals(Objectoutro){//SenãotemosumobjetodotipoConta

VocêpodetambémfazerocursodatadessaapostilanaCaelum

18.2MELHORANDOAIMPLEMENTAÇÃODOEQUALSCOMOIS

144 18.2MELHORANDOAIMPLEMENTAÇÃODOEQUALSCOMOIS

Page 152: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

//Entãoométododevolvefalseif(!(outroisConta)){returnfalse}

ContaoutraConta=(Conta)outro;returnthis.Numero==outraConta.Numero;}

Nos capítulos anterioresmodificamos o formulário doBanco para utilizar um combo box para

fazeraorganizaçãodascontascadastradas.Paracolocarmosumnovoitemnocambobox,utilizamosométodoAddemsuapropriedadeItemspassandoqualéonovotextoquequeremosadicionar:

comboContas.Items.Add("NovoItem");

Com isso, o comboboxmostrará umnovo itemcomo texto"NovoItem".Naverdade, quando

utilizamosessemétodoAdd,podemospassarqualquerobjetocomoargumento:

Contac=newContaCorrente();c.Numero=1;

comboContas.Items.Add(c);

QuandopassamosumobjetoparaométodoAdd, oC#precisa transformar esse objeto emuma

stringqueseráexibidacomoitemdocombobox.Paraissoeleutilizamaisummétodoherdadoda

classeObjectchamadoToString.Aresponsabilidadedessemétodoétransformarumobjetoqualqueremumastring.

AimplementaçãopadrãodométodoToStringquevemherdadodaclasseObjectsimplesmente

devolveastringquerepresentaonomecompletodaclasse,ouseja,nomedonamespaceseguidodo

nomedaclasse(Banco.Contas.ContaCorrente,nocasodaContaCorrente).Mas,paramostrarmos

a conta no combo box, precisamos de uma implementação que descreva a conta que o usuário estáselecionando,entãovamosnovamenteutilizarasobrescritademétodosparamodificarocomportamentodoToString:

publicabstractclassConta{//outrosmétodosepropriedades

publicoverridestringToString(){

}}

DentrodessemétodoToString,precisamosdevolverumtextoquedescrevaacontaqueousuário

estáselecionando:

18.3INTEGRANDOOOBJECTCOMOCOMBOBOX

18.3INTEGRANDOOOBJECTCOMOCOMBOBOX 145

Page 153: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

publicabstractclassConta{//outrosmétodosepropriedades

publicClienteTitular{get;set;}

publicoverridestringToString(){return"titular:"+this.Titular.Nome;}}

AgoraquecolocamosaimplementaçãodoToStringnaclasseConta,aoexecutarmosnovamente

o código que adiciona um item no combo box, o C# mostrará o resultado do ToString que foi

implementado.

1. Assinaleaalternativacorreta

TodasasclassesemC#herdamdiretamenteouindiretamentedeObject

Objectéumaclasseabstrata

SóasclassesquenãoherdamdenenhumaclassesãoherdadasdeObject

Objectéumainterface

2. Analiseocódigoaseguiredigaqualseráasuasaída.

classCliente{publicstringNome{get;set;}publicstringRg{get;set;}publicCliente(stringnome){this.Nome=nome;}publicoverrideboolEquals(Objectobj){ClienteoutroCliente=(Cliente)obj;returnthis.Nome==outroCliente.Nome&&this.Rg==outroCliente.Rg;}}

Clienteguilherme=newCliente("GuilhermeSilveira");guilherme.Rg="12345678-9";

Clientemauricio=newCliente("MauricioAniche");mauricio.Rg="12345678-9";

if(guilherme.Equals(mauricio)){MessageBox.Show("Sãoomesmocliente");}else

18.4EXERCÍCIOS

146 18.4EXERCÍCIOS

Page 154: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

{MessageBox.Show("Nãosãoomesmocliente");}

Nãosãoomesmocliente

Ocódigonãocompila

Sãoomesmocliente

Nadaémostrado

Ocódigorodamasquebraaoexecutar

3. VamossobrescreverométodoToStringdaclasseContacomaseguinteimplementação:

publicabstractclassConta{//RestodaimplementaçãodaContapublicoverrideStringToString(){return"titular:"+this.Titular.Nome;}}

Agoraadicionaremosacontaaoinvésdeumastringcomoitemdocomboboxdentrodométodo

AdicionaContadoformulárioprincipaldaaplicação,classeForm1:

publicvoidAdicionaConta(Contaconta){this.contas[this.numeroDeContas]=conta;this.numeroDeContas++;comboContas.Items.Add(conta);}

Depoisdefazeressamodificação,testeaaplicaçãoevejaoToStringdacontaemaçãodentrodos

opçõesdocombobox.

4. Quandoadicionamosumobjetonocombobox,émais interessanterecuperardiretamenteoobjetoquefoiselecionadodoqueoíndicequefoiselecionado.

Para recuperar o objeto que está selecionado em um combo box, utilizamos a propriedadeSelectedItem.Essa propriedade devolve um Object que guarda a instância selecionada no

combobox.

Sabendodisso,podemosmodificaraaçãodobotãodedepósito,botaoDeposito_Clickdaclasse

Form1,parautilizaroSelectedItemdocomboContas,queconteráainstânciadacontaqueo

usuário selecionou na interface gráfica. Porém para podermos utilizar a conta selecionada,precisamosprimeiroconvertê-laparaumainstânciadeConta:

privatevoidbotaoDeposito_Click(objectsender,EventArgse){

18.4EXERCÍCIOS 147

Page 155: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Contaselecionada=(Conta)comboContas.SelectedItem;

//implementaalógicadedepósitoutilizandoaconta}

Implementeetesteessamodificaçãodentrodoseuprojeto.Façaomesmoparaobotãodesaque.

5. (Opcional)EmalgumassituaçõesnãoqueremosutilizaroToStringdopróprioobjetoparamontar

a listade itensdocombobox,nessassituações,podemosutilizarumapropriedadedoComboBox

chamadaDisplayMemberparaescolherqualéapropriedadedoobjetoquequeremosincluircomo

itemdocombo.Porexemplo,noseguintecódigo,ositemsdocomboboxserão1e2:

Contac=newContaCorrente(){Numero=1};Contac2=newContaCorrente(){Numero=2};comboContas.Items.Add(c);comboContas.Items.Add(c2);comboContas.DisplayMember="Numero";

QuandoutilizamosoDisplayMemberocomboboxtambémutilizaoToStringdomembropara

montaroitemqueseráexibidoparaousuário.

UtilizeoDisplayMemberparamostraroToStringdapropriedadeTitulardacontaaoinvésde

mostraroToStringdaprópriaConta.

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

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

148 18.4EXERCÍCIOS

Page 156: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO19

Sequisermosarmazenarmuitascontasnamemória,podemosfazerousodearrays,oqualjáestudamosnoscapítulosanteriores.Arraysnospossibilitamguardarumaquantidadedeelementosedepoisacessá-losdeformafácil.

Masoproblemaéquemanipularumarraynãoéfácil.Porexemplo,imagineumarraycom5contasguardadas. Se quisermos remover a posição 1, como fazemos? Pois, se apagarmos, precisaremosreordenartodonossoarray.Eparainserirumelementonomeiodoarray?Precisamos"abrirumburaco"noarray,empurrandoelementosprabaixo,paraaísimcolocaronovoelementonomeio.

Pararesolverosproblemasdoarray,podemostrabalharcomumaclassedoC#chamadaList.Para

utilizarmos uma lista dentro do código precisamos informar qual é o tipo de elemento que a listaarmazenará:

//criaumalistaquearmazenaotipoContaList<Conta>lista=newList<Conta>();

Damesma forma que criamos a lista de contas, também poderíamos criar uma lista de númerosinteirosoudequalqueroutrotipodoC#.EssalistadoC#armazenaseuselementosdentrodeumarray.

TRABALHANDOCOMLISTAS

19.1 FACILITANDO O TRABALHO COM COLEÇÕES ATRAVÉS DASLISTAS

19TRABALHANDOCOMLISTAS 149

Page 157: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

AgoraqueinstanciamosoList,podemosutilizarométodoAddparaarmazenarnovoselementos:

Contac1=newContaCorrente();Contac2=newContaPoupanca();Contac3=newContaCorrente();

//c1ficanaposição0lista.Add(c1);//c2na1lista.Add(c2);//ec3na2lista.Add(c3);

SequisermospegaressaConta,podemosacessá-lapelasuaposição(nocaso,0,igualnoarray):

Contaconta=lista[0];

Sequisermosremoverumadascontasdalista,podemosusarométodoRemoveouRemoveAt:

//Alistacomeçadaseguinteforma:[c1,c2,c3]//DepoisdoRemove,elaterminadaseguinteforma:[c1,c3]//Acontac1continuanaposição0ec3vaiparaaposição1lista.Remove(c2);//removepeloelemento

//Depoisdessachamada,c3ocupaaposição0:[c3]lista.RemoveAt(0);//removepeloíndice

Se quisermos saber quantos elementos existem em nosso List, podemos simplesmente ler a

propriedadeCount:

varc1=newContaCorrente();varc2=newContaInvestimento();

lista.Add(c1);lista.Add(c2);

intqtdDeElementos=lista.Count;

Tambémpodemosdescobrirseumelementoestádentrodeumalista:

Contac1=newContaCorrente();Contac2=newContaPoupanca();

lista.Add(c1);

booltemC1=lista.Contains(c1);//truebooltemC2=lista.Contains(c2);//false

UmoutrorecursoqueaclasseListnosforneceéaiteraçãoemcadaumdosseuselementos:

Contac1=newContaCorrente();Contac2=newContaPoupanca();

lista.Add(c1);lista.Add(c2);

foreach(Contacinlista){MessageBox.Show(c.ToString());

150 19.1FACILITANDOOTRABALHOCOMCOLEÇÕESATRAVÉSDASLISTAS

Page 158: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

}

VejacomolidarcomcoleçõesdeelementosficoumuitomaisfácilcomaclasseList!

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

CasadoCódigo,LivrosdeTecnologia.

1. ComodescobrimosaquantidadedeelementosarmazenadoemumList?

varlista=newList<Conta>();lista.Add(...);lista.Add(...);lista.Add(...);

lista.Size

lista.Count()

lista.Size()

lista.Count

lista.GetTotal()

2. Qualométodoqueremoveumelementodalistapelasuaposição?

lista.Remove(posicao);

lista.RemoveAt(posicao);

lista.DeleteFrom(posicao);

lista.DeleteAt(posicao);

Seuslivrosdetecnologiaparecemdoséculopassado?

19.2EXERCÍCIOS

19.2EXERCÍCIOS 151

Page 159: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

3. AclasseListimplementaumainterfacemaisgenéricadelistas.Qualé?

Você pode consultar a documentação da classe no próprio site da Microsoft:http://msdn.microsoft.com/pt-br/library/6sh2ey19.aspx

IList

Nenhuma

List

GenericList

4. Vamosmodificarocódigodoprojetodobancoparautilizarlistasaoinvésdearraysparaguardarascontascadastradas.

Inicialmentesubstituaadeclaraçãodoatributoqueguardaareferênciaparaoarraydecontaspeladeclaraçãodeumalistadecontas.ApaguetambémadeclaraçãodoatributonumeroDeContas:

//Essadeclaraçãoseráutilizadanolugardoarray//decontasprivateList<Conta>contas;

ModifiqueométodoForm1_LoadparaqueeleinstancieumList<Conta>aoinvésdeumarrayde

contas:

privatevoidForm1_Load(objectsender,EventArgse){this.contas=newList<Conta>();

//orestodométodocontinuaigual}

Porfim,modificaremosométodoAdicionaContadoformulárioprincipal:

publicvoidAdicionaConta(Contaconta){this.contas.Add(conta);comboContas.Items.Add(conta);}

Depoisdessasmodificações,testeaaplicação.

152 19.2EXERCÍCIOS

Page 160: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO20

Agora estamos interessados em melhorar o cadastro de contas que implementamos nos capítulosanteriores. O banco não quer aceitar o cadastro de contas cujo titular seja devedor, então dentro dosistemaprecisamosguardarumalistacomnomesdosdevedores:

List<string>devedores=newList<string>();

devedores.Add("victor");devedores.Add("osni");

Agoranocadastroprecisamosverificarseonomequefoidigitadonoformulárioestádentrodessalista.PodemosfazerissoutilizandoométodoContainsdaclasseList:

stringtitular=//lêocampotitulardocadastroboolehDevedor=devedores.Contains(titular);

MasaimplementaçãodoContainsdalistaprecisapercorrertodososnomescadastradosparasó

entãodevolverseoelementoestáounãodentrodalista.Dessaforma,dependendodotamanhodalista,essabuscapodeficardemorada.

Como vimos, as listas não são muito otimizadas para as operações de buscas, pois além depermitiremarepetiçãodeelementos(queprejudicaodesempenhodabusca),precisampercorrertodososelementosparaimplementaremaoperaçãoContains.

Quandoprecisamosqueaoperaçãodebuscasejarápida,utilizamososconjuntosdoC#aoinvésdaslistas.Conjuntossãoestruturasnasquaispodemosfazerbuscasrápidasequenãopermitemrepetiçãodeelementos.

UmdostiposdeconjuntosdisponíveisnoC#éaclasseHashSet.Parabuscardemaneirarápida,o

HashSet"categoriza"osseuselementos,deformaaencontrá-losrapidamente.Porexemplo,imagine

você em um supermercado. Se você quer comprar sorvete, você não olha todos os itens dosupermercado,massimvaidiretoparaaseçãodecongelados.Lá,vocêprocuraoseusorvetefavorito.Vejaquevocêolhoumuitomenoselementos,poisfoidiretoparaacategoriadele.OHashSet faz a

mesmacoisa.Eledá"categorias"paracadaumdoselementos,equandobuscaporeles,vaidiretoparaacategoria.

LIDANDOCOMCONJUNTOS

20.1OTIMIZANDOABUSCAATRAVÉSDECONJUNTOS

20LIDANDOCOMCONJUNTOS 153

Page 161: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

AcategoriaédadaapartirdométodoGetHashCode()quevemherdadodaclasseObjectdoC#.

Essemétododevolveumnúmerointeiroquerepresentaqualéacategoriadoobjeto.

CUIDADOSAOSOBRESCREVEROGETHASHCODE

Quando sobrescrevemos o método Equals de uma classe é uma boa prática também

sobrescrevermos o método GetHashCode . Além disso, para que o HashSet funcione

corretamente,aimplementaçãodoGetHashCodedeveobedeceràseguinteregra:

Se tivermos dois objetos, objeto1 e objeto2 , com objeto1.Equals(objeto2)

devolvendoovalortrue,entãoosmétodosGetHashCodedoobjeto1edoobjeto2devem

devolveromesmovalor.Ouseja,objetosiguaisdevemserdamesmacategoria.

Umdetalheinteressantedosconjuntoséquevocêpodeadicionar,removereatémesmoverificarseum elemento está lá.Mas diferentemente da lista, você não consegue pegar um elemento randômiconela.Porexemplo,conjunto[10]nãofunciona!Eissofazsentido:nãoexisteordememumconjunto.

HashSet<string>devedores=newHashSet<string>();//PodemosadicionarelementosnoconjuntoutilizandoométodoAdddevedores.Add("victor");devedores.Add("osni");

//Parasabermosonúmerodeelementosadicionados,utilizamosapropriedade//Countdoconjunto.Nesseexemploelementosguardaráovalor2intelementos=devedores.Count;

//Oconjuntonãoguardaelementosrepetidos,entãosetentarmos//adicionarnovamenteastring"victor",onúmerodeelementos//continuasendo2devedores.Add("victor");

//Paraperguntarmosseoconjuntopossuiumdeterminadoelemento,//utilizamosométodoContains

154 20.1OTIMIZANDOABUSCAATRAVÉSDECONJUNTOS

Page 162: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

boolcontem=devedores.Contains("osni");

//Nãopodemospegarumelementopelasuaposição,poisoselementosdo//conjuntonãopossuemumaordenaçãobemdeterminada.Ocódigoabaixo//geraumerrodecompilação:devedores[0];

ParaiterarmosnoselementosdeumHashSet,podemosutilizarnovamenteocomandoforeach:

foreach(stringdevedorindevedores){MessageBox.Show(devedor);}

QuandoexecutamosoforeachemumHashSet, aordememqueos elementos são iterados é

indefinida.

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

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Emmuitasaplicaçõesalémdabuscarápida,tambémprecisamosmanteraordenaçãodoselementosde um conjunto. Nesse tipo de aplicação, podemos utilizar uma nova classe do C# chamadaSortedSet.

OSortedSet funciona de forma similar ao HashSet, utilizamos o Add para adicionar um

elemento, o Remove para remover itens, o Count para perguntar quantos elementos estão

armazenadoseContainsparaverificarseumdeterminadoelementoestánoconjunto.Adiferençaé

quenoHashSetoselementossãoespalhadosemcategoriaseporissonãosabemosqualéaordemda

iteração,jáoSortedSetguardaoselementosnaordemcrescente.Entãonoexemplodoconjuntode

devedores,teríamosumconjuntoemqueoselementosestãoemordemalfabética:

SortedSet<string>devedores=newSortedSet<string>();

devedores.Add("Hugo");devedores.Add("Ettore");devedores.Add("Osni");

Agoraéamelhorhoradeaprenderalgonovo

20.2CONJUNTOSORDENADOSCOMOSORTEDSET

20.2CONJUNTOSORDENADOSCOMOSORTEDSET 155

Page 163: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

devedores.Add("Alberto");devedores.Add("Victor");

//Esseforeachvaimostrarosnomesnaseguinteordem://Alberto,Ettore,Hugo,OsnieporfimVictorforeach(stringnomeindevedores){MessageBox.Show(nome);}

VimosquetemosduasclassesquerepresentamconjuntosnoC#,oHashSeteoSortedSet,em

ambasasclasses,quandoqueremosarmazenarumelementoutilizamosométodoAdd,pararemovero

Remove,parabuscaroContainseparasaberonúmerodeelementosoCount, por essemotivo,

existe uma interface que declara todos os comportamentos comuns aos conjunto que é a interfaceISet.

Vimosqueaslistaseosconjuntossãoduasestruturasqueexpõemmuitosmétodosemcomum,masquetambémpossuemdiversasdiferenças:

Naslistasoselementossãoarmazenadosnaordemdeinserçãoenquantocadaconjuntoarmazenaoselementosnaordemquedesejarparaotimizarotempodebusca;Listasaceitamrepetiçõesenquantoosconjuntosnão;Podemosacessarelementosdeumalistaatravésdeseuíndice,umaoperaçãoquenãofazsentidonoconjunto..

Comolistaseconjuntospossuemmuitasoperaçõesemcomum,tantoaslistasquantoosconjuntosimplementamumaoutrainterfacedoC#chamadaICollection:

20.3AINTERFACEDETODOSOSCONJUNTOS

20.4COMPARAÇÃOENTRELISTASECONJUNTOS

156 20.3AINTERFACEDETODOSOSCONJUNTOS

Page 164: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Além disso, aprendemos que podemos utilizar o foreach com qualquer coleção do C#. Isso

aconteceporqueoforeachaceitaqualquerclassequeimplementeainterfaceIEnumerable, que é

umasuperinterface(interfacepai)daICollection:

20.4COMPARAÇÃOENTRELISTASECONJUNTOS 157

Page 165: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

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

CasadoCódigo,ebookcompreçodeebook.

1. Qualasaídadoprogramaaseguir?

varconjunto=newHashSet<Conta>();varc1=newContaCorrente();conjunto.Add(c1);conjunto.Add(c1);MessageBox.Show(conjunto.Count.ToString());

0

1

UmSetnãopossuipropriedadeCount

2

2. Comoeliminartodososelementosdeumconjunto?

varconjunto=newHashSet<Conta>();conjunto.????();

.Clear()

.DeleteAll()

.Reset()

.Empty()

3. No Banco, não podemos criar novas contas para clientes que são devedores, então na tela decadastrodenovaconta,antesdecriarmosanovacontaqueseráadicionadanaaplicaçãoprecisamosverificarseelaestáemumalistadedevedoresquecontém30000nomes.

EditoraCasadoCódigocomlivrosdeumaformadiferente

20.5EXERCÍCIOS

158 20.4COMPARAÇÃOENTRELISTASECONJUNTOS

Page 166: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Adicionenoprojetoumanovapasta chamadaBusca e dentrodessapasta crie umanova classe

chamadaGeradorDeDevedorescomoseguintecódigo:

namespaceBanco.Busca{publicclassGeradorDeDevedores{publicList<string>GeraList(){List<string>nomes=newList<string>();for(inti=0;i<30000;i++){nomes.Add("devedor"+i);}returnnomes;}}}

Essaéaclassequeseráresponsávelporgeraralistadedevedoresqueutilizaremosnaaplicação.

No construtor do formulário de cadastro, classe FormCadastroConta , vamos utilizar o

GeradorDeDevedoresparainicializaralistadedevedores:

publicpartialclassFormCadastroConta:Form{privateICollection<string>devedores;

privateForm1formPrincipal;

publicFormCadastroConta(Form1formPrincipal){this.formPrincipal=formPrincipal;InitializeComponent();

GeradorDeDevedoresgerador=newGeradorDeDevedores();this.devedores=gerador.GeraList();}

//Restodaclassecontinuaigual}

Agoranaaçãodobotãodecadastro,antesdecriarmosaconta,precisamosverificarseotitulardessanovacontaédevedor:

privatevoidbotaoCadastro_Click(objectsender,EventArgse){stringtitular=textoTitular.Text;boolehDevedor=this.devedores.Contains(titular);if(!ehDevedor){//fazalógicaparacriaraconta}else{MessageBox.Show("devedor");}}

20.4COMPARAÇÃOENTRELISTASECONJUNTOS 159

Page 167: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

4. Paraverificarmosadiferençaentreo tempodebuscade listaseconjuntos,vamos repetirabusca30000vezesdentrodeumloop:

privatevoidbotaoCadastro_Click(objectsender,EventArgse){stringtitular=this.textoTitular.Text;boolehDevedor=false;for(inti=0;i<30000;i++){ehDevedor=this.devedores.Contains(titular);}if(!ehDevedor){//fazalógicaparacriaraconta}else{MessageBox.Show("devedor");}}

Enquantoocódigoestáexecutando,tentemoverajanela.Oqueaconteceu?

5. AgoramodifiqueoGeradorDeDevedoresparaqueeleutilizeumHashSetaoinvésdeumList:

publicHashSet<string>GeraList(){HashSet<string>nomes=newHashSet<string>();for(inti=0;i<30000;i++){nomes.Add("devedor"+i);}returnnomes;}

Repare que, para utilizarmos o HashSet, precisamos mudar os tipos do objeto instanciado, da

variável e do retorno no método. O que podemos fazer para evitar tantas mudanças quandoqueremostrocaraimplementaçãodecoleçãoqueusamos?

6. Testenovamenteocadastrodacontaevejaquedessavezabuscaémaisrápida.7. ExperimentetambémoutrascoleçõesnométodoGeraList.

Noprojetodobanco,temosdiversascontascadastradaseagoraqueremoscriarumanovabuscadecontapornomedotitular.Paraimplementaressabusca,podemositerarnalistadecontasecompararonomedotitulardecadaumadessascontas:

IList<Conta>contas=//pegaascontascadastradasstringtitularDaBusca="victor";Contaresultado=null;foreach(Contacontaincontas){if(conta.Titular.Nome.Equals(titularDaBusca))

20.6BUSCASRÁPIDASUTILIZANDODICIONÁRIOS

160 20.6BUSCASRÁPIDASUTILIZANDODICIONÁRIOS

Page 168: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

{resultado=conta;break;}}

Agora repare que em todo ponto do código em que precisamos buscar uma conta pelo nome dotitular, precisamos repetir esse bloco de código, além disso, essa busca passa por todas as contascadastradasnosistema,oquepodedemorarbastante.Pararesolveresseproblemadeformaeficiente,oC#nosofereceosDicionários(Dictionary).

ODictionaryéumaclassequeconsegueassociarumachaveaumvalor.Utilizandoodicionário,

podemos,porexemplo,associaronomedotitularcomumacontadosistema.Quandovamosconstruirumdicionáriodentrodocódigo,precisamosinformarqualéotipodachaveequalseráotipodovalorassociadoa essa chave,para implementarmosabuscade contas, precisaríamosdeumdicionárioqueassociaumachavedotipostringcomumaConta.

Dictionary<String,Conta>dicionario=newDictionary<String,Conta>();

Agoraparacolocarmosumvalornodicionário,utilizamosométodoAdd:

Dictionary<String,Conta>dicionario=newDictionary<String,Conta>();Contaconta=//inicializaaconta

//vamosadicionaracontanodicionário//associaonomedotitularcomaconta.dicionario.Add(conta.Titular.Nome,conta);

Depoisqueinicializamosodicionário,podemosrealizarbuscasdevaloresutilizandoaschavesqueforamcadastradas.Vamos,porexemplo,buscaracontadeumtitularchamado"Victor":

Contabusca=dicionario["Victor"];

Veja que utilizando dicionários a busca por nomes ficou muito mais simples do que a buscautilizandooforeach,alémdisso,asbuscascomdicionáriossãotãorápidasquantobuscasutilizando

conjuntos,ouseja,muitomaiseficientesdoqueonossoforeachinicial.

Alémde fazermosbuscas rápidas, podemos também iterarnos elementosque estão armazenados,para isso tambémutilizamosoforeach doC#. Porémqual será o tipo que utilizaremos dentro do

foreach?

Ao iterarmos em um dicionário, o tipo utilizado dentro do foreach é um tipo que consegue

guardarumparde chaveassociadoaumvalordodicionário (KeyValuePair).Logo, no códigodo

foreachotiposeriaKeyValuePair<tipodachave,tipodovalor>:

Dictionary<string,Conta>dicionario=newDictionary<string,Conta>();

20.7ITERANDONODICIONÁRIO

20.7ITERANDONODICIONÁRIO 161

Page 169: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

//preencheodicionário

foreach(KeyValuePair<string,Conta>parindicionario){//podemosacessarachaveatualdodicionáriostringchave=par.Key;

//epodemospegarovalorassociadoàchaveContavalor=par.Value;}

Assim como no HashSet, quando iteramos em um dicionário, seus elementos não estão em

nenhuma ordem em particular, logo não podemos depender da ordem dos elementos do dicionário.Quando estamos trabalhando com um algoritmo que depende da ordem dos elementos, precisamosutilizarumoutro tipodedicionáriochamadoSortedDictionary.OusodoSortedDictionary é

igual ao do Dictionary, porém seus elementos estão sempre na ordem crescente das chaves do

dicionário.

No C#, temos uma interface implementada por todos os tipos os tipos de dicionários, aIDictionary, além disso, os dicionários também implementam a interface ICollection do C#,

porémelessãocoleçõesdeKeyValuePair.Podemosversuahierarquianaimagemaseguir:

AhierarquiadascoleçõesdoC#ficadaseguinteforma:

162 20.7ITERANDONODICIONÁRIO

Page 170: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

1. Em nosso banco, precisamos implementar uma nova busca de contas por nome do titular. Paraimplementarmosessabusca,utilizaremososdicionáriosdoC#.

Noformulárioprincipaldaaplicação,coloqueumnovocampodetextoquereceberáqualéonomedotitulardabusca.ChameessecampodetextoBuscaTitular.Alémdessenovocampodetexto,

coloquetambémumnovobotãoquequandoclicadoexecutaráabuscapornome,chameessebotãodebotaoBusca.Oseuformuláriodeveficarparecidocomoquesegue:

JáconheceoscursosonlineAlura?

20.8EXERCÍCIOS

20.5EXERCÍCIOS 163

Page 171: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Paraimplementarmosessabuscapornomedetitular,oformulárioprecisadeumnovoatributodotipoDictionary.Quaisdevemserostiposdachaveedovalordodicionário?Agoraquetemoso

dicionário,todavezquecriamosumanovaconta,precisamosadicioná-laàlistadecontas,nocomboboxenodicionáriodecontas,mascomooformuláriopossuiummétodoespecializadoemadicionarnovascontas,oAdicionaConta,sóprecisamosmodificaraimplementaçãodessemétodo.Repare

quecomoocódigoestáencapsulado,precisamosapenasmodificaressemétodoquetudofuncionaráautomaticamente.

publicpartialclassForm1:Form{privateDictionary<string,Conta>dicionario;

privatevoidForm1_Load(objectsender,EventArgse){this.dicionario=newDictionary<string,Conta>();

//restodométodo}

publicvoidAdicionaConta(Contaconta){contas.Add(conta);comboContas.Items.Add(conta);

//agorasóprecisamosatualizarodicionáriothis.dicionario.Add(conta.Titular.Nome,conta);}

//Restodocódigodaclasse}

Agora que já preparamos o dicionário, precisamos apenas utilizá-lo para implementar a ação dobotãodebuscaportitular.

164 20.8EXERCÍCIOS

Page 172: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

privatevoidbotaoBusca_Click(objectsender,EventArgse){//Precisamosprimeirobuscarqualéonomedotitularquefoidigitado//nocampodetextostringnomeTitular=textoBuscaTitular.Text;

//Agoravamosusarodicionárioparafazerabusca.//ReparecomoocódigodebuscaficasimplesContaconta=dicionario[nomeTitular];

//EagorasóprecisamosmostraracontaquefoiencontradanabuscatextoTitular.Text=conta.Titular.Nome;textoNumero.Text=Convert.ToString(conta.Numero);textoSaldo.Text=Convert.ToString(conta.Saldo);}

2. (Opcional)Nocódigodoexercíciopassado,quandoencontramosumacontadentrododicionário,estamos apenas atualizando as informações que são mostradas nos campos textoNumero ,

textoSaldoetextoTitular,porémquandotentamosfazerumaoperação,sempreutilizamoso

itemqueestáselecionadoatualmentenocomboContas.Precisamosutilizaracontadevolvidapelo

dicionárioparaatualizarovalorselecionadodocomboContas,parafazerisso,precisamosapenas

atribuiracontaquequeremosselecionarnapropriedadeSelectedIndexdocomboContas:

privatevoidbotaoBusca_Click(objectsender,EventArgse){stringnomeTitular=textoBuscaTitular.Text;Contaconta=dicionario[nomeTitular];

//AgoravamosatualizaroitemselecionadodocomboContas:comboContas.SelectedItem=conta;}

QuandoescrevemosnapropriedadeSelectedItem,oWindowsFormsautomaticamentechamaa

açãodemudançade itemselecionadodocombobox(ocomboContas_SelectedIndexChanged),

logonãoprecisamosnospreocuparematualizaroscamposdetextonocódigodabuscapornomedotitular.

3. O que acontece quando tentamos buscar um nome de titular que não existe? Tente modificar ocódigodoformulárioparacorrigiroproblema.

20.8EXERCÍCIOS 165

Page 173: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO21

Nossobancoarmazenaumalistadecontas.Essascontaspossuemosmaisvariadoscorrentistas,saldosetipos.Muitasvezes,precisamosfiltrá-lasdealgumaforma.Porexemplo,sequisermospegar todasascontascomsaldomaiorque2000reais,fazemos:

varlista=newList<Conta>();

//inserimosalgumascontaslista.Add(...);

//crialistaqueusaremosparaguardaroselementosfiltradosvarfiltrados=newList<Conta>();foreach(varc:lista){if(c.Saldo>2000){filtrados.Add(c);}}

//agoraavariavel"filtrados"temascontasquequeremos!

Secomplicarmosaindamaisofiltro(porexemplo,contascomsaldomaiorque2000emenorque5000,comdatadeaberturaentreosanos2010e2012,...),nossocódigoficarátambémmaiscomplexo,alémdisso,sequiséssemosaplicarumfiltroemumalistacomoutrotipodeobjeto,teríamosquerepetirnovamenteocódigodoforeachemdiversospontosdaaplicação.

Parafiltrarumalista,seriamuitomaisinteressantequeaprópriacoleçãotivessealgummétodoquerecebesseacondiçãoquequeremosaplicarnessefiltroejáimplementassealógicadoforeach,algo

como:

List<Conta>contas=//inicializaalista

varfiltradas=contas.Filtra(condição);

Mascomopassaracondiçãoparaessefiltro?Teríamosqueenviarumblocodecódigoqueaceitaourejeitaosvaloresdacoleção.Parapassarumblocodecódigoquepodeserutilizadoporummétodo,oC# introduziu as funções anônimas ou lambdas. As funções anônimas funcionam como métodosestáticosdalinguagemcomumadeclaraçãosimplificada.Paradeclararumafunçãoanônimaquerecebe

LINQELAMBDA

21.1FILTROSUTILIZANDOOLINQ

166 21LINQELAMBDA

Page 174: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

umargumentodotipoContautilizamososeguintecódigo:

(Contac)=>{//implementaçãodafunçãoanônima}

Dentrodoblocodeimplementaçãodafunçãoanônima,colocaremosaimplementaçãodacondição:

(Contac)=>{returnc.Saldo>2000;}

EagoraessafunçãopodeserpassadaparadentrodométodoFiltra:

contas.Filtra((Contac)=>{returnc.Saldo>2000;});

NoC#temosexatamenteaimplementaçãodessaideia,masométodosechamaWhereaoinvésde

Filtra.Então,parabuscarmostodasascontasquetêmumsaldomaiordoque2000,utilizaríamoso

seguintecódigo:

List<Conta>contas=//inicializaalistavarfiltradas=contas.Where((Contac)=>{returnc.Saldo>2000;});

Agoraquetemosalistadecontasfiltradas,podemos,porexemplo,iterarnessalista:

foreach(Contacontainfiltradas){MessageBox.Show(conta.Titular.Nome);}

AbibliotecadoC#quedefineométodoWhereéchamadaLINQ,aLanguageIntegratedQuery.

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoC#eOrientaçãoaObjetos

Veja que, no código do lambda que passamos como argumento para oWhere, definimosqueo

argumentodafunçãoanônimaédotipoContaporquealistadavariávelcontasédotipoConta.

Reparequeotipodoargumentodolambdanaverdadeéredundanteeporisso,desnecessário:

varfiltradas=contas.Where(c=>{returnc.Saldo>2000;});

VocêpodetambémfazerocursodatadessaapostilanaCaelum

21.2SIMPLIFICANDOADECLARAÇÃODOLAMBDA

21.2SIMPLIFICANDOADECLARAÇÃODOLAMBDA 167

Page 175: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Alémdisso, quandodeclaramosuma função anônimaque temapenasuma linhaquedevolveumvalor,podemosremoverinclusiveaschaveseoreturndadeclaraçãodolambda:

varfiltradas=contas.Where(c=>c.Saldo>2000);

Vejaqueessecódigofinalémuitomaissimplesdoqueadeclaraçãoinicialqueutilizamosparaafunçãoanônima.

Agoraimaginequequeremossaberqualéasomadosaldodetodasascontasqueestãocadastradasdentro da aplicação. Para resolver esse problema, teríamos que fazer um código parecido com oseguinte:

List<Conta>contas=//inicializaalistadecontasdoubletotal=0.0;

foreach(Contacincontas){total+=c.Saldo;}

Porém esse tipo de código também acaba ficando repetitivo.Quando queremos fazer a soma doselementosdeumalista,podemosutilizarométodoSumdoLINQ,passandoumlambdaquefalaqualéapropriedadedacontaquequeremossomar:

doubletotal=contas.Sum(c=>c.Saldo);

Com essa linha de código conseguimos omesmo efeito do foreach anterior. Além do Sum,

tambémpodemosutilizar ométodoAverage para calcular amédia dosvalores,Count para contar onúmerodevaloresqueobedecemalgumcritério,MinparacalcularomenorvaloreMaxparacalcularomaiorvalor:

List<Conta>contas=//inicializaalista

//somadossaldosdetodasascontasdoublesaldoTotal=contas.Sum(c=>c.Saldo);

//mediadosaldodascontasdoublemediaDosSaldos=contas.Average(c=>c.Saldo);

//númerodecontasquepossuemNumeromenordoque1000intnumero=contas.Count(c=>c.Numero<1000);

intmenorNumero=contas.Min(c=>c.Numero);

doublemaiorSaldo=contas.Max(c=>c.Saldo);

Quandoutilizamosessesmétodosdeagregaçãoemumalistacomtiposprimitivos,olambdaéumargumentoopcional.Porexemplo,setivéssemosumalistadedouble,poderíamosutilizaroseguinte

códigoparacalcularamédiadosnúmeros:

21.3OUTROSMÉTODOSDOLINQ

168 21.3OUTROSMÉTODOSDOLINQ

Page 176: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

List<double>saldos=//inicializaalista

doublemedia=saldos.Average();

OLINQ, alémde trabalhar com listas, tambémpode serutilizados comoutros tiposde coleções,podemosutilizaroLINQcomqualquerobjetoqueimplementeainterfaceIEnumerable,ouseja,ele

podeserutilizadocomqualquerobjetoquepossaserpassadoparaa instruçãoforeach. Isso inclui

todosostiposdecoleções(Listas,conjuntosedicionários)earrays.

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

CasadoCódigo,LivrosdeTecnologia.

VimosqueutilizandooLINQpodemosfazerfiltroseagregaçõesdeumaformafácilemqualquercoleçãodoC#,porémquandoprecisamosfazerumfiltrocomplexo,olambdapodeficarcomumcódigocomplexo.Eporisso,aMicrosoftdecidiufacilitaraindamaisousodoLINQ.

Para implementarmos um filtro, em vez de utilizarmos ométodoWhere, podemos utilizar uma

sintaxequefoibaseadanalinguagemdebuscaembancodedados,aSQL.Paracomeçarmosumfiltroutilizandoessanovasintaxe,precisamoscomeçarofiltrocomapalavrafromcriandoumavariávelqueseráutilizadaparanavegarnalista:

varfiltradas=fromcincontas

Agora para colocarmos uma condição nesse filtro, utilizamos a palavrawhere passando qual é acondiçãoaqueacontadeveobedecerparaaparecercomoresultadodessefiltro:

varfiltradas=fromcincontaswherec.Numero<2000

21.4UTILIZANDOOLINQCOMOUTROSTIPOS

Seuslivrosdetecnologiaparecemdoséculopassado?

21.5 MELHORANDO AS BUSCAS UTILIZANDO A SINTAXE DEQUERIES

21.4UTILIZANDOOLINQCOMOUTROSTIPOS 169

Page 177: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Eporfim,precisamosapenasinformaroqueseráselecionadoutilizandooselect:

varfiltradas=fromcincontaswherec.Numero<2000selectc;

Com esse código, estamos definindo um filtro que devolverá apenas as contas que têm númeromenordoque2000.

Quandoocompiladorda linguagemC#encontrao filtroquedefinimos, essecódigoé convertidoparaumachamadaparaométodoWherequevimosanteriormente.Essanovasintaxeéapenasumjeito

deesconderacomplexidadedolambda.

Muitasvezes,quandoestamosusandooLINQ,ofiltronãoprecisaretornartodasasinformaçõesdosobjetosdalistaqueestásendoprocessada.Podemosestarinteressadosembuscarapenasonúmerodascontasqueobedecemoscritériosdabusca,paraissoprecisamosapenasmudaroselectdoLINQ.

List<Conta>contas=//inicializaalista

varresultado=fromcincontaswhere<condiçãodabusca>selectc.Numero;

Oresultadodessabuscaseráumacoleçãodenúmerosinteiros.

Mas e quando queremos devolver mais atributos da conta? Como no LINQ podemos apenasdevolverumobjetocomoresultadodaquery,teríamosquecriarumaclassequecontémosatributosqueserãodevolvidospelaquery,masmuitasvezesnósfazemosabuscaeutilizamosoresultadodentrodeum único ponto da aplicação (dentro de ummétodo, por exemplo).Nesses casos, podemos deixar ocompiladordoC#cuidardacriaçãodesseobjetoanônimo:

varresultado=fromcincontaswhere<condiçãodabusca>selectnew{c.Numero,c.Titular};

Nessecódigo,ocompiladordoC#criaumnovotipoqueseráutilizadoparaguardaroresultadodabusca.Esse tipo não possui umnomedentro do código e por isso o objeto devolvido é chamado deObjetoAnônimo.QuandoutilizamosoobjetoanônimonoLINQ,somosforçadosautilizarainferênciadetipos(palavravar).

No exemplo, o objeto anônimo devolvido pelo compilador possui as propriedades Titular e

Numero,portantopodemosutilizá-lasdentrodeumforeach:

foreach(varcinfiltradas){//aquidentropodemosapenasusaroTitulareoNumero,//setentarmosacessaroSaldoteremosumerrodecompilaçãoMessageBox.Show(c.Titular.Nome+""+c.Numero);}

21.6PARASABERMAIS—PROJEÇÕESEOBJETOSANÔNIMOS

170 21.6PARASABERMAIS—PROJEÇÕESEOBJETOSANÔNIMOS

Page 178: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

1. CrieumnovoformuláriochamadoFormRelatorios.Utilizá-lo-emosparamostraroresultadode

queriesfeitasutilizandooLINQ.

No editor gráfico desse novo formulário, abra a janela Toolbox e adicione o componente

ListBox,chame-odelistaResultado.UtilizaremosesseListBoxparamostrarosresultados

devolvidospeloLINQ.

Agora vamos criar nosso primeiro relatório, o de busca de contas com saldomaior do que 5000,atravésdeumnovobotãodentrodajanela.UtilizeonomebotaoFiltroSaldo:

Quandoessebotãoforclicado,queremosexecutarumfiltrocomoLINQ:

privatevoidbotaoFiltroSaldo_Click(objectsender,EventArgse){//Aquiimplementaremosofiltro}

Comoosrelatóriosprecisarãodalistadecontas,pediremosessalistanoconstrutordajanela:

publicpartialclassFormRelatorios:Form{privateList<Conta>contas;publicFormRelatorios(List<Conta>contas){InitializeComponent();this.contas=contas;}//outrosmétodosdajanela.}

Dentrodaaçãodobotão,implementeabuscaportodasascontasquepossuemsaldomaiordoque5000.AgorautilizaremosoListBoxparamostrarascontasdevolvidaspeloLINQ.

OListBoxfuncionacomooComboBox.Quandoqueremosadicionarumanovalinha,precisamos

adicionaroobjetoquequeremosmostrardentrodapropriedadeItemsdoListBox.Elemostrará

21.7EXERCÍCIOS

21.7EXERCÍCIOS 171

Page 179: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

o ToString() do objeto adicionado. Como utilizaremos esse ListBox para mostrarmos o

resultadodediversasbuscas,precisamoslimparoresultadoanteriorantesdemostraropróximo,efazemosissoatravésdométodoClear()dapropriedadeItems:

privatevoidbotaoFiltroSaldo_Click(objectsender,EventArgse){listaResultado.Items.Clear();varresultado=//querydoLINQforeach(varcinresultado){listaResultado.Items.Add(c);}}

Agorapara testarmosessabusca,vamosadicionarumnovobotãodentrodo formulárioprincipal,classe Form1 , chamado botaoRelatorio que instanciará o formulário FormRelatorios

passandoalistadecontascomoargumentoedepoischamaráoShowDialogparamostraressanova

janela:

privatevoidbotaoRelatorio_Click(objectsender,EventArgse){FormRelatoriosform=newFormRelatorios(this.contas);form.ShowDialog();}

2. Agora vamos implementar um novo relatório com o LINQ. Dessa vez, queremos listar todas ascontas antigas (numeromenordoque10) com saldomaior doque1000.Para isso crie umnovobotãona janela de relatórios quequando clicado executará a querydoLINQna lista de contas emostraoresultadodentrodoListBoxquecriamosnoexercícioanterior.

3. Agoravamoscolocar resumosdas informaçõescontidasno relatório.Para isso,colocardentrodo

172 21.7EXERCÍCIOS

Page 180: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

relatórioumnovoGroupBoxqueteráotítuloResumo.DentrodesseGroupBox,mostraremos,por

exemplo,qualéosaldodacontademaiorSaldoequaléoSaldototaldetodasascontas.

Além desse GroupBox, coloque algumas 4 labels para mostrar os resumos desse relatório. O

primeirodevemostraro textoSaldoTotal, o segundo, o textoMaiorSaldo.Osdois labels

restantesserãoutilizadosparamostrarosresumos—chameoterceirolabeldelabelSaldoTotale

oúltimodelabelMaiorSaldo.Seuformuláriodeveficarparecidocomafiguraaseguir:

Depoisdemodificarmoso formulário,vamosmodificarasaçõesdobotãoparaqueelas, alémdefazerema busca, também atualizem o resumo com as informações da busca. Podemos extrair osresumosdaseguinteforma:

privatevoidbotaoFiltroSaldo_Click(objectsender,EventArgse){listaResultado.Items.Clear();varresultado=//querydoLINQforeach(varcinresultado){listaResultado.Items.Add(c);}doublesaldoTotal=resultado.Sum(conta=>conta.Saldo);doublemaiorSaldo=resultado.Max(conta=>conta.Saldo);

labelSaldoTotal.Text=Convert.ToString(saldoTotal);labelMaiorSaldo.Text=Convert.ToString(maiorSaldo);}

Experimente a API do LINQ, tentando criar novas queries e extrair outras informações para oresumodorelatório.

21.7EXERCÍCIOS 173

Page 181: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

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

Business,entreoutros!Ex-estudantedaCaelumtem10%dedesconto,sigaolink!

ConheçaaAluraCursosOnline.

Alémdefazermosbuscaseprojeções,podemostambémutilizaroLINQparaordenarcoleçõesdeelementos. Para isso precisamos apenas colocar um orderby dentro da query. Por exemplo, parabuscarmostodasascontascomsaldomaiordoque10000ordenadaspelonomedotitular,utilizamososeguintecódigo:

List<Conta>contas=//inicializaalistadecontasvarresultado=fromcincontaswherec.Saldo>10000orderbyc.Titular.Nomeselectc;

Comissotemosumalistadecontasordenadaspelonomedotitulardeformaascendente(alfabética).Assimcomopodemosfazeraordenaçãoascendente, tambémpodemosfazeraordenaçãodescendenteutilizandoapalavradescending:

List<Conta>contas=//inicializaalistadecontasvarresultado=fromcincontaswherec.Saldo>10000orderbyc.Titular.Nomedescendingselectc;

Masesetivermosdoistitularescomexatamenteomesmonome?Nessecaso,podemosdefinirumsegundocritérioparadesempatar aordenação.Cadaumdos critériosdaordenação fica separadoporvírgula noorderby. No exemplo, para desempatarmos a ordenação utilizando o número da conta,

utilizamososeguintecódigo:

List<Conta>contas=//inicializaalistadecontasvarresultado=fromcincontaswherec.Saldo>10000orderbyc.Titular.Nomedescending,c.Numeroselectc;

Osegundocritériodeordenaçãotambémpodeteropcionalmenteapalavradescending:

Agoraéamelhorhoradeaprenderalgonovo

21.8ORDENANDOCOLEÇÕESCOMLINQ

174 21.8ORDENANDOCOLEÇÕESCOMLINQ

Page 182: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

List<Conta>contas=//inicializaalistadecontasvarresultado=fromcincontaswherec.Saldo>10000orderbyc.Titular.Nomedescending,c.Numerodescendingselectc;

Assimcomono casodo filtro, as ordenaçõesdoLINQ também são traduzidas para chamadasdemétodo pelo compilador doC#.Quando colocamos umorderby na busca, o compilador chama o

métodoOrderBy(ouOrderByDescendingnocasodeumaordenaçãodescendente).Aquerycomo

filtroeaordenaçãopelotitularficadaseguinteforma:

varresultado=contas.Where(c=>c.Saldo>10000).OrderBy(c=>c.Titular.Nome);

Quandocolocamosumaordenaçãosecundária,ocompiladordoC#chamaométodoThenBy (ou

ThenByDescendingnocasodeumaordenaçãosecundáriadescendente):

varresultado=contas.Where(c=>c.Saldo>10000).OrderBy(c=>c.Titular.Nome).ThenBy(c=>c.Numero);

1. Vamos adicionar uma ordenação na tela de relatórios. Faça com que os botões que geram osrelatóriosmostremascontasordenadaspelaordemalfabéticadonomedotitular.

2. (Opcional) Agora tente fazer a mesma ordenação do exercício passado utilizando o métodoOrderBydoLINQ.

3. (Opcional) Tente utilizar também uma ordenação secundária pelo número da conta em seusrelatórios.

21.9EXERCÍCIOS-ORDENAÇÃO

21.9EXERCÍCIOS-ORDENAÇÃO 175

Page 183: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO22

AgoraquejávimosquepodemosutilizaroC#paradesenvolverumsistemaorientadoaobjetos,vamosaprendercomoutilizarasbibliotecasdoSystem.IOparalereescreverdadosemarquivos.

AentradadedadosnoC#funcionaemduasetapas.Naprimeiraetapa, temosumaclasseabstrataque representa uma sequência de bytes na qual podemos realizar operações de leitura e escrita. EssaclasseabstrataéchamadadeStream.

Como o Stream é uma classe abstrata, não podemos usá-la diretamente, precisamos de uma

implementação para essa classe. No caso de leitura ou escrita em arquivos, utilizamos um tipo deStream chamadoFileStream, que pode ser obtido através dométodo estático Open da classe

File.QuandoutilizamosoOpen, devemospassar o nomedo arquivoque será aberto e devemos

informá-looquequeremosfazercomoarquivo(lerouescrever).

Paraabrirmosoarquivoentrada.txtparaleitura,utilizamosocódigoaseguir:

Streamentrada=File.Open("entrada.txt",FileMode.Open);

AgoraquetemosoStream,podemoslerseupróximobyteutilizandoométodoReadByte.

byteb=entrada.ReadByte();

Porém, trabalhar combytesnãoé fácil, queremos trabalhar com textos!Portantovamosutilizar asegundapartedaleitura.

Para facilitar a leitura de Streams, o C# nos oferece uma classe chamada StreamReader ,

responsável por ler caracteres ou strings de umStream.OStreamReader precisa saber qual é a

Streamqueserálida,portantopassaremosessainformaçãoatravésdeseuconstrutor:

StreamReaderleitor=newStreamReader(entrada);

Paralerumalinhadoarquivo,utilizamosométodoReadLinedoStreamReader:

stringlinha=leitor.ReadLine();

Enquanto o arquivo não terminar, o método ReadLine() devolve um valor diferente de nulo,

SYSTEM.IO

22.1LEITURADEARQUIVOS

176 22SYSTEM.IO

Page 184: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

portanto,podemoslertodasaslinhasdeumarquivocomoseguintecódigo:

stringlinha=leitor.ReadLine();while(linha!=null){MessageBox.Show(linha);linha=leitor.ReadLine();}

Assimqueterminamosdetrabalharcomoarquivo,devemossemprelembrardefecharoStreame

oStreamReader:

leitor.Close();entrada.Close();

Ocódigocompletoparalerdeumarquivoficadaseguinteforma:

Streamentrada=File.Open("entrada.txt",FileMode.Open);StreamReaderleitor=newStreamReader(entrada);stringlinha=leitor.ReadLine();while(linha!=null){MessageBox.Show(linha);linha=leitor.ReadLine();}leitor.Close();entrada.Close();

Porém,oarquivopodenãoexistire,nessecaso,oC#lançaaFileNotFoundException.Devemos,

portanto, verificar se o arquivo existe antes de abri-lo para leitura. Podemos verificar se um arquivoexisteutilizandoométodoExistsdaclasseFile:

if(File.Exists("entrada.txt")){//Aquitemoscertezaqueoarquivoexiste}

Ocódigodaleituracomaverificaçãoficaassim:

if(File.Exists("entrada.txt")){Streamentrada=File.Open("entrada.txt",FileMode.Open);StreamReaderleitor=newStreamReader(entrada);stringlinha=leitor.ReadLine();while(linha!=null){MessageBox.Show(linha);linha=leitor.ReadLine();}leitor.Close();entrada.Close();}

22.1LEITURADEARQUIVOS 177

Page 185: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

LENDOTODOOCONTEÚDODEUMARQUIVO

Vimosqueparalertodasaslinhasdeumarquivo,precisamosutilizarométodoReadLineaté

queoretornosejaovalornull,masissoétrabalhoso.

Ao invés de chamar o método ReadLine para cada linha, podemos utilizar o método

ReadToEnddaclasseStreamReader.Essemétododevolveumastringcomtodooconteúdo

doarquivo.

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

CasadoCódigo,ebookcompreçodeebook.

Assimcomoa leitura, aescrita tambémaconteceemduasetapas.Naprimeiraetapa, trabalhamosnovamenteescrevendobytesparaasaída.ParaissoutilizaremosnovamenteaclasseabstrataStream.

Para escrevermos em um arquivo, precisamos primeiro abri-lo em modo de escrita utilizando ométodoOpendoFilepassandoomodoFileMode.Create:

Streamsaida=File.Open("saida.txt",FileMode.Create);

Porém,nãoqueremostrabalharcomBytes,entãoutilizaremosumaclasseespecializadaemescreveremumStreamchamadaStreamWriter.

StreamWriterescritor=newStreamWriter(saida);

PodemosescreverumalinhacomoStreamWriterutilizandoométodoWriteLine:

escritor.WriteLine("minhamensagem");

EditoraCasadoCódigocomlivrosdeumaformadiferente

22.2ESCREVENDOEMARQUIVOS

178 22.2ESCREVENDOEMARQUIVOS

Page 186: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Depoisqueterminamosdeutilizaroarquivo,precisamosfechartodososrecursos:

escritor.Close();saida.Close();

Ocódigocompletoparaescrevernoarquivoficadaseguinteforma:

Streamsaida=File.Open("saida.txt",FileMode.Create);StreamWriterescritor=newStreamWriter(saida);escritor.WriteLine("minhamensagem");escritor.Close();saida.Close();

Repareque,porusarmosumaclasseabstrata,podemosentãotrocarfacilmenteaclasseconcretaporoutra.Porexemplo,poderíamos lerdeumSocket,oudeumaportaserial,eocódigoseriaomesmo:bastaaclasseserfilhadeStream.Reparequeousodeclassesabstratasepolimorfismonospossibilita

ler/escreveremdiferenteslugarescomomesmocódigo.VejaqueaprópriaMicrosoftfezbomusodeorientaçãoaobjetosparafacilitaravidadosdesenvolvedores.

OIOdoC#podeseresquematizadopelaseguintefigura:

ONDEOSARQUIVOSSÃOGRAVADOS

Quandopassamos apenasonomedo arquivono códigodoFile.Open, oC#procura esse

arquivodentrodapastaemqueaaplicaçãoéexecutada.NocasodeexecutarmosaaplicaçãopeloVisualStudio,apastautilizadapelaaplicaçãoseráapastaemqueoprojetofoicriado.

Toda vez que abrimos um arquivo dentro de um programa C#, precisamos fechá-lo utilizando ométodoClose.DevemosgarantirqueoClose seráexecutadomesmoquandoocódigo lançauma

exceçãodurantesuaexecução,paraissopodemosutilizaroblocofinally:

Streamarquivo=null;

22.3GERENCIANDOOSARQUIVOSCOMOUSING

22.3GERENCIANDOOSARQUIVOSCOMOUSING 179

Page 187: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

StreamReaderleitor=null;try{arquivo=File.Open("arquivo.txt",FileMode.Open);leitor=newStreamReader(arquivo);//utilizaoarquivo}catch(Exceptionex){//Executaotratamentodoerroqueaconteceu}finally{//fechaoarquivoeoleitor

//antesdefecharmos,precisamosverificarqueoarquivoeoleitorforam//realmentecriadoscomsucessoif(leitor!=null){leitor.Close();}if(arquivo!=null){arquivo.Close();}}

Vejaqueocódigoparalidarcorretamentecomosarquivospodeficarmuitocomplicado.Aoinvésdecuidarmosmanualmentedosarquivos,podemospedirparaalinguagemC#cuidardogerenciamentoutilizandooblocousing.

Dentrodeumblocousingpodemosinstanciarumrecursoquequeremosquesejagerenciadopelo

C#,comoporexemploumarquivo:

using(Streamarquivo=File.Open("arquivo.txt",FileMode.Open)){//oarquivosóficaabertodentrodessebloco.}//setentarmosutilizaroarquivoforadoblocousingteremosumerrodecompilação.

TambémpodemosutilizarousingparagerenciaroStreamReader:

using(Streamarquivo=File.Open("arquivo.txt",FileMode.Open))using(StreamReaderleitor=newStreamReader(arquivo)){//aquidentrovocêpodeutilizartantooleitorquantooarquivo}

Ousingautomaticamentefechaosarquivosutilizadosdentrodoblocomesmoquandoumaexceçãoélançadapelocódigo.

Podemos utilizar o bloco using para gerenciar qualquer classe que implemente a interfaceIDisposabledoC#.

22.4EXERCÍCIOS

180 22.4EXERCÍCIOS

Page 188: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

1. Vamosagoracriarumpequenoeditorde textopara trabalharmoscomarquivos.DentrodoVisualC#,crieumnovoprojetodotipoWindowsFormApplicationchamadoEditorDeTexto.Dentro

desseprojeto,adicioneumTextBoxqueseráocampodetextoondeousuáriodigitaráotextoque

devesergravadonoarquivo,chame-odetextoConteudo.Alémdessecampode texto,adicione

também um botão que quando clicado gravará o campo de texto em um arquivo, chame-o debotaoGrava.

Para permitir que o usuário possa digitar diversas linhas no campo de texto, clique com o botãodireitonoTextBoxeselecioneaopçãoProperties.DentrodajanelaProperties,encontrea

propriedadechamadaMultilineemudeseuvalorparatrue.AgoraestiqueoTextBoxparaqueoseuformuláriofiqueparecidocomodaimagem:

Agoraquetemosoformuláriopronto,façacomqueocarregamentodoprogramapreenchaocampodetextodo formuláriocomoconteúdodeumarquivochamadotexto.txt.Não se esqueçade

verificarqueoarquivoexisteantesdeabri-lo

privatevoidForm1_Load(objectsender,EventArgse){if(File.Exists("texto.txt")){Streamentrada=File.Open("texto.txt",FileMode.Open);StreamReaderleitor=newStreamReader(entrada);stringlinha=leitor.ReadLine();while(linha!=null){textoConteudo.Text+=linha;linha=leitor.ReadLine();}leitor.Close();entrada.Close();}}

22.4EXERCÍCIOS 181

Page 189: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

2. Implemente a ação do botão Gravar. Quando clicado, esse botão deve gravar o conteúdo doTextBoxdentrodeumarquivochamadotexto.txt:

privatevoidbotaoGrava_Click(objectsender,EventArgse){Streamsaida=File.Open("texto.txt",FileMode.Create);StreamWriterescritor=newStreamWriter(saida);escritor.Write(textoConteudo.Text);escritor.Close();saida.Close();}

3. ExisteummétododentrodaclasseStreamReaderchamadoReadToEndquelêtodasaslinhasdo

arquivo.Modifiqueoeditorparautilizaressemétodo.

4. Modifiqueocódigodoeditordetextoparaqueeleutilizeousingparafecharosarquivos.

5. (Opcional)Quando queremos um programa que trabalha com o terminal do sistema operacional,precisamoscriarumtipodiferentedeprojetonoVisualStudio,oConsoleApplication.

Para criarmos a aplicação que usa o terminal, devemos seguir os mesmos passos da criação doWindows Form Application, porém escolheremos o Console Application na janela do

assistente.

Quandocriamosumaaplicaçãonoconsole,oVisualStudiocriaumnovoprojetocomumaclassequecontémummétodochamadoMain.ÉessemétodoqueseráexecutadoquandoapertarmosF5

pararodaroprograma.

DentrodoMain,podemosimprimirumamensagemnoterminalutilizandooConsole.WriteLine

passandoamensagem:

Console.WriteLine("Mensagemquevaiparaoterminal");

Quandoqueremos lerumalinhaqueousuáriodigitouno terminal,utilizamosumatributodo tipoTextReaderdaclasseConsolechamadoIn:

TextReaderleitor=Console.In;

NoTextReader,temosométodoReadLinequeconseguelerumalinhadoterminal.

stringlinha=leitor.ReadLine();

OReadLinedevolveumastringnãonula,enquantoousuáriocontinuarenviandonovaslinhas.

while(linha!=null){//usaotextodalinhaatuallinha=leitor.ReadLine();}

QuandoousuáriomandaacombinaçãoCtrl+zparaaaplicação,oleitordevolvenull.

182 22.4EXERCÍCIOS

Page 190: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CrieumprogramaquelêeimprimeaslinhasqueousuáriodigitanoterminalatéquesejaenviadaacombinaçãoCtrl+z.

6. (Opcional)Quandofizemosaleituradeumarquivo,utilizamosocódigo:

using(Streamentrada=File.Open("entrada.txt",FileMode.Open))using(StreamReaderleitor=newStreamReader(entrada)){//usaoleitor}

NoC#,oStreamReaderéumasubclassedaclasseabstrataTextReader,amesmaqueutilizamos

paralerdadosdoterminal,logopodemosreescreverocódigodaleituradearquivopara:

using(Streamentrada=File.Open("entrada.txt",FileMode.Open))using(TextReaderleitor=newStreamReader(entrada)){//usaoleitor}

Quais modificações deveríamos fazer nesse código para ler o texto que o usuário digitou noterminal?

AAluraoferececentenasdecursosonlineemsuaplataformaexclusivadeensinoquefavoreceoaprendizadocomaqualidadereconhecidadaCaelum.VocêpodeescolherumcursonasáreasdeProgramação,Front-end,Mobile,

Design&UX,Infra,Business,entreoutras,comumplanoquedáacessoatodososcursos.Ex-estudantedaCaelumtem10%dedescontonestelink!

ConheçaoscursosonlineAlura.

Precisamos tomar muito cuidado ao escrever programas que guardam informações dentro dearquivos.Comoditoanteriormente,quandoutilizamosoFile.Open,oC#procuraoarquivonapasta

emqueaaplicaçãoestásendoexecutada,porémmuitasvezesosprogramasescritossãoinstaladosempastas do sistema operacional, por exemplo C:/Arquivos de Programas, nesse caso o programa

tentaráescreveras informaçõesdentrodeumpastadosistemaoperacionalepor isso,elesópodeserexecutadoporumadministradordosistema.

JáconheceoscursosonlineAlura?

22.5 PARA SABER MAIS — ONDE COLOCAR OS ARQUIVOS DAAPLICAÇÃO

22.5PARASABERMAIS—ONDECOLOCAROSARQUIVOSDAAPLICAÇÃO 183

Page 191: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Normalmente,quandoescrevemosumaaplicaçãocomalgumerrodeprogramação,issonãoafetaosistemaoperacionalpoisoprogramanãoéexecutadocompermissõesdeadministradore,portanto,nãopode fazermodificaçõesperigosasno sistema.Então, paraque a aplicaçãonãoprecise ser executadocomo administrador, podemos fazer com que ela escreva, por exemplo, na pasta de documentos dousuáriologado.

Quandoqueremos recuperaro caminhoparaumapasta especialdo sistemaoperacional, podemosutilizar uma classe doC# chamada Environment do namespace System. Nessa classe, podemos

invocar ométodoGetFolderPath para recuperar o caminho para umapasta do sistema.Ométodo

GetFolderPathrecebecomoargumentoumaconstantequeindicaqualéapastaquequeremos.Para

recuperarmos o caminho para a pasta de documentos do usuário logado, podemos utilizar o seguintecódigo:

stringpastaDocumentos=Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

Os outros valores aceitos pelo método GetFolderPath podem ser encontrados nessa página:http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx

Agora se quisermos abrir um arquivo chamado entrada.txt dentro da pasta de documentos,

precisamos combinar o caminho da pasta com o nome do arquivo. Para resolver esse problema,utilizamosométodoCombinedaclassePathdonamespaceSystem.IO:

stringpastaDocumentos=Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

stringcaminhoArquivo=Path.Combine(pastaDocumentos,"entrada.txt");

184 22.5PARASABERMAIS—ONDECOLOCAROSARQUIVOSDAAPLICAÇÃO

Page 192: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO23

EmC# textos são representados por objetos do tipo string. Para criar um texto, podemos usar a

seguintesintaxe:

stringtitulo="ArquiteturaeDesigndeSoftware";MessageBox.Show(titulo);//imprimeoconteúdo

Podemosaindajuntarduasstrings:

stringtitulo="Arquitetura"+"e"+"DesigndeSoftware";titulo+="!"//concatenaa!nofimdotexto

Usandoaconcatenação,podemosinserirovalordequalquervariávelnomeiodenossotexto:

intidade=42;MessageBox.Show("aidadeatualé"+idade);

Mas ficar concatenando strings nem sempre é fácil, principalmente se temos muitos valores.Podemosusarumaalternativa,fazendoopróprioC#fazeressaconcatenaçãopornós.Paraisso,bastaindicarnastringaposiçãoquequerinseriravariávelusandoasintaxe{posicao},epassarovalor

correspondenteemordem:

stringnome="Guilherme";intidade=42;Console.WriteLine("Olá{0},asuaidadeé{1}",nome,idade);

Casoprecisemosarmazenarastringjáconcatenadaemumavariávelaoinvésdeaimprimir,bastausarométodoFormat:

stringnome="Guilherme"intidade=42;stringtxt=string.Format("Olá{0},asuaidadeé{1}",nome,idade);MessageBox.Show(txt);

Imagine que temos uma linha de texto que separa os dados de umusuário do sistema através devírgulas:

stringtexto="guilhermesilveira,42,sãopaulo,brasil";

Comosepararcadaumadaspartesatravésda,?AclasseStringcontatambémcomummétodo

Split,quedivideaStringemumarraydeStrings,dadodeterminadocaracterecomocritério:

stringtexto="guilhermesilveira,42,sãopaulo,brasil";string[]colunas=texto.Split(',');

MANIPULAÇÃODESTRINGS

23MANIPULAÇÃODESTRINGS 185

Page 193: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

SemprequechamamosummétodoemumobjetoString, umnovoobjeto é criado e retornado

pelo método, mas o original nunca é modificado. Strings são imutáveis. Portanto ao tentarmostransformaremletramaiúsculaoresultadopodenãoseroesperado:

stringcurso="fn13";curso.ToUpper();MessageBox.Show(curso);//imprimefn13

Sendoassim,quandoqueremostransformaremmaiúsculodevemosatribuiroresultadodométodo:

stringcurso="fn13";stringmaiusculo=curso.ToUpper();MessageBox.Show(maiusculo);//imprimeFN13

PodemossubstituirpartedoconteúdodeumaString,usandoométodoReplace:

stringcurso="fn13";curso=curso.ToUpper();curso=curso.Replace("1","2");MessageBox.Show(curso)//imprimeFN23;

Podemosconcatenarasinvocaçõesdemétodo,jáqueumastringédevolvidaacadainvocação:

stringcurso="fn13";curso=curso.toUpper().Replace("1","2");MessageBox.Show(curso)//imprimeFN23;

Àsvezesprecisamosquebrarnossostextosempartesmenorescombasenaquantidadedecaracteres,ouainda,encontraraposiçãodeumcaractereespecíficodentrodenossastring:

stringnomeCompleto="guilhermesilveira";stringnome=nomeCompleto.Substring(0,9);MessageBox.Show(nome)//imprimeguilherme;

Eparabuscarocaractereespaçodentrodeumastring:

intposicaoDoEspaco=nomeCompleto.IndexOf("");MessageBox.Show(posicaoDoEspaco);//imprime8

Ouainda,usaressesmétodosemconjunto,paraumexemplomaisavançado,noqualimprimimososegundonome:

stringnomeCompleto="guilhermesilveira";

intinicioDoSegundoNome=nomeCompleto.IndexOf("s");

MessageBox.Show(nomeCompleto.Substring(inicioDoSegundoNome));//imprimesilveira

1. Observeoseguintetrechodecódigo:

stringconteudo="16,23,34,24,15,25,35,35,54,32";

23.1EXERCÍCIOS

186 23.1EXERCÍCIOS

Page 194: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

string[]idades=????;

foreach(varninidades){MessageBox.Show(n);}

Qualtrechodecódigodevesubstituiras???paraimprimirtodososnúmeros?

csharpconteudo.Split(',');

csharpconteudo.Replace("","\n");

csharpconteudo.Split(,);

csharpconteudo.Split('');

2. Vamosagoramelhoraroeditordetextoquecriamosnocapítuloanteriorutilizandoasoperaçõesemstring!Inicialmente,vamosincluirafuncionalidadedebuscadestringsnaaplicação.

Vamoscriarmaisumcampode textono formulárioqueseráutilizadopelousuárioparadigitarotermoqueserábuscadonoeditor.ChameessecampodetextodetextoBusca.Alémdocampode

texto, inclua tambémumbotão que, quando clicado, buscará o texto dotextoBusca dentro do

editor.Chame-odebotaoBusca.Seuformuláriodeveficarparecidocomoquesegue:

Agora que atualizamos o formulário, vamos implementar a funcionalidade de busca.Na ação dobotãodebusca,vamosutilizarométodoIndexOfparaimplementarabusca:

privatevoidbotaoBusca_Click(objectsender,EventArgse){stringbusca=textoBusca.Text;stringtextoDoEditor=textoConteudo.Text;intresultado=textoDoEditor.IndexOf(busca);if(resultado>=0)

23.1EXERCÍCIOS 187

Page 195: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

{MessageBox.Show("acheiotexto"+busca);}else{MessageBox.Show("nãoachei");}}

Testeessanovafuncionalidadedoprograma.

3. Agoravamosimplementarafuncionalidadefind/replacequeémuitocomumnoseditoresdetextoatuais. Para isso, vamos adicionar mais um campo de texto no formulário que será otextoReplace, além de um novo botão que quando clicado trocará todas as ocorrências de

textoBuscaportextoReplacedentrodoeditor.EssebotãoseráobotaoReplace.

4. Vamosagoraadicionarumnovobotãonoformulárioquequandoclicadofarácomqueo textodoeditorfiquecomletrasmaiúsculas.UtilizeométodoToUpper()daStringparafazeressetrabalho.

5. (Opcional)AdicionetambémumbotãoqueutilizaoToLower()dastring.

6. (Opcional)Agoravamos fazer comqueobotãoToUpper altere apenasopedaçoqueousuário

selecionar do texto digitado ao invés de todo o texto. Para isso, utilizaremos duas novaspropriedades do TextBox que lidam com seleção de texto: SelectionStart e

SelectionLength.

ApropriedadeSelectionStart nos diz em qual posição, começando em 0, do texto o usuário

iniciouaseleção.SelectionLength nos devolvequantos caracteres do texto estão selecionados

atualmente.

Porexemplo,notextoabaixo:

CursodeC#daCaelum

SeousuárioselecionarapalavraCurso,SelectionStartdevolverá0eSelectionLength,5.

AgoravamosutilizaressasduasnovaspropriedadesparaimplementaroToUppernaseleção:

privatevoidbotaoToUpper_Click(objectsender,EventArgse){intinicioSelecao=textoConteudo.SelectionStart;inttamanhoSelecao=textoConteudo.SelectionLength;

//agoravamosutilizaroSubstringparapegarotextoselecionadostringtextoSelecionado=textoConteudo.Text.Substring(inicioSelecao,tamanhoSelecao);

//alémdotextoselecionado,precisamosdotextoantesdaseleção:stringantes=textoConteudo.Text.Substring(0,inicioSelecao);

//etambémdotextodepoisstringdepois=textoConteudo.Text.Substring(inicioSelecao+tamanhoSelecao);

188 23.1EXERCÍCIOS

Page 196: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

//EagorasóprecisamosredefinirocampotextotextoConteudo.Text=antes+textoSelecionado.ToUpper()+depois;}

TentefazeromesmoparaobotãoToLower.

Querendoaprenderaindamaissobre?Esclarecerdúvidasdosexercícios?Ouvirexplicaçõesdetalhadascomuminstrutor?ACaelum oferece o cursodata presencial nas cidades de São Paulo, Rio deJaneiroeBrasília,alémdeturmasincompany.

ConsulteasvantagensdocursoC#eOrientaçãoaObjetos

VocêpodetambémfazerocursodatadessaapostilanaCaelum

23.1EXERCÍCIOS 189

Page 197: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

CAPÍTULO24

Muitasvezesusamosclassescriadasporoutrosdesenvolvedores,comoporexemplotodasasclassesdo.NETframework.Aclassestringéumbomexemploecheiademétodosúteismasquemdesenhoua

classenãocolocouummétodoparatransformarumapalavraemseuplural,porexemplo.Oquefazersequeremosopluralde"conta"e"banco"geradoautomaticamente?

Umaabordageméacriaçãodeummétodoestáticoquepodeserchamado:

publicstaticclassStringUtil{publicstaticstringPluralize(stringtexto){if(texto.EndsWith("s")){returntexto;}else{returntexto+"s";}}}

Claroqueessemétodoéumaabordagembemsimplesparaumalgoritmoqueécapazderetornarplurais,masjáresolveoproblemanocasogeral.Agorapodemosemtodolugardonossocódigofazer:

stringbancos=StringUtil.Pluralize("banco");stringcontas=StringUtil.Pluralize("conta");

Por mais que a implementação funcione, o código fica muito feio porque toda vez precisamosinvocarométodoestático.Nãoseriapossívelestenderaclassestringparafazeralgocomoocódigoa

seguir?

Stringtexto="banco";Stringplural=texto.Pluralize();

OC#permiteacriaçãodemétodosdeextensãoparaclassesquejáexistematravésdousodapalavrausing,maspara issodevemos colocar nossa classe estática dentrodeumnamespace e adicionar a

palavrathisaoprimeiroparâmetro:

APÊNDICE—ESTENDENDOCOMPORTAMENTOSATRAVÉSDEMÉTODOSEXTRAS

190 24APÊNDICE—ESTENDENDOCOMPORTAMENTOSATRAVÉSDEMÉTODOSEXTRAS

Page 198: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

namespaceMinhasExtensoes{publicstaticclassStringExtensions{publicstaticstringPluralize(thisstringtexto){if(texto.EndsWith("s")){returntexto;}else{returntexto+"s";}}}}

Agorapodemos:

usingMinhasExtensoes;

stringtexto="banco";stringplural=texto.Pluralize();

Notecomo,aoimportarasextensões,todososmétodosestáticosdeclassesestáticaspúblicasdentrodo namespace importado estarão disponíveis para serem acessados como se pertencessem a classe,apesardenãopertencerem.

É importante lembrarqueométodosópodeseracessadocasoaindanãoexistaumoutrométodocomomesmonomeetiposdeparâmetrosnaclasse.Istoé,nãoseriapossívelestenderaclassestring

comumnovométodoToString()poiselejáexiste.Sópodemosadicionarnovoscomportamentos.

Exatamenteporissopodeserperigosoadicionarmétodoscomoextensõessemcuidadonenhum:nofuturoalguémpodeadicionaressemétodoàclassequeestendemoseagoranossocódigoquebrapoisnãoémaiscompatível.Somenteestendaoscomportamentosdeumaclassecasosejanecessário.

1. Queremos"adicionar"atodasasnossascontasacapacidadedeumaContasetransformaremXML.ParaissooC#jádispõeumaAPI:

usingSystem.IO;usingSystem.Xml.Serialization;publicstaticclassSerializer{publicstaticstringAsXml(Contaresource){

varstringWriter=newStringWriter();newXmlSerializer(resource.GetType()).Serialize(stringWriter,resource);returnstringWriter.ToString();}}

Paraacessaresseprocessofazemos:

24.1EXERCÍCIOS

24.1EXERCÍCIOS 191

Page 199: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Contaconta=newConta();System.Console.Write(Serializer.AsXml(conta));

Como desejamos usar o recurso de extensão externa doC# para poder "adicionar" ummétodo atodosascontasdosistema,oquedevemoscolocarnalinhacomentadaparadefinirnossométodo?

usingSystem.IO;usingSystem.Xml.Serialization;

namespaceCaelum{publicstaticclassObjectExtensions{//Definiçãodométodo{varstringWriter=newStringWriter();newXmlSerializer(resource.GetType()).Serialize(stringWriter,resource);returnstringWriter.ToString();}}}

//UsousingSystem;usingCaelum;Contaconta=newConta();Console.Write(conta.AsXml());

publicstaticstringAsXml(thisContaresource)

publicstringAsXml(Contaresource)

publicstringAsXml(thisContaresource)

publicstaticstringAsXml(Contaresource)

publicstaticextensionstringAsXml(Contaresource)

publicstaticstringAsXml(extensionContaresource)

2. Em vez de adicionar o extension method a todas as nossas contas, queremos incluir essecomportamentocomoextensãoatodososobjetosdosistema.Comodefiniressemétodo?

publicstaticclassSerializer{//comodefinirométodo???{

varstringWriter=newStringWriter();newXmlSerializer(resource.GetType()).Serialize(stringWriter,resource);returnstringWriter.ToString();

}}

publicstaticstringAsXml(thisobjectresource)

publicstaticstringAsXml(thisresource)

192 24.1EXERCÍCIOS

Page 200: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

publicstaticstringAsXml(objectresource)

publicstaticstringAsXml(thisallresource)

3. Definimosumaextensãoaobjectdaseguintemaneira:

namespaceCaelum{publicstaticclassObjectExtensions{publicstaticstringToString(thisobjectresource){varstringWriter=newStringWriter();newXmlSerializer(resource.GetType()).Serialize(stringWriter,resource);returnstringWriter.ToString();}}}

Aodefinirousingadequado,qualoresultadoaochamaroToStringaseguir?

usingCaelum;Contaconta=newConta();MessageBox.Show(conta.ToString());

NãocompilapoisnãopodemossobrescreverométodoToString.

Mostraumaversãoemxmldenossaconta,ouseja,oC#usaoextensionmethod.

ImprimeoresultadotradicionaldométodoToString,ouseja,oC#nãousaoextensionmethod.

4. DadaaclasseContadefinidanoscapítulosanteriores:

publicabstractclassConta{publicdoubleSaldo{get;protectedset;}

//outrosmétodosepropriedadesdaclasseConta}

Eumaclassecomumextensionmethodparaaconta:

publicstaticclassContaExtensions{publicstaticvoidMudaSaldo(thisContaconta,doublenovoSaldo){conta.Saldo=novoSaldo;}}

Escolhaaalternativacomaafirmaçãoverdadeira.

Essecódigonãocompila,poisoExtensionMethodsópodeacessarainterfacepúblicadaConta.

Ocódigo funcionanormalmente,poiso compiladordoC# trataumextensionmethodcomosefosseummétododaContae,portanto,ométodopodeacessarosmétodoseatributosprivatee

24.1EXERCÍCIOS 193

Page 201: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

protecteddaConta.

Ocódigocompilanormalmente,porémsópodemosusaroMudaSaldodentrodaprópriaclasseConta.

5. Sobreocódigoaseguir:

publicabstractclassConta{publicClienteTitular{get;set;}//outrosmétodoseatributosdaconta}

publicstaticclassContaExtensions{publicstaticvoidMudaTitular(thisContaconta,thisClientetitular){conta.Titular=titular;}}

Oquepodemosafirmar?

Ocódigonãocompila,poisothissópodeficarnoprimeiroargumentodoextensionmethod.

Compila normalmente e podemos usar o MudaTitular como extension method de Conta e deCliente.

Compilanormalmente,porémométodosópodeserusadocomoextensionmethoddeConta.

6. Dadasasclasses:

publicabstractclassConta{publicClienteTitular{get;set;}//outrosmétodoseatributosdaConta}publicstaticclassContaExtensions{publicstaticvoidMudaTitular(thisContac,Clientetitular){c.Titular=titular;}}

Oquepodemosafirmarsobreocódigoaseguir?

Contac=newContaCorrente();Clientetitular=newCliente("victor");ContaExtensions.MudaTitular(c,titular);

ExtensionMethodéummétodoestáticocomume,portanto,ocódigodoexercíciofunciona.

Ocódigodoexercícionãocompila.SópodemosusaroMudaTitularcomoextensionmethodenãocomométodoestático.

194 24.1EXERCÍCIOS

Page 202: uso comercial deste material, por favor, consulte a Caelum … · 2020-07-03 · Essa apostila é constantemente atualizada e disponibilizada no site da Caelum. Sempre consulte o

Ocódigonãocompila,poistemosumthisnoprimeiroargumentodoMudaTitular.

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

CasadoCódigo,LivrosdeTecnologia.

Seuslivrosdetecnologiaparecemdoséculopassado?

24.1EXERCÍCIOS 195