Baixe o app para aproveitar ainda mais
Prévia do material em texto
PROGRAMAÇÃO DE COMPUTADORES Eduardo Cardoso Melo Rosangela Silqueira Hickson Rios Te cn o lo g ia P R O G R A M A Ç Ã O D E C O M P U T A D O R E S E d ua rd o C ar d os o M el o R os an g el a S ilq ue ira H ic ks on R io s Curitiba 2016 Programacao de Computadores Eduardo Cardoso Melo Rosangela Silqueira Hickson Rios Ficha Catalográfica elaborada pela Fael. Bibliotecária – Cassiana Souza CRB9/1501 M528p Melo, Eduardo Cardoso Programação de computadores / Eduardo Cardoso Melo, Rosangela Silqueira Hickson Rios - Curitiba: Fael, 2016. 164 p.: il. ISBN 978-85-60531-51-6 1. Programação (Informática) 2. Linguagem orientada a objeto I. Rios, Rosangela Silqueira Hickson II. Título CDD 005.117 Direitos desta edição reservados à Fael. É proibida a reprodução total ou parcial desta obra sem autorização expressa da Fael. FAEL Direção de Produção Fernando Santos de Moraes Sarmento Coordenação Editorial Raquel Andrade Lorenz Revisão FabriCO Projeto Gráfico Sandro Niemicz Capa Vitor Bernardo Backes Lopes Imagem Capa Shutterstock.com/Bruce Rolff/McIek Arte-Final Evelyn Caroline dos Santos Betim Sumário Carta ao aluno | 5 1. Fundamentos da programação | 7 2. Características das Linguagens Orientadas a Objetos | 21 3. Classes | 37 4. Fundamentos de métodos | 53 5. Criando objetos | 73 6. Herança, polimorfismo e encapsulamento | 93 7. Aplicação de herança, polimorfismo e encapsulamento | 107 8. Tipos abstratos de dados | 119 9. Aplicação em linguagem de alto nível | 131 10. Elementos de software | 143 Conclusão | 157 Referências | 159 Carta ao aluno Prezado(a) aluno(a), Os programas de computador estão presentes em, pratica- mente, todas as empresas modernas, seja para auxiliar a gestão finan- ceira ou, até mesmo, para subsidiar o processo de tomada de deci- sões dos gestores. Em alguns casos, existe uma dependência quase completa da empresa em relação aos seus sistemas informatizados. Sendo assim, é muito importante que o profissional desta área apresente conhecimentos relacionados à forma como esses pro- gramas de computador são elaborados, desde sua concepção até seu efetivo desenvolvimento em uma linguagem de programação – 6 – Programação de Computadores moderna. O entendimento das regras básicas de programação é fundamental para a qualidade dos programas codificados. Além disso, atualmente, espera- -se que este profissional domine as principais características do paradigma mais utilizado para o desenvolvimento de sistemas, conhecido como “Orien- tado a Objetos”. Os conteúdos abordados no material desta disciplina objetivam jus- tamente prepará-lo e capacitá-lo para o desenvolvimento de programas de computador. Para isso, toma-se como base o modelo orientado a objetos, per- mitindo o estudo dos conceitos de classes, objetos, encapsulamento, herança, polimorfismo e tipos abstratos de dados. Esperamos que, ao final dos estudos, você seja capaz de aplicar diversas competências interligadas com a programação de computadores, especial- mente, aquelas relacionadas com a aplicação do modelo orientado a objetos na elaboração de programas. Seja muito bem-vindo e tenha um ótimo aproveitamento! Neste capítulo, apresentaremos as características relacio- nadas com o desenvolvimento de programas de computador, dando especial atenção à construção de algoritmos. Este entendimento inicial é muito importante para que você compreenda como um software é produzido, desde a concepção da sua ideia até o desenvol- vimento do código que será executado pelo computador (ou outro equipamento eletrônico). Também serão demonstrados alguns con- ceitos fundamentais da programação de computadores, como as variáveis, os tipos de dados e a definição de identificadores. 1 Fundamentos da programação – 8 – Programação de Computadores Objetivos de aprendizagem: 2 Apresentar os fundamentos da programação de computadores; 2 Compreender como é o funcionamento interno de um computa- dor em relação ao processamento de dados; 2 Identificar as características básicas e os principais formatos de algoritmos; 2 Diferenciar algoritmos e programas de computador; 2 Compreender a forma de utilização da memória por programas de computador. 1.1 Conceitos iniciais Desde tempos remotos, a humanidade busca criar máquinas capazes de auxiliar na realização de tarefas e melhoria da qualidade de vida das pessoas. Essa situação deu origem a inúmeras inovações relacionadas com diversas áreas, como financeira, transportes, educação e saúde. Atualmente, é difícil pensar o mundo sem o uso de automóveis e aviões, de smartphones e tablets, de caixas eletrônicos e, até mesmo, de uma simples lâmpada. Os produtos e serviços mais recentes, principalmente aqueles disponíveis desde a década de 1980, têm em comum o uso intenso de recursos computacionais. Em outras palavras, os equipamentos eletrônicos que o mundo passou a utilizar no seu dia a dia funcionam com base em um computador interno programado para realizar tarefas específicas. Sendo assim, é importante fazermos uma diferenciação entre o conceito real de computador e a ideia que a maioria das pessoas possui sobre este termo (representada pela figura do computador pessoal). Basicamente, a definição mais aceita de computador indica que ele é um equipamento eletrônico com capacidade de receber diversos tipos de dados e processá-los para alcançar determinado objetivo. Portanto, o termo apresenta um entendimento bem mais amplo do que apenas um computador pessoal, envolvendo qualquer tipo de dispositivo eletrônico que realize processamentos/operações. Apesar de os computadores apresentarem diversas vantagens de uso, eles carregam o peso de serem quase totalmente dependentes e sem iniciativa. – 9 – Fundamentos da programação O que isso quer dizer, na prática? Que ele precisa receber constantemente instruções detalhadas das tarefas que deve realizar, pois do contrário não fará nada. A atuação deles é totalmente dependente de instruções contidas nos chamados programas de computador, também conhecidos como softwares ou aplicativos. Compreender o funcionamento de um computador é relativamente sim- ples, considerando que sua atividade principal é a de processar dados. O usu- ário do computador (ou dispositivo eletrônico) realiza a entrada dos dados, isto é, informa a um programa o que deseja fazer. Para isso, ele normalmente utiliza um dispositivo de entrada, como mouse ou teclado. Em seguida, o computador realiza diversas operações com esses dados, podendo inclusive armazená-los em discos, e criando a possibilidade de utilizações futuras. Por fim, esse processamento gera uma saída, conforme solicitado pelo usuário, a qual pode ser apresentada em um monitor de vídeo, impressora, dentre outros dispositivos de saída. A Figura 1 apresenta de forma gráfica como é o funcionamento do computador. Figura 1: Funcionamento do computador Dados iniciais Processamento dos dados Resposta gerada Dispositivo de entrada CPU/Memória Dispositivo de saída + = Fonte: elaborado pelo autor, 2015. A partir do entendimento de como o computador funciona, fica claro que, mais importante que o equipamento físico em si, são os programas que estão instalados nele e que permitem o seu manuseio pelos usuários. Esses programas precisam ser escritos com uma linguagem acessível, tanto pelo seu desenvolvedor quanto pelo computador, ao qual se dá o nome de linguagem de programação. A criação e disponibilização das linguagens de programa- ção de alto nível permitiram que muitos programas fossem criados para as diversas plataformas de hardware existentes,pois os programadores passaram a ter acesso a ferramentas mais simplificadas para a produção de seus trabalhos. – 10 – Programação de Computadores Em outras palavras, o desenvolvedor escreve o código do seu programa utilizando comandos e instruções que são baseados em uma linguagem natural. Esse agrupamento de comandos pode ser entendido pelo hardware que, posteriormente, se ocupará de sua execução e geração de resultados para os usuários. Para simplificar o entendimento de como ocorre o desenvolvimento de um programa de computador, podemos pensar em um ciclo com três etapas. Na primeira etapa, o objetivo seria levantar as características do problema que o programa pretende resolver, definindo quais serão os dados de entrada, os processamentos necessários e as saídas esperadas. A segunda etapa objetiva construir o chamado “algoritmo”, isto é, descrever o problema (e as soluções apresentadas) em formatos como o português estruturado, a descrição nar- rativa ou o fluxograma. Terminadas essas duas etapas, inicia-se a fase final, na qual o algoritmo especificado é convertido em códigos escritos com uma linguagem de programação previamente definida. Ao final, temos um sof- tware que pode ser instalado em determinado equipamento e utilizado por qualquer pessoa (ou outro sistema) que tenha a necessidade de resolver o problema delimitado inicialmente. Considerando que os algoritmos são a base para a construção dos programas de computador, iremos analisá-los com maiores detalhes no próximo tópico. 1.2 Algoritmos Considerando que diversos autores apresentam conceitos formais dife- rentes sobre os algoritmos, é importante entendê-los como uma sequência finita e sistemática de instruções para resolução de determinado problema. Na prática, o algoritmo se apresenta como um agrupamento de ideias que, executadas de forma metódica, permite encontrar a solução de um problema real. Sobre as instruções que compõem qualquer algoritmo, Xavier (2007) identifica três propriedades que devem ser cumpridas: 2 Precisão: o objetivo de cada uma das instruções do algoritmo deve ser totalmente claro, não permitindo interpretações diversas; 2 Simplicidade: a instrução deve ser simples, ao ponto de qualquer pessoa conseguir executá-la utilizando apenas papel e lápis; – 11 – Fundamentos da programação 2 Finalização garantida: as condições apresentadas pelas instru- ções precisam garantir que o problema seja resolvido quando elas forem satisfeitas. Nas nossas atividades diárias podemos, a todo o momento, criar algorit- mos para auxiliar no entendimento e, principalmente, na resolução dos nos- sos problemas. E isso inclui desde situações mais simples até problemas que, em um primeiro momento, identificamos como de difícil solução. Pense na troca de uma lâmpada. Podemos construir um algoritmo contendo diversas instruções que, após serem executadas, irão gerar como resultado a lâmpada trocada. Veja este exemplo: Algoritmo para troca de lâmpada 2 Tarefa 1: obter uma lâmpada nova. 2 Tarefa 2: pegar uma cadeira ou uma escada. 2 Tarefa 3: colocar a cadeira ou escada embaixo da lâmpada a ser trocada. 2 Tarefa 4: subir na cadeira ou na escada. 2 Tarefa 5: tirar a lâmpada queimada. 2 Tarefa 6: colocar a nova lâmpada. 2 Tarefa 7: descer da cadeira ou escada. 2 Tarefa 8: ligar o interruptor para testar a lâmpada. 2 Tarefa 9: jogar a lâmpada que foi retirada no lixo. 2 Tarefa 10: guardar a cadeira ou escada. Note que para este algoritmo foram definidas dez tarefas, mas isso depende basicamente do nível de detalhamento que necessitamos. Algumas dessas tarefas poderiam ser subdivididas em mais de uma tarefa, aumentando o detalhamento do que deve ser feito. Por outro lado, poderíamos reduzir o tamanho do algoritmo, agrupando tarefas ou até mesmo eliminando aquelas consideradas mais óbvias. Outra observação importante é que um mesmo problema pode ter diversas soluções, ou seja, vários algoritmos podem ser criados para resolver determinado problema, mas sempre gerando a mesma resposta. Neste sentido, – 12 – Programação de Computadores cabe ao usuário avaliar os algoritmos e identificar aquele que melhor se adapta à sua situação. Você sabia? O Google é uma empresa que nasceu a partir da construção de um algoritmo de buscas na internet, o qual vem sendo constantemente aperfeiçoado no intuito de gerar resultados com mais rapidez e relacionados com a pesquisa feita pelos usuários. Para conhecer mais a respeito, acesse os links a seguir: http://www.conversion.com.br/blog/como-funciona-o-algoritmo-do-google/ http://www.seohoje.com/blog/como-funciona-o-algoritmo-de-busca-do-google/ Por se tratar de uma atividade que pode se mostrar bastante complexa, a construção de algoritmos requer a utilização de algumas práticas que facili- tam este processo. Não se trata de uma receita que precisa ser seguida à risca, mas sim de boas práticas utilizadas com frequência nas equipes de programa- ção de computadores. São elas: a) Fazer uma leitura detalhada do enunciado do problema, identifi- cando os pontos principais; b) Identificar quais são os dados de entrada, isto é, aqueles que deve- rão ser fornecidos pelo usuário; c) Compreender o que será processado pelo algoritmo, tendo como base os dados de entrada e o que é necessário para a resolução do problema em questão; d) Identificar quais são os dados de saída, isto é, aqueles que serão gerados pelo processamento; e) Produzir o algoritmo utilizando um formato como o português estruturado, a descrição narrativa ou o fluxograma; f ) Realizar testes no algoritmo para verificar sua aderência ao problema. Considerando que os algoritmos normalmente são representados utili- zando um dos formatos apresentados no item “e” anterior, iremos analisá-los com maiores detalhes no próximo tópico. – 13 – Fundamentos da programação 1.3 Formatos de algoritmos Analisando a literatura relacionada com a construção de algoritmos, existem três formatos mais comuns utilizados: a descrição narrativa, o pseudocódigo, também conhecido como portugol, e o fluxograma. (FOR- BELLONE, 2005) a) Descrição narrativa O objetivo da descrição narrativa é construir um algoritmo que apresente as etapas para resolução do problema em uma lingua- gem natural, por exemplo, a própria língua portuguesa. Neste caso, como a língua natural é sujeita a diversas interpretações, quem estiver construindo o algoritmo deve tomar muito cui- dado para especificar com clareza as suas instruções, diminuindo assim o risco de ocasionar ambiguidades e facilitando a posterior transformação deste algoritmo em um programa de computador. b) Pseudocódigo ou portugol O pseudocódigo (ou portugol, sua forma mais comum de repre- sentação) pode ser entendido, de maneira bem simplificada, como uma forma textual de representação de algoritmos, seguindo para isso determinadas regras predefinidas. O principal ponto positivo deste formato é que a transformação do algoritmo em um programa de computador é facilitada, pois o desenvolvedor necessitará apenas conhecer o conjunto de palavras reservadas (e suas regras de uso) da linguagem de programação escolhida para o software. Por outro lado, o responsável pela construção do algoritmo terá de conhecer as regras do próprio pseudocódigo com o intuito de elaborá-lo de acordo com as convenções mais utilizadas no desenvolvimento de programas de computador. Saiba mais Por se tratar de uma forma mais próxima ao código escrito em uma lingua- gem de programação, o pseudocódigo é muito utilizado em empresas que – 14 – Programação de Computadores desenvolvem softwares. Para otimizar a construção de algoritmos neste formato, é possível utilizar uma ferramenta chamada “Visualg”, capaz de interpretar e executar os algoritmoscriados como se fossem um programa do computador. Download do Visualg: http://sourceforge.net/projects/visualg30/ Manual do Visualg: http://www.inf.ufsc.br/~bosco/ensino/ine5201/ApostilaVisuAlg20.pdf Apostila sobre Visualg: http://www2.joinville.udesc.br/~alp/arquivos/UDESC_Apostila_sobre_ Visualg_2011.pdf c) Fluxograma Considerando que determinadas pessoas têm mais facilidade de entender imagens do que textos, o algoritmo também pode ser construído no formato gráfico, conhecido como fluxograma. É importante ressaltar que os símbolos gráficos utilizados no flu- xograma são predefinidos, de maneira a padronizar os algorit- mos apresentados neste formato. Em comparação com os outros dois formatos apresentados, o fluxograma tem a desvantagem de não apresentar um detalhamento maior das instruções a serem executadas pelo algoritmo, o que pode dificultar a sua transfor- mação em um programa de computador. A Tabela 1 apresenta os símbolos normalmente utilizados em fluxogramas. Tabela 1: Símbolos utilizados em um fluxograma Símbolo Descrição Indica onde começa e termina o algoritmo. Indica instruções de cálculos e atribuição de valores. – 15 – Fundamentos da programação Representa a entrada de dados. Representa a saída de dados. Representa a necessidade de uma tomada de decisão (desvio). Representa o sentido do fluxo de dados, interli- gando os diversos símbolos de um fluxograma. Fonte: elaborado pelo autor, com base em Forbellone (2005). 1.4 Exemplo de algoritmo apresentado nos três formatos Para melhorar seu entendimento sobre a construção de algoritmos, apre- sentamos a seguir exemplos de utilização dos três formatos citados na seção anterior. Para isso, considere a necessidade de construção de um algoritmo muito simples, cujo objetivo é o de exibir o resultado da subtração de dois números. a) Formato “descrição narrativa” Tarefa 1: obter os dois números que serão subtraídos. Tarefa 2: subtrair os números. Tarefa 3: apresentar o resultado final. b) Formato “pseudocódigo” ALGORITMO DECLARE N1, N2, R NUMÉRICO ESCREVA “Informe os dois números” LEIA N1, N2 R ← N1 – N2 ESCREVA “O resultado da subtração é: “, R FIM_ALGORITMO – 16 – Programação de Computadores c) Formato “fluxograma” INÍCIO N1, N2 R = N1 - N2 R FIM Fonte: Elaborado pelo autor, 2015. 1.5 Conceituação de variável É possível afirmar que praticamente todos os algoritmos e programas de computador recebem dados que serão utilizados nas instruções de processa- mento. Em diversos casos, esses dados precisam ser armazenados para usos futuros, isto é, não imediatos. No caso dos equipamentos eletrônicos, o arma- zenamento dos dados acontece no que se convencionou chamar de “memó- ria”. A memória de um computador é organizada como se fosse um armário contendo várias divisões. Cada uma dessas divisões possui um endereço pró- prio que a identifica, permitindo ao computador acessá-la quando necessário. Quando precisamos armazenar algum dado na memória, precisamos criar uma variável, que pode ser entendida como a representação de um espaço da memória do computador. Esta variável, ao ser criada, irá possuir um nome (também chamado de “identificador”) e um tipo de dados, cujas características básicas conheceremos nas seções seguintes deste capítulo. Importante O nome da variável é fundamental em qualquer programa de computador, pois é por ele que buscamos o valor armazenado na memória para a variável. Outras duas características importantes de qualquer variável é que o seu valor pode ser alterado ao longo do tempo, ou seja, durante a execução do software, e o espaço de memória utilizado por ela somente é capaz de alocar um valor a cada momento. – 17 – Fundamentos da programação 1.6 Identificadores Os algoritmos são compostos por diversas variáveis, constantes e rotinas, cada uma identificada por um nome específico, também conhecido como identificador. As regras fundamentais para sua definição são: 2 O caractere sublinhado (_), ou uma letra, necessariamente será o primeiro caractere de um identificador; 2 Podem ser utilizados na definição de um identificador as letras mai- úsculas e minúsculas, os números e o caractere sublinhado; 2 As palavras pertencentes às linguagens de programação (também chamadas de “palavras reservadas”) não podem ser utilizadas como identificadores; 2 Caracteres especiais (como o $, !, @, +, %, -) e espaços em branco não podem ser utilizados. Para que você possa ter uma noção mais clara de quais identificadores são válidos ou não, analise os exemplos a seguir. a) Identificadores válidos: x A1 soma MATRICULA data _ENDERECO nota01 b) Identificadores inválidos: 9y (começa com um número) B 2 (possui espaço em branco entre a letra “B” e o número “2”) a@r (possui um caractere especial) @nota (02) (possui caracteres especiais e um espaço em branco) WHILE (palavra reservada das linguagens de programação) IF (palavra reservada das linguagens de programação) – 18 – Programação de Computadores 1.7 Tipos de Dados Conforme apresentamos na seção 1.5, para que possamos criar uma variável é necessário especificar seu nome (identificador) e o tipo de dados. Nos algoritmos e programas de computador existem alguns tipos de dados mais utilizados, conhecidos como caractere ou literal, numérico e lógico. (XAVIER, 2007) a) Caractere ou literal Compreende os dados formados tanto por apenas um caractere como aqueles compostos de uma cadeia de caracteres. Os valores armazena- dos como caracteres podem ser letras (maiúsculas e/ou minúsculas), números (que não poderão ser utilizados em instruções de cálculos, por serem lidos como caracteres) e caracteres especiais (como %, #, @, &, +, !). Utilizamos aspas simples para indicar o(s) caractere(s) da variável, como pode ser observados nos exemplos a seguir. ‘josé maria da silva’ ‘Avenida Norte Sul, 123’ ‘3 * 4’ ‘(11) 3345-9851’ ‘12345’ b) Numérico O tipo de dados numérico pode ser subdividido em inteiros e reais. Os números inteiros não apresentam parte decimal, ao con- trário dos números reais, sendo que ambos podem ser negativos ou positivos. É importante salientar que quando um valor do tipo real é armazenado no computador, ele consome mais memória do que se fosse declarado como inteiro, daí a importância de definirmos corretamente o tipo de dados de cada variável do nosso algoritmo. Exemplos de valores inteiros: 100 -55 1299 -777 20 – 19 – Fundamentos da programação Exemplos de valores reais: 3.14 95.43 -120.01 750.0 -4.0 Importante Como os números reais adotam a notação inglesa, a separação entre a parte decimal e a inteira deve ser feita com um ponto, e não com uma vírgula, como estamos acostumados no Brasil. c) Lógico O tipo de dados lógico é considerado o mais simples, pois essa vari- ável somente pode assumir os valores falso ou verdadeiro. Estes dados também são conhecidos como booleano, pois é baseado na álgebra de Boole. Álgebra de Boole: é um sistema utilizado em operações lógi- cas, colocando o raciocínio lógico de forma matemática que pode assumir apenas duas possibilidades, verdadeiro ou falso. Resumindo A programação de computadores é uma complexa área de conhecimento, que demanda domínio tanto dos equipamentos que serão utilizados quanto das técnicas a serem empregadas na construção de programas. Neste capítulo, analisamos os fundamentos relacionados com a programação de computa- dores e estudamos as características básicas do algoritmo, estrutura funda- mental para a construção de softwares. É possível afirmar que um algoritmo construído adequadamente facilita sobremaneira o trabalho do desenvolvedor que deverá transformá-lo em um programa executável de computador. Neste capítulo, faremos um brevehistórico sobre a evolu- ção da programação de computadores para, posteriormente, apre- sentar as principais características da programação estruturada e da orientada a objetos. Entendendo que esses dois paradigmas conti- nuam sendo os mais utilizados atualmente, em especial o orientado a objetos, torna-se fundamental conhecer melhor suas particulari- dades. Ao final, promoveremos um comparativo entre os paradig- mas, possibilitando que você compreenda quais os pontos positivos e negativos de cada um deles. 2 Características das Linguagens Orientadas a Objetos Programação de Computadores – 22 – Paradigma: consiste em um modelo ou padrão a ser seguido em situações específicas. Objetivos de aprendizagem: 2 Apresentar as bases históricas da programação de computadores; 2 Conhecer as características dos paradigmas de programação estru- turado e orientado a objetos; 2 Compreender como é o processo de codificação do sistema em cada um desses paradigmas de programação; 2 Comparar as características da programação orientada a objetos frente à programação estruturada. 2.1 Histórico da programação de computadores Nos primórdios da computação, o item mais valioso era o hardware, ou seja, os equipamentos eletrônicos utilizados principalmente para proces- samentos de cálculos matemáticos. Apenas algumas grandes organizações tinham recursos financeiros suficientes para adquirir os computadores da época, que além de ocuparem um espaço físico muito grande, eram extrema- mente difíceis de manusear e manter. Neste contexto, o software era apenas um “auxiliar” direto do hardware. (FONSECA FILHO, 2007) A partir do momento em que os componentes eletrônicos foram sendo melhorados e seu custo reduzido, um número maior de softwares podia ser instalado e executado nos computadores. A própria evolução das empresas passou a criar novas demandas que até então não existiam, como gestor de folha de pagamento e contas a pagar e receber das empresas. Assim, nasce a indústria do software, responsável por criar soluções tecnológicas que objeti- vam tanto resolver problemas (profissionais e pessoais,) quanto melhorar o gerenciamento das organizações como um todo. – 23 – Características das Linguagens Orientadas a Objetos A criação e o desenvolvimento das linguagens de programação estão diretamente ligados a essa evolução das tecnologias de software e também do hardware. Com o aumento da capacidade de processamento dos computado- res, diversos problemas considerados mais complexos passaram a ser resolvi- dos com o apoio de programas específicos, os quais eram escritos inicialmente em linguagem de máquina, muito complexa e difícil de aprender. Os especia- listas então começaram a desenvolver novas linguagens de programação mais acessíveis e simples, como podemos notar no breve histórico apresentado a seguir. (FONSECA FILHO, 2007) 2 Década de 1940: a codificação de programas era feita totalmente com códigos escritos na linguagem da máquina, o que demandava profissionais com pleno conhecimento do hardware. 2 Década de 1950: nesta época, foram desenvolvidas linguagens de programação que ficaram conhecidas como de “1ª geração”, cuja característica principal era a programação lógica, onde ocorria abstração do hardware utilizado. A ênfase dos programas desen- volvidos nesta época era nos cálculos numéricos. Fortan e List são exemplos de linguagens desenvolvidas nesta época. 2 Década de 1960: as linguagens desta época (conhecidas como de “2ª geração”) focavam diretamente o processamento de dados colhidos dentro das organizações, como, por exemplo, de siste- mas bancários e financeiros. Algol, Basic e Cobol são exemplos de linguagens de 2ª geração. 2 Década de 1970: a ênfase das linguagens desta época (conheci- das como de “3ª geração”) era na criação de uma estrutura para o código-fonte dos programas elaborados, que viria a ser futuramente denominada de “programação estruturada”. Como exemplos pode- mos citar a Linguagem C, o Pascal e a Simula, considerada a lin- guagem pioneira no suporte ao conceito de classes. A Figura 1, a seguir, apresenta de forma gráfica a evolução das lingua- gens de programação desde a década de 1950, especificando o nome das lin- guagens utilizadas em cada época. Programação de Computadores – 24 – Figura 1: Evolução das linguagens de programação 50 60 70 80 90 Imperativo Orientado por Objetos Funcional Lógico Fortran Cobol Lisp PrologAlgol 60 PL/1 Simula Smaltalk Pascal C ML Miranda Haskell Modula Oberon C++ Ada Eiffel Java Fonte: Trancoso, 2010. Saiba mais Como o objetivo principal deste capítulo é abordar as características princi- pais da programação estruturada e da programação orientada a objetos, foi destacada a evolução das linguagens até a década de 1970. Acesse os links e saiba mais a respeito desta evolução. História das Linguagens de Programação http://www.ppgia.pucpr.br/~alekoe/APB/Historia-Justino.pdf Mapa com a evolução das linguagens de programação http://www.levenez.com/lang/lang.pdf – 25 – Características das Linguagens Orientadas a Objetos Saiba mais A forma de comunicação com o computador precisa seguir uma série de padrões, isto é, todas as instruções que desejamos que ele execute precisam ser escritas em uma linguagem que ele compreenda, chamada de linguagem de máquina. Para conhecer mais a respeito e a sua importância para a com- putação moderna, acesse os links a seguir. http://elemarjr.net/2013/09/11/linguagem-de-maquina/ ht tp://blog in fogeeks.b logspot.com.br/2011/03/ l inguagem-de- -maquina-como-o-computador.html http://www.projetostecnologicos.com/cursos/programacao/Introducao/ Linguagem-de-maquina.html 2.2 Programação estruturada De maneira simplificada, podemos entender a programação estrutu- rada como uma forma de elaboração de programas que invariavelmente podem ser visualizados sob três estruturas básicas de controle: sequência, condição e iteração. A sequência mostra que nos programas estruturados uma instrução é executada logo após a outra. Já a condição indica que determinadas condições deverão ser satisfeitas dentro do programa para que outras instruções possam ser executadas. Por fim, a iteração apresenta um bloco de instruções que são executadas repetidamente por um número finito de vezes. (DEITEL e DEITEL, 2011) O propósito de se utilizar essas estruturas dentro de um algoritmo, ou de um programa de computador, é tornar o código mais legível, aumentando consequentemente sua compreensão pelos desenvolvedores e demais interessados. Espera-se que com o uso dessas estruturas não seja utilizado um recurso comum em linguagens de 2ª geração chamado “GO TO”, o qual permitia o desvio da execução de um programa de computa- dor de uma parte do código para outra, e assim sucessivamente, criando um grande descontrole na ordem do código-fonte. Programação de Computadores – 26 – Outra característica fundamental da programação estruturada é a subpro- gramação, também conhecida como modularização. À medida que o código- -fonte do programa aumenta, normalmente em função da implementação de novas funcionalidades, a complexidade também sofre mudanças, podendo oca- sionar dificuldades de manutenção do código para os programadores. A pro- gramação estruturada entende que quando o programa começa a ficar muito extenso, é melhor dividí-lo em partes menores, chamadas subprogramas ou funções, facilitando o gerenciamento das unidades de código. Esses subpro- gramas serão executados a partir de outro código e resolverão uma parte do problema maior; quando todos os subprogramas forem executados, espera-se que todo o problema tenha sido resolvido. (MIZRAHI, 2006) Esta técnica de subdivisão do programa apresenta diversas vantagenstais como: 2 Proporciona maior simplicidade em todo código-fonte; 2 Melhora a legibilidade do código elaborado pelo programador; 2 Aumenta a facilidade de manutenção do programa, seja para corre- ção de erros ou para implementação de novas rotinas; 2 Possibilita a divisão das tarefas de desenvolvimento (cada programa- dor pode ser responsável por desenvolver um subprograma diferente); 2 Permite o reuso de subprogramas em outros programas (no caso da Linguagem C, isso é feito com o uso de cabeçalhos). Cabeçalhos: do inglês headers, indicam que deter- minado programa irá utilizar funções previamente construídas em outra unidade de código, facilitando assim o reaproveitamento de instruções prontas. A partir do momento que criamos uma série de subprogramas, precisa- mos definir como será feita a comunicação entre eles. Por exemplo, se existisse uma função específica para calcular o salário de determinado funcionário, o que ela deveria fazer com o valor final calculado? Devolver o valor calcu- lado para quem fez a chamada à função ou imprimí-lo na tela do usuário? Esse tipo de definição é fundamental em qualquer programa estruturado, – 27 – Características das Linguagens Orientadas a Objetos pois pode impactar diretamente na sua performance. Uma possibilidade é a utilização de variáveis globais que atuariam no armazenamento de valores utilizados/calculados pelas funções, porém, devido ao seu escopo ser muito grande, essa solução passa a não ser recomendada. As técnicas mais comuns para lidar com esse intercâmbio de dados são a passagem de parâmetros de entrada nas funções, muitas vezes por referência, e o retorno pela própria função de determinado valor. Importante O tipo de desenvolvimento aplicado pela programação estruturada é conhecido como top-down, isto é, primeiramente são desenvolvidas as funções mais abs- tratas do sistema para, em seguida, serem elaboradas as funções mais específicas. Para compreender melhor como o código-fonte é construído na progra- mação estruturada, analise o algoritmo apresentado a seguir, responsável pelo simples cálculo da soma de dois números. ROTINA DECLARE valor1, valor2, resultado NUMERICO LEIA valor1 LEIA valor2 resultado = valor1 + valor2 ESCREVA resultado FIMROTINA Agora iremos converter este algoritmo em código com- putacional tendo como base a Linguagem C, considerada como um dos principais exem- plos de programação estrutu- rada. Confira na Figura 2 como seria este código. Observe os detalhes de como essa conversão aconteceu, e Figura 2 - Código-fonte de um programa para somar dois números. Fonte: Elaborado pelo autor, 2016. #include <studio.h> #include <conio.h> main (){ int valor1, valor2, resultado; scanf (“%d”, &valor1); scanf (“%d”, &valor2); resultado = $valor1 + valor2; printf (“%d”, &resultado); } Programação de Computadores – 28 – note que o código-fonte final elaborado em Linguagem C possui uma estrutura muito similar ao algoritmo. No código-fonte também podemos perceber a utilização do conceito de funções da programação estruturada, denomi- nada aqui de “main()”. Como falamos anteriormente, cada instrução deste código será executada de uma vez, na sequência que é apresentada. Sendo assim, primeiramente as variáveis são declaradas (valor1, valor2 e resultado), o programa faz a leitura dos dois números a serem somados e armazena os valores informados pelo usuário nas respectivas variáveis (valor1 e valor2), o resultado é calculado com base na soma dos valores das duas variáveis e, por fim, é exibido na tela. Código-fonte: é o conjunto de instruções (basea- das em uma linguagem de programação) que for- mam um programa de computador ou software. 2.3 Programação orientada a objetos 2.3.1 Histórico Uma das principais reclamações dos especialistas na área de desenvolvi- mento de softwares é que a programação estruturada não conseguiu resolver os problemas relacionados com a baixa produtividade da equipe e a quali- dade dos sistemas produzidos. Se considerarmos as características dos softwares atuais, com frequente interação com os usuários e uso de interfaces gráficas aprimoradas, bem como demandas constantes de alterações e adaptações nas funcionalidades já em funcionamento, torna-se complicado equilibrar difi- culdades de produtividade e qualidade com o desenvolvimento de um pro- duto com esses aspectos. (SINTES, 2002) Diversas pesquisas mostram que a chave para tentar resolver esses pro- blemas de produtividade e qualidade do software está diretamente vinculada com o conceito de reutilização. De maneira simples, podemos entender a reutilização como o uso de alguma coisa que já está pronta. No caso dos programas de computador, a proposta seria reutilizar o máximo possível de determinado código-fonte já elaborado. Esse tipo de estratégia consegue, na prática, aumentar a produtividade da equipe de desenvolvimento, pois como – 29 – Características das Linguagens Orientadas a Objetos diversas rotinas serão reaproveitadas de outro código-fonte, o tempo que seria gasto nessa tarefa pode ser dispendido em outras atividades. Como as técnicas propostas pela programação estruturada não conse- guiam melhorar os resultados do processo de desenvolvimento de softwares, surgiu uma nova forma de se elaborar os programas de computador, denomi- nada de programação orientada a objetos. 2.3.2 O paradigma orientado a objetos A ideia básica da orientação a objetos é promover uma representação fiel das situações reais no mundo computacional. Considerando que, de acordo com nosso entendimento, o mundo é composto de diversos objetos que estão em constante interação com outros objetos, a orientação propõe entender os sistemas computacionais como uma coleção deles que interagem entre si, e não como um conjunto definido de processos e instruções sequenciais. (COELHO, 2013) Nos programas orientados a objetos as instruções são organizadas em módulos responsáveis por agrupar determinado estado, e as operações que incidem sobre ele. Em outras palavras, são definidas estruturas em conjunto com diversas operações que atuam sobre essas estruturas. Como exemplo prá- tico, imagine uma estrutura para armazenar dois números e operações que utilizam esses valores, tais como as quatro operações básicas da matemática. Winck e Goetten Júnior (2006) afirmam que o paradigma orientado a objetos permitiu transportar para dentro deles o estado atual do sistema, isto é, os objetos do sistema têm capacidade de simular a realidade a partir do armazenamento do estado momentâneo do sistema. Para que isso fosse pos- sível, a orientação utilizou um conceito denominado de “visibilidade”, cuja proposta é definir o grau de acesso das propriedades e métodos (operações) de uma estrutura. Desta maneira, é possível restringir o acesso direto às partes que compõem esta estrutura e, de maneira direta, ao seu estado. Importante A grande adesão ao paradigma orientado a objetos aconteceu principal- mente em função de ela possibilitar a modelagem e o projeto de um software assim como um problema do mundo real é analisado. Programação de Computadores – 30 – Para compreendermos melhor como funciona, é necessário analisar os requisitos básicos para que uma linguagem de programação “pertença” a este paradigma. a) Abstração Podemos afirmar que a abstração é o ponto principal de qualquer linguagem de programação orientada a objetos. Conforme vimos anteriormente, estamos trabalhando com a representação de um objeto do mundo real no ambiente computacional, o que faz com que tenhamos que imaginar quais as características deste objeto e quais ações ele pretende executar no nosso software. Sendo assim, inicialmente precisamos definir a identidade do objeto que será criado no nosso sistema.Importante salientar que esta identidade precisa ser única, evitando a ocorrência de confli- tos com outros objetos. A título de exemplo, considere que um objeto do nosso sistema terá a identidade “Carro”. Em seguida, é necessário especificar as características próprias dele, isto é, quais elementos que definem este objeto. No caso da programação orien- tada a objetos, elas são chamadas de propriedades. Considerando o nosso “Carro”, podemos relacionar diversas propriedades que o delimitam, como marca, modelo, ano de fabricação, cor, etc. Por fim, é preciso definir as ações que ele poderá executar dentro do sistema. A programação orientada a objetos trata essas ações como métodos. O objeto carro poderia estar relacionado com métodos denominados “Ligar”, “Acelerar” e “Frear”. b) Encapsulamento Outra técnica fundamental para a programação orientada a objetos é conhecida como encapsulamento, que consiste em uma forma de “esconder” o acesso direto às propriedades de um objeto para pro- porcionar maior segurança. Por exemplo, imagine a propriedade “ano de fabricação” do objeto “Carro”, definido anteriormente. Se ela não for protegida, o usuário poderá atribuir qualquer valor a ela, como, por exemplo, 31/02/2000 (o mês de fevereiro não pode ter 31 dias). – 31 – Características das Linguagens Orientadas a Objetos Para resolver este tipo de situação, as linguagens orientadas a obje- tos implementam o encapsulamento com base na declaração de propriedades privadas, as quais não permitem acesso direto do usu- ário. Para que isso aconteça, são criados métodos especiais respon- sáveis tanto por preencher o valor de uma propriedade, quanto por retornar o valor atual atribuído a ela. Neste caso, as validações dos valores informados pelo usuário são feitas dentro desses métodos especiais. Resumindo, a proposta é que o usuário não tenha acesso direto aos dados do objeto, mas sim por intermédio dos métodos. Analise a Figura 3 para compreender melhor este relaciona- mento existente entre o usuário, os métodos especiais e os dados de um objeto. É possível notar que o usuário faz uma chamada aos métodos por meio de uma interface do software e os méto- dos fazem as manipulações necessárias nos dados. Figura 3 - Acesso aos dados por meio da execução de métodos. INTERFACE Métodos Dados Fonte: Elaborado pelo autor, com base em Sintes, 2002. c) Herança Diversos especialistas afirmam que uma das principais vantagens da programação orientada a objetos é sua grande capacidade de proporcionar reaproveitamento de código. Na prática, isso é possível graças a um meca- nismo conhecido como herança, o qual proporciona considerável aumento na produtividade de softwares. A maneira mais simples de entendermos este conceito é pensando em uma família. O filho herda de seus pais determinadas características; os pais também herdam algumas características de seus avós, fazendo com que o filho também herde estas características. Esse relacionamento acontece de forma Programação de Computadores – 32 – sucessiva, como, por exemplo, no caso do nascimento de um bisneto dos avós citados. Analise a Figura 4 que mostra um relacionamento de herança entre dois objetos (1 e 2) e a possibilidade de aumentar estes relacionamentos para n objetos. Figura 4 - Relacionamento de herança. ... Objeto 1 Objeto 2 Objeto N Fonte: elaborado pelo autor, adaptado de Lee e Tepfenhart, 2001. No paradigma orientado a objetos entendemos que o objeto logo abaixo na hierarquia herdará as características de todos os seus ancestrais, isto é, de todos os objetos que estiverem acima dele. Daí surge o conceito de herança direta e indireta. Quando analisamos a herança do Objeto 2 para o Objeto 1, dizemos que existe uma herança direta. Porém, se logo abaixo do Objeto 2 existisse outra herança para um Objeto 3, diríamos que existe uma herança indireta entre o Objeto 3 e o Objeto 1. Importante A implementação da herança varia dependendo da linguagem de programa- ção utilizada. A Linguagem C++, por exemplo, oferece a possibilidade de um objeto herdar ao mesmo tempo as características de diversos ancestrais, fazendo com que um objeto filho possua quantos objetos pais forem precisos. Quando isso ocorre, afirmamos que existe uma herança múltipla. Por outro lado, outras linguagens não permitem a codificação de heranças múltiplas dire- tas, mas sim por meio do recurso de interfaces. – 33 – Características das Linguagens Orientadas a Objetos Polimorfismo A quarta característica principal do paradigma orientado a objetos é cha- mada de polimorfismo, que consiste na capacidade de cada objeto alterar sua forma mediante condições do ambiente. Conforme vimos no tópico anterior, o objeto filho herda as ações e características de seu(s) ancestral(is), porém em deter- minadas situações é preciso que a ação executada para um mesmo método tenha resultados diferentes. Em termos práticos, o polimorfismo é a técnica que possibi- lita mudar a forma de atuação interna de métodos herdados de objetos ancestrais. A Figura 5, a seguir, apresenta o relacionamento entre um objeto genérico chamado “Aeronave” e dois objetos filhos chamados “Avião” e “Helicóptero”. Figura 5 - Herança envolvendo três objetos. Aeronave Avião Helicóptero Fonte: elaborado pelo autor, 2015. Agora imagine que o objeto genérico “Aeronave” possui um método chamado “Acelerar”. Como os objetos “Avião” e “Helicóptero” herdam da “Aeronave”, eles também possuirão um método específico para acelerar. Porém, a forma de aceleração do “Avião” é diferente da forma do “Heli- cóptero”, o que faz com que tenhamos que reescrever o método “Acelerar” em cada uma das classes filhas. Sendo assim, as classes “Avião” e “Helicóp- tero” são consideradas polimórficas, pois irão mudar a forma de atuação do método herdado de seu ancestral. 2.3.3 Exemplos de linguagens de programação orientadas a objetos Dentre as diversas linguagens de programação que implementam as características do paradigma orientado a objetos, podemos destacar C++, Java, C#, Python e PHP. Programação de Computadores – 34 – Você sabia? Cada linguagem de programação possui sua própria história, envolvendo desde sua definição, criação, validação e disponibilização para uso geral. Algumas possuem um número maior de usuários ao redor do mundo, outras têm atuação mais focada em nichos. Acesse os links a seguir e conheça um pouco mais sobre a história das principais linguagens de programação orientadas a objetos. Histórico da linguagem Java http://www.devmedia.com.br/java-historia-e-principais-conceitos/25178 Histórico da linguagem C++ http://www.targettrust.com.br/blog/desenvolvimento/c-historia/ Histórico da linguagem Python http://mindbending.org/pt/a-historia-do-python Ranking de utilização de linguagens/plataformas de programação http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html 2.4 Comparativo entre a programação estruturada e a programação orientada a objetos Para finalizarmos o entendimento sobre esses dois importantes paradig- mas de programação, iremos promover um pequeno comparativo entre eles, enfocando aspectos mais práticos. Entretanto, tenha sempre em mente que não existe genericamente um paradigma melhor que o outro, mas sim um que melhor se adapta à determinada situação. No que se refere à reutilização de código, tanto a programação estru- turada, quanto a orientada a objetos, auxiliam o desenvolvedor a aproveitar partes já prontas de códigos. Entretanto, em função de seu caráter sequencial, determinados códigos produzidos em programação estruturada não podem ser efetivamente reutilizados sem a necessidade de clonar o código em locais diferentes, o que pode ocasionar dificuldades de manutenção e duplicidade – 35 – Característicasdas Linguagens Orientadas a Objetos de funcionalidades. A reutilização na programação orientada a objetos é faci- litada pela implementação do mecanismo de herança, que permite controlar inclusive o que pode ser herdado a partir de um ancestral. Sobre a estruturação do código, a programação estruturada tende a construir códigos misturados, isto é, o tratamento dos dados do programa é feito juntamente com instruções sobre o seu comportamento. Isso pode causar sérios problemas na manutenção de entendimento do sistema como um todo. Já o código produzido com base nas técnicas da orientação a objetos tende a ser mais organizado e bem dividido, contribuindo diretamente para sua legibilidade e qualidade. Além disso, como a orientação a objetos produz representações de sistemas próximos com o que vemos no mundo real, a com- preensão de cada parte e do seu todo fica muito mais simplificada. Em termos de desempenho, pelo fato de trabalhar com instruções mais próximas à linguagem da máquina e não possuir tantos desvios na execu- ção, os programas elaborados com linguagens de programação estruturada são relativamente mais rápidos em comparação àqueles feitos com orientação a objetos. Contudo, como o hardware disponível atualmente na maioria dos dispositivos possui grande poder de processamento, essa diferença de desem- penho dificilmente será sentida por um usuário comum. Resumindo A definição de qual paradigma de programação e, consequentemente, de qual linguagem de programação será utilizada em um projeto de desenvol- vimento de software é fundamental para aumentar suas chances de sucesso. Neste capítulo, analisamos as principais características da programação estru- turada e da orientada a objetos, bem como promovemos uma objetiva com- paração entre pontos positivos e negativos dessas duas abordagens. Não se trata de qual paradigma é mais vantajoso, mas sim de qual deles é o mais viável e aderente à necessidade que se apresenta. Neste capítulo, abordaremos um dos principais conceitos utilizados na programação orientada a objetos: as classes. Como trata-se da mais importante estrutura deste paradigma de progra- mação, é fundamental que todos os elementos que compõem uma classe sejam compreendidos, em especial, os atributos e métodos. Além disso, como o conceito de objetos está diretamente relacio- nado com o de classes, ele também é analisado neste capítulo. Em relação à prática, são apresentados códigos básicos para a definição de classes na Linguagem C++. 3 Classes Programação de Computadores – 38 – Objetivos de aprendizagem: 2 Apresentar os conceitos fundamentais da programação orientada a objetos; 2 Compreender as características básicas dos principais elementos da orientação a objetos; 2 Diferenciar objetos e classes; 2 Identificar a importância da correta definição das classes para o projeto; 2 Utilizar a Linguagem C++ para elaborar o código responsável pela declaração de classes, objetos, atributos e métodos. 3.1 Conceitos fundamentais da programação orientada a objetos O objetivo principal da programação orientada a objetos é elaborar uma representação fiel das diversas situações do mundo real em um sistema com- putacional. Assim, como as pessoas compreendem o mundo sendo composto de objetos que realizam constantes interações com outros objetos, a orienta- ção visa analisar os sistemas de computação como uma coleção de objetos que interagem entre si, e não apenas como um conjunto estruturado de processos. (COELHO, 2013) Considerando que tanto a programação estruturada quanto a programa- ção orientada a objetos possibilitam a especificação de estruturas e a execução de operações sobre elas, é possível afirmar que o grande diferencial da orienta- ção a objetos é sua aplicação do conceito de herança, técnica pela qual pode- mos promover efetivamente o reaproveitamento de código em um sistema computacional. Em conjunto com a herança, outra característica fundamen- tal da orientação a objetos é o polimorfismo, mecanismo pelo qual o sistema pode atuar de formas variadas ao longo de sua existência (SINTES, 2002). Estruturas em programação: são entendidas como conjun- tos de instruções/códigos que possuem algum relacionamento – 39 – Classes direto. No caso da programação orientação a objetos, uma das principais estruturas existentes é conhecida como classe, em que são declarados os atributos e métodos de determi- nado modelo. No caso da programação estruturada, existem formas específicas de criação de estruturas de dados, as quais podem ser compostas por variáveis de diversos tipos. Saiba mais Existem diversos outros paradigmas de programação além do estru- turado e do orientado a objetos. Uma tendência observada no mer- cado de tecnologia indica que o paradigma orientado a aspectos proporciona grandes benefícios aos desenvolvedores, especialmente nas situações em que partes de um sistema estão constantemente afetando outras partes já estabelecidas. Para saber mais a respeito da programação orientada a aspectos, acesse os links a seguir: http://aspect-oriented.awardspace.com/desvpoa.html http://www.javaframework.org/portal/2010/04/14/o-que-progra- mao-orientada-a-aspectos/ Iremos analisar os principais conceitos que fazem parte da progra- mação orientada a objetos, utilizando para isso exemplos práticos que facilitarão o entendimento. 3.1.1 Objetos No contexto da programação orientada a objetos, o termo “objeto” é utilizado para fazer a representação de algum item ou elemento específico do mundo real. Entretanto, como os sistemas computacionais precisam ser objetivos e concisos, é importante que sejam analisados apenas aqueles que apresentem importância para auxiliar na resolução do problema em questão. (DEITEL e DEITEL, 2011) Programação de Computadores – 40 – Importante Podemos conceituar formalmente o termo “objeto” como sendo uma enti- dade do mundo real que necessita ser representada no ambiente que será programado. (DEITEL e DEITEL, 2011) Os objetos também são entendidos como instâncias de classes, as quais especificam as informações que determinado objeto possui e como ele poderá manipulá-las. Sendo assim, os objetos têm a habilidade de guardar um estado (como se fosse uma informação) e acessar um conjunto de operações (com- portamentos) que podem ou não alterar este estado. (SINTES, 2002). No caso dos sistemas construídos com base nas linguagens de programação orientadas a objetos, esta é a forma mais comum de executar o processa- mento de informações. Instância de classe: Trata-se de um objeto criado a partir de determinada classe, ou seja, é a representação da classe. É a instância/objeto que possuirá dados armazenados e poderá executar métodos, e não a classe, pois esta funciona ape- nas como um modelo para criação de novos objetos. Alguns exemplos práticos de objetos: 2 Objetos físicos: computador, monitor, carro, avião, armário, mesa, cadeira, caneta, lápis. 2 Funções em sistemas computacionais representadas por pes- soas: funcionário, atendente, vendedor, aluno, professor, cliente, comprador, gerente. 2 Eventos: venda, compra, login no sistema, empréstimo, devolução, consignação, lançamento de notas, emissão de nota fiscal. 2 Lugares: filial, matriz, unidade sul, reitoria, campus. 2 Interações entre objetos: o exemplar de um livro a ser emprestado pelo atendente de uma biblioteca pode ser entendido como uma interação entre objetos. – 41 – Classes Para complementar este entendimento sobre objetos, vamos analisar o objeto “carro”, representado pela Figura 1 abaixo. Ao analisarmos a Figura 1 é possível notar que o objeto “carro” possui determinadas características específicas, isto é, que pertencem a apenas este objeto representado nesta figura, taiscomo: 2 Marca; 2 Modelo; 2 Ano de fabricação; 2 Cor; 2 Preço; 2 Chassi. Importante No contexto da programação orientada a objetos, as informações que des- crevem ou caracterizam um objeto são chamadas de atributos. A partir da análise de nosso conhecimento básico sobre qualquer objeto “carro”, é possível listarmos suas características como identificarmos uma série de ações que ele pode executar, tais como: 2 Ligar; 2 Acelerar; 2 Frear; 2 Parar; 2 Movimentar volante; 2 Alterar marcha. Figura 1 - Imagem de um carro representando um objeto. Fonte: Shutterstock, 2016. Programação de Computadores – 42 – Importante No contexto da programação orientada a objetos, os eventos ou ações que um objeto pode executar são chamados de métodos. Diferentemente da programação estruturada, na programação orien- tada a objetos a única forma de acontecer interação entre os objetos e, por consequência, mudanças em seus estados, é por meio da execução de métodos disponibilizados pelos objetos envolvidos. Por exemplo, para interagirmos com o objeto “carro”, especificado anteriormente, utilizamos os métodos que ele disponibiliza. Se quisermos que ele comece a funcionar, uti- lizamos o método “Ligar”; se quisermos que ele mude a marcha atualmente selecionada, usamos o método “Alterar marcha”; se quisermos que ele pare completamente, utilizamos o método “Parar”; e assim por diante. Importante No contexto da programação orientada a objetos, a coleção de métodos que são disponibilizados por ele é chamada de interface. Conforme tratamos, cada objeto possui um conjunto de atributos e métodos que o caracterizam perante outros objetos do sistema computacio- nal. Porém, é preciso entender de forma mais detalhada o que são atributos e quais os métodos para a orientação. a) Atributos Todos os objetos existentes no mundo real apresentam caracterís- ticas, que, por sua vez, possuem valores definidos. São justamente esses valores que definem qual o estado de determinado objeto. No caso da orientação a objetos, essas características recebem a deno- minação de atributos. Na prática, podemos entender os atributos dos objetos como se fossem “variáveis” responsáveis por guardar os possíveis valores que cada característica de um objeto pode conter. Sendo assim, – 43 – Classes o estado do objeto é definido pela coleção de valores que seus atributos possuem em determinado momento, e o comporta- mento indica como o objeto atua quando ocorre uma mudança de estado (SINTES, 2002). Estado do objeto: Indica a situação atual de determi- nado objeto, sendo baseada no valor dos atributos dele. Agora, imagine que o nosso sistema computacional precise gerenciar os dados de diversos carros localizados em um estacionamento. Cada um desses carros estacionados neste local é considerado pelo sistema como um objeto, sendo que todos eles possuem os mesmos atributos, porém os valores são diferentes para cada um deles. Alguns valores podem até se repetir, por exemplo, se tivermos dois carros de uma mesma marca ou com uma mesma cor, dependeremos de outros atributos que consigam diferenciar um modelo do outro, como o chassi. Veja nas tabelas a seguir a representação de quatro carros (objetos) localizados neste estacionamento. Tabela 1: Exemplos de objetos da classe “Carro” Objeto: carro1 Marca Fiat Modelo Palio Ano de fabricação 2014 Cor Preto Preço R$39.900,00 Chassi 11AD8948OP Programação de Computadores – 44 – Objeto: carro2 Marca Ford Modelo Focus Ano de fabricação 2012 Cor Prata Preço R$31.450,00 Chassi 23BB3379XP Objeto: carro3 Marca Fiat Modelo Uno Ano de fabricação 2015 Cor Azul Preço R$45.500,00 Chassi 56NY3309UT Objeto: carro4 Marca Chevrolet Modelo Prisma Ano de fabricação 2014 Cor Prata Preço R$42.000,00 Chassi 99BE1227LL Fonte: elaborado pelo autor, 2015. Para finalizar o entendimento das características básicas dos atribu- tos, é importante ressaltar que, de acordo com a programação orientada a objetos, a forma adequada de alterar o valor armazenado em um atributo do objeto é executando um método do próprio objeto que irá realizar esta transição de estado. – 45 – Classes b) Métodos De maneira simplificada, podemos compreender os métodos como todas as ações que determinado objeto pode executar dentro do contexto de um sistema computacional. Na prática, tudo aquilo que o objeto realiza no sistema, desde a atribuição de valor para um atributo até a interação com outro objeto, é a partir de um método. Utilizando os termos mais comuns da programação estruturada, os métodos também são conhecidos como funções ou procedimentos, isto é, um conjunto de instruções que visam, principalmente, a manipulação do estado de um objeto. Considerando o exemplo de um objeto “carro“, apresentado ante- riormente, podemos especificar diversos métodos ou ações que ele poderia executar quando fosse necessário. Por exemplo, no momento da criação deste objeto, o método “Ligar” seria execu- tado, indicando que o carro foi ligado e está pronto para receber novas instruções. Em seguida, o objeto poderia executar o método “Acelerar”, para que ocorresse sua movimentação. Quando fosse necessário, haveria uma chamada ao método “Frear” para que o objeto apenas reduzisse sua velocidade, ou ao método “Parar”, para que ele parasse completamente. O método “Movimentar volante” seria bastante executado, tendo em vista que este comportamento é fundamental para a correta utilização do carro. 3.1.2 Classes Em um sistema computacional desenvolvido sob o paradigma da orien- tação a objetos, o conceito de classe indica que ela é responsável por represen- tar uma coleção de objetos com características e comportamentos similares. Um objeto, então, é a representação de determinada classe, isto é, ele possui toda a estrutura (atributos e métodos) pertencente à classe da qual faz parte. (DEITEL e DEITEL, 2011) Ao analisarmos os objetos “Carro” apresentados na seção anterior, é pos- sível notar que todos possuem atributos iguais, indicando que pertencem a uma mesma classe. Em outras palavras, se eles possuem coleção de atributos e métodos iguais, quer dizer que são objetos criados a partir de uma mesma Programação de Computadores – 46 – classe. É importante ressaltar que, apesar de todos os objetos possuírem os mesmos atributos, os valores desses atributos em cada um dos objetos podem ser diferentes, pois eles se referem a carros diferentes na vida real, cada um com suas próprias características. É neste contexto que podemos notar a importância do conceito de instância de classe; como cada objeto criado é uma instância independente da classe, seus valores de atributos não se mistu- ram com os valores de atributos de outro objeto/instância. Pensando em termos de análise orientada a objetos, a conceituação de classe indica que ela é uma coleção de instruções de programação que defi- nem os atributos e métodos requeridos para criarmos um ou mais objetos. Pensando em termos mais amplos, podemos compreender uma classe como sendo o local onde toda forma do objeto está descrita, isto é, ela é um modelo para criação de diversos objetos. Por este motivo, anteriormente dissemos que um objeto é uma instância de determinada classe. É válido salientar que a própria estrutura da linguagem de programação orientada a objetos faz com que cada um que for criado possua uma referência implícita à sua classe de origem, possibilitando saber a qual ele pertence (SINTES, 2002). Análise orientada a objetos: consiste em um processo de produção de sistemas baseado no entendimento de que existem diversas interações entre objetos e que são justamente essas cone- xões as responsáveis pela execução de tarefas computacionais.É importante ressaltar que as classes são apenas as definições do for- mato dos objetos do sistema, não existindo na realidade. Conforme abor- damos anteriormente, apenas os objetos existem, pois são as representa- ções das classes nos sistemas computacionais. Quando um novo objeto é criado, tendo uma classe como base, entende-se que ocorreu uma “ins- tanciação” do objeto. A Figura 2 apresenta os quatro objetos da classe “Carro” criados na seção anterior. Note que todos eles derivam da mesma classe, motivo pelo qual possuem estrutura igual (atributos e métodos). Além disso, veja que a classe modelada apresenta três divisões em seu formato: no topo da figura é mostrado o nome da classe; a parte do meio contém a especificação de todos os atributos que a compõem; a parte mais – 47 – Classes baixa relaciona os métodos que podem ser executados por objetos criados a partir desta classe. Figura 2: Classe “Carro” com seus objetos instanciados. Marca Modelo Ano de fabricação Cor Preço Chassi Ligar Acelerar Frear Parar Movimentar volante Alterar marcha Carro carro1 carro2 carro3 carro4 Fonte: elaborado pelo autor, 2015. A definição da estrutura da classe é fundamental para qualquer sistema orientado a objeto, pois todas as outras estruturas e relacionamentos derivam dela. Sendo assim, procure construir as classes especificando todos os seus possíveis atributos e métodos, facilitando assim futuras manutenções, tanto no modelo de classes quanto no código-fonte do programa. Para auxiliá-lo neste processo de definição de atributos e métodos de classes, pense em um sistema computacional solicitado por uma agência bancária que necessita gerenciar todas as informações das contas de seus clientes. Como o relacionamento dos clientes com essa agência se dá por meio da existência de uma conta, é preciso conhecer sua estrutura real para especificá-la nas instruções do sistema. Agora, pense em pelo menos três atributos que uma conta corrente bancária possui, além de três métodos que um objeto desta classe poderia executar. Tente criar um modelo desta classe, assim como fizemos para a classe “Carro”. Ao final, compare-o com o modelo apresentado a seguir. Programação de Computadores – 48 – Figura 3 - Classe “Conta Corrente” com seus atributos e métodos. Número Saldo atual Limite de crédito Sacar Depositar Encerrar Conta Corrente Fonte: elaborado pelo autor, 2015. Note que fizemos a definição da estrutura de uma classe apenas com os conhecimentos básicos que temos a respeito de uma conta corrente bancária. Em um processo ideal, algum participante do projeto poderia conversar com o gerente da agência bancária para identificar outros requisitos e complemen- tar este modelo proposto. Para finalizar nosso entendimento sobre a definição das classes, consi- dere a necessidade de se desenvolver um sistema para uma empresa de vendas diretas ao consumidor, como um restaurante, por exemplo. Diversas clas- ses poderiam ser definidas neste contexto, objetivando gerenciar os dados dos clientes, funcionários, produtos, vendas e compras, dentre outras. Agora tente montar um modelo para a classe responsável pelo gerenciamento dos produtos deste restaurante, definindo seus atributos e métodos. Figura 4 - Classe “Produto” com seus atributos e métodos. Código de barras Nome Unidade Preço de compra Preço de venda Quantidade de estoque Produto Vender Comprar Alterar estoque Recalcular preço Fonte: elaborado pelo autor, 2015. – 49 – Classes 3.1.3 Codificando classes na linguagem C++ A partir do momento que já modelamos nossa classe, estamos aptos a convertê-la em um conjunto de instruções de determinada linguagem de programação. Por se tratar de uma linguagem de fácil aprendizado, iremos aplicar os conceitos trabalhados sobre classes, objetos, atributos e métodos utilizando a Linguagem C++ como base. Você sabia? A Linguagem C++ foi criada na década de 1980 com o objetivo de melho- rar a Linguagem C, cuja plataforma era até então o padrão mais utilizado para desenvolvimento de programas de computador. Para conhecer melhor o his- tórico desta importante linguagem de programação, acesse os links a seguir. http://linguagemc.com.br/breve-historia-da-linguagem-c/ http://www.tiexpert.net/programacao/c/introducao-cpp.php http://www.infoescola.com/informatica/cpp/ A estruturação de qualquer classe em C++ segue uma padronização básica indicando que, primeiramente, é definido o nome da classe, em seguida os seus atributos para, no final, serem especificados os métodos. Sendo assim, vamos codificar a classe “Carro” apresentada na seção anterior, considerando todos os seus atributos e métodos. class Carro { //Atributos public: string marca; string modelo; int ano_de_fabricacao; string cor; float preco; string chassi; //Métodos void ligar(); Programação de Computadores – 50 – void acelerar(); void frear(); void parar(); void movimentar_volante(); void alterar_marcha(); }; É oportuno ressaltar que para a codificação desta classe estar plenamente correta, o programa deverá utilizar duas bibliotecas do C++ chamadas “iostream” e “string”. Para isso, no cabeçalho do arquivo, inclua as seguintes instruções: #include <iostream> #include <string> using namespace std; Agora precisamos criar um objeto a partir da classe já estruturada, de maneira que seja possível preenchermos o valor de cada um dos atributos do objeto. Isso deve ser feito dentro da função principal (“main”) do código-fonte. #include <iostream> #include <string> using namespace std; int main(int argc, char** argv){ //Declaração do objeto Carro carro1; //Armazenando valores dos atributos dos objetos carro1.marca = “Fiat”; carro1.modelo = “Palio”; carro1.ano_de_fabricacao = 2014; carro1.cor = “Preto”; carro.preco = 39900.00; carro1.chassi = “11AD89480P”; //Imprimindo dados cout << “Marca” << carro1.marca; cout << “Modelo” << carro1.modelo; cout << “Ano de fabricação” << carro1.ano_de_fabricacao; cout << “Cor” << carro1.cor; cout << “Preço” << carro1.preco; cout << “Chassi” << carro1.chassi; return 0; } – 51 – Classes Note que dentro do método principal foi criado um novo objeto da classe “Carro” chamado “carro1”. A sintaxe utilizada pela Linguagem C++ para definição de classes é relativamente simples, bastando utilizar a palavra reservada class, seguida do nome da classe. Como todos os atributos da classe são públicos, isto é, permitem acesso direto por qualquer programa, foi pos- sível armazenar um valor para cada atributo deste objeto criado, usando a chamada “notação ponto”. Na prática, esta notação indica que sempre que desejamos acessar o membro de algum objeto, escrevemos o nome do objeto, o sinal de ponto e o nome do membro que será acessado. Neste exemplo, colocamos o nome do objeto (“carro1”), seguido do sinal de ponto e seus membros (os nomes dos atributos). Para cada atributo acessado, o programa armazenou um valor diferente. Saiba mais Existem diversos softwares que permitem a criação dos arquivos de códigos da Linguagem C++, cada uma com sua própria interface e recursos adi- cionais. Você encontra o link para download desses softwares na listagem apresentada a seguir. Sugiro que você opte neste momento por uma ferra- menta mais simplificada, para que seu foco seja na elaboração das instruções computacionais e nos seus testes. Dev-C++: http://sourceforge.net/projects/orwelldevcpp/ NetBeans: https://netbeans.org/downloads/ Visual Studio: https://www.visualstudio.com/pt-br/visual-studio-homepage-vs.aspx CodeBlocks: http://www.codeblocks.org/downloads Notepad++: https://notepad-plus-plus.org/download/v6.8.8.html Programação de Computadores– 52 – Resumindo O entendimento e a posterior diferenciação dos conceitos de objetos e classes são fundamentais para elaborar programas utilizando o paradigma orientado a objetos. Neste capítulo, analisamos esses dois conceitos e apresen- tamos diversos exemplos reais de como eles seriam trabalhados em sistemas computacionais, inclusive com a produção de código-fonte na linguagem C++. Tenha sempre em mente que a definição da estrutura de uma classe é uma tarefa em certos aspectos trabalhosa e que demanda investigação junto aos futuros usuários do software para que ela realmente seja um modelo do mundo real dentro do sistema. Neste capítulo, apresentaremos as características de um dos principais recursos utilizados na programação orientada a obje- tos: os métodos. Como toda a comunicação é baseada na troca de mensagens, são os métodos que possibilitam que essa implementa- ção seja feita, enviando mensagens entre as diversas instâncias de classes criadas ao longo do sistema computacional. Diferentemente da programação estruturada, os métodos na programação orientada a objetos possuem diversas formas de cons- trução e podem ser utilizados nos mais variados casos, como vere- mos a seguir. Por fim, este capítulo apresenta ainda exemplos práti- cos de métodos construídos na Linguagem C++. 4 Fundamentos de métodos Programação de Computadores – 54 – Objetivos de aprendizagem: 2 Conceituar a utilização de métodos em C++; 2 Aprender e usar métodos de classe; 2 Diferenciar métodos comuns, estáticos, virtuais e inline; 2 Diferenciar passagem de parâmetros por valor e por referência; 2 Implementar, na prática, o conceito de encapsulamento. 4.1 Conceitos básicos sobre os métodos A principal estrutura elaborada dentro da programação orientada a obje- tos é a classe, que é composta basicamente por atributos e métodos, segundo Sintes (2002). Enquanto os atributos são as características que um objeto desta classe irá possuir, os métodos são as ações que esse objeto poderá exe- cutar dentro do contexto do sistema computacional. O que exatamente são os métodos? Basicamente, são as funções que realizam as tarefas do objeto, codificadas de acordo com a necessidade real do usuário. Na orientação a objetos, os métodos são executados por um objeto assim que ele recebe uma mensagem, seja interna ou vinda de outro objeto. Uma de suas principais tarefas é manipular os valores armazenados nos atributos de sua própria classe, criando uma barreira de segurança adicional, impedindo o acesso direto a esses atributos. No caso da programação orientada a objetos, essa “barreira” corresponde ao conceito de encapsulamento, o qual é implementado com o apoio direto do uso de métodos, que cumprem o papel de “esconder” dos usuários o que é feito durante a manipulação dos valores dos atributos. Para Deitel e Deitel (2011), os métodos têm a capacidade de especificar o comportamento dos objetos de determinada classe. Quando ocorre uma associação entre a classe e um método, dá-se o nome de “ligação” (binding). Sendo assim, um método está ligado à determinada classe durante o tempo de compilação (ligação estática) ou associado a uma instância desta classe em tempo de execução (ligação dinâmica). Em termos práticos, pense em quais funções um objeto do mundo real executa nas suas tarefas rotineiras. Por exemplo, se considerarmos o con- – 55 – Fundamentos de métodos texto de um sistema educacional, os alunos realizam matrículas, pegam livros emprestados na biblioteca, pagam a mensalidade, dentre outros. Todas essas ações são exemplos de métodos que a classe “Aluno” em um sistema orientado a objetos deveria fornecer a seus objetos. Considere também os professores, que podem agendar laboratórios, postar materiais, lançar notas e frequência, dentre outras ações. É importante que você tenha em mente que as ações variam de acordo com a área do sistema que está sendo desenvolvido e devem sempre representar ações desempenhadas por objetos do mundo real. Saiba mais A troca de mensagens é o meio pelo qual os diversos objetos de um programa, construído com base no paradigma orientado a objetos, se comunicam. Para compreender melhor como é a aplicação desta técnica, acesse os links a seguir. http://www.bosontreinamentos.com.br/analise-de-sistemas/ conceitos-de-programacao-orientada-a-objetos/ http://www.devmedia.com.br/orientacao-a-objetos-parte-ii/7161 http://www.cin.ufpe.br/~rcmg/cefet-al/proo/apostila-poo.pdf (Item 2.3) https://bsideias.wordpress.com/2008/01/29/poo-programacao- orientada-a-objetos/ 4.2 Especificadores de acesso Antes de aprofundarmos nossos conhecimentos na criação dos métodos, é importante compreendermos o conceito e a aplicação dos especificadores de acesso dentro de um programa orientado a objetos. Determinadas partes de uma classe podem necessitar de proteção extra, isto é, requerem que o acesso a elas não seja feito de forma direta pelo usuário, mas sim por um método definido especificamente para isso. Eles estão diretamente relacionados ao conceito de encapsulamento dos membros de uma classe, recurso fundamen- tal na programação orientada a objetos. Mas para que é utilizado o encapsulamento na construção de um sis- tema computacional? Segundo Deitel e Deitel (2011), quando usamos o encapsulamento, queremos alcançar dois objetivos: Programação de Computadores – 56 – 2 Ocultar a estrutura interna do programa (e suas particularidades) para quem deseja utilizá-lo. Por exemplo, para que o usuário grave o nome de um cliente no atributo de uma classe, ele não precisa saber qual o tipo de dado, mas que será possível armazenar todas as informações necessárias relacionadas com o nome; 2 Reduzir o número de mudanças no código-fonte quando houver alteração da estrutura interna dos dados. Por exemplo, se a estru- tura interna dos dados sofrer algum tipo de mudança, não será necessário mudar o código daqueles objetos que executam opera- ções da classe, desde que o nome e o tipo do método público (e sua lista de parâmetros) permaneçam inalterados. Mas como identificar a especificação de acesso? As palavras reservadas public, private e protected indicam no código a utilização dos especificado- res. Membros da classe definidos como private definem os atributos ou méto- dos que poderão ser acessados apenas por membros da própria classe, ou seja, códigos fora da classe não conseguirão acessar essa área. Já os membros defi- nidos como public, podem ser manipulados diretamente em qualquer parte do código do programa. Vale ressaltar que quando nenhum especificador de acesso é definido para um membro da classe, ele será declarado como privado (por padrão). O especificador protected é mais utilizado quando existe uma relação de herança entre diversas classes do sistema, permitindo acesso direto por uma subclasse aos membros da sua superclasse. Em termos práticos, o encapsulamento facilita diversos aspectos da progra- mação e esconde aqueles particulares da estrutura da classe que desejamos, além de reduzir o retrabalho quando são feitas alterações na classe. Pense em uma classe que possui um atributo para armazenar o peso de um veículo. Se esse atributo fosse público, o usuário poderia atribuir qualquer valor para ele, inclusive núme- ros negativos. Ora, sabemos que um veículo nunca terá o peso negativo, portanto é preciso que o programa limite a ação do usuário, isto é, não permita a ele infor- mar qualquer valor para o atributo. Neste caso, o encapsulamento pode auxiliar na resolução do problema, pois o atributo seria declarado como de acesso privado, não permitindo a manipulação direta pelo usuário. A atribuição de valores seria feita por um método criado, especificamente, para este fim, o qual poderia validar o peso informado pelo usuário, indicando se está correto ou
Compartilhar