Baixe o app para aproveitar ainda mais
Prévia do material em texto
03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 1/19 PROGRAMAÇÃO VOLTADA A OBJETOS AULA 1 Prof. Leonardo Gomes 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 2/19 CONVERSA INICIAL Nesta etapa, faremos uma introdução ao tópico de programação orientada a objetos e à linguagem de programação Java. Falaremos sobre os diferentes paradigmas de programação com foco na orientação a objetos. Daremos também os primeiros passos no Java, uma importante linguagem de programação que servirá de base para este estudo como um todo. Ao final desta etapa, esperamos atingir os seguintes objetivos que serão avaliados ao longo do estudo da forma indicada: Quadro 1 – Objetivos Objetivos Avaliação 1 – Contextualização sobre o paradigma de programação orientado a objetos e à Linguagem de programação Java Questionário e questões dissertativas 2 – Capacidade de criar projetos Java simples dentro da IDE Eclipse Questionário e questões dissertativas 3 – Desenvolver programas básicos utilizando Java Questionário e questões dissertativas Fonte: Gomes, 2020. TEMA 1 – PARADIGMAS DE PROGRAMAÇÃO E HISTÓRIA DA PROGRAMAÇÃO ORIENTADA A OBJETOS Neste tópico, discutiremos os diferentes paradigmas de programação e um pouco de seu histórico com foco na Orientação a Objetos. Antes mesmo do surgimento dos primeiros computadores na década de 1940, já existiam modelos e regras formais para descrever algoritmos 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 3/19 que serviram de base para as primeiras linguagens de programação propriamente ditas. Chamamos de paradigma de programação um dos meios de classificar linguagens de programação de acordo com sua estruturação, abstração e funcionalidades. Nestes primeiros anos da programação, destacamos o paradigma procedural, o paradigma funcional, o paradigma lógico e o paradigma orientado a objetos. Geralmente, iniciamos o aprendizado na programação por meio do paradigma procedural, e a linguagem C utiliza exclusivamente esse paradigma. Nele, baseamos nosso código em comandos que mudam o estado da memória de forma detalhada e sequencial, ou seja, procedural. Reservamos espaços de memória por meio de variáveis para armazenar nossos dados e criamos funções que definem comportamentos desejados para esses dados. Esse paradigma se aproxima da forma que o processador interpreta os comandos e trabalha com os dados efetivamente, dando maior liberdade para o programador desenvolver algoritmos eficientes. Junto ao paradigma procedural, surgiu também o paradigma funcional, no qual o código é pensado e descrito por meio da resolução de funções matemáticas. Esse paradigma facilita o desenvolvimento de certos algoritmos que são mais facilmente representados de forma puramente matemática. Tal paradigma ainda é muito utilizado em certas linguagens que combinam paradigmas como a linguagem Scala. Outro importante paradigma que surgiu na década de 1950 foi o paradigma lógico, no qual uma base de declarações lógicas matemáticas é gerada pelo programador, com a qual o computador se baseia para calcular respostas fundamentadas na base inicialmente criada. Uma linguagem proeminente que adota esse paradigma de forma exclusiva é o Prolog, que possui diversas aplicações na inteligência artificial. Em meados dos anos 1960, um pesquisador chamado Alan Kay, influenciado por sua formação em biologia e matemática, além de outras tecnologias da época, como o Sketchpad e a Simula, pensou em uma nova arquitetura de programação que chamou de paradigma orientado a objetos. Em sua concepção original, a programação orientada a objeto deveria se basear em células independentes trocando mensagens entre si e retirando o foco dos dados. As linguagens de programação Simula e Smalltalk foram as primeiras a adotar as práticas propostas por Alan Kay. As linguagens modernas de programação se inspiram e combinam esses paradigmas oferecendo diversas opções de estratégias para o desenvolvimento de algoritmos. 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 4/19 As soluções aplicadas em um paradigma podem ser de forma direta ou indireta representadas em outro, tornando cada paradigma ótimo para um tipo de situação diferente. Um programador versado em diversos paradigmas terá um ferramental maior na hora de gerar soluções para problemas complexos. Neste estudo, vamos abordar o paradigma orientado a objetos, que é muito popular em soluções comerciais hoje por ser especialmente adequado para projetos de grande escala que necessitam de constante manutenção e ampliação. Figura 1 – Representação dos paradigmas de programação Fonte: Gomes, 2020. Imperativo são os paradigmas voltados para representar os comandos que resolvem o problema, focado em como resolver. Em contrapartida, temos os paradigmas declarativos que não focam em mudanças de estado sequencial de um programa, mas sim no que se deve resolver. Dessas duas classes derivam os paradigmas que discutimos até aqui. 1.1 PARADIGMA DE PROGRAMAÇÃO ORIENTADA A OBJETOS O paradigma orientado a objeto foi pela primeira vez aplicado de forma adaptada na linguagem de programação Simula 67, nos anos de 1960, posteriormente também sendo utilizado de forma exclusiva na linguagem Smalltalk da Xerox. Sua grande popularidade influenciou todas as principais linguagens de programação de hoje, C++, C#, PHP, Python e Java, que é a linguagem base do nosso estudo. 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 5/19 O pesquisador Alan Kay, que atuou na empresa Xerox, foi quem liderou o projeto que encabeçou as primeiras linguagens de programação baseadas em orientação a objetos, sendo inclusive responsável por cunhar o termo. Alan Kay propôs uma abstração em que a programação de computadores poderia ser encarada como um organismo vivo, no qual cada célula é entendida como um elemento independente, relacionando-se com outras células de forma a manter o funcionamento de todo um organismo. Alan Kay expandiu essa ideia para outras relações além das intercelulares, pois a forma como entendemos o mundo se dá por meio das relações de objetos e pessoas, cada um com suas características individuais, realizando ações uns sobre os outros e permitindo a construção de sistemas complexos. Essa forma de pensar é natural e intuitiva para nós, pois emula como vemos o mundo. Em programação estruturada, o foco está nas ações: em um programa de computador de vendas, por exemplo, o conjunto de instruções que efetua a compra de itens por um cliente geralmente seria agrupado em uma função chamada comprar(), porém, em um sistema orientado a objetos, pensamos primeiro no objeto “quem está realizando essa compra?”, e teríamos um objeto cliente com todos os dados dos clientes, bem como um comando como cliente.comprar(). Assim, associamos sempre os objetos (cliente neste exemplo) à ação (comprar), que deixa mais clara e intuitiva a leitura dos códigos, pois há maior contexto quando pensamos em um “cliente comprando” que simplesmente na ação de comprar isolada, trazendo o código mais perto de como entendemos o mundo. Associando essa prática a outros conceitos, como herança, polimorfismo, encapsulamento, entre outros, promovemos ganhos de produtividade, especialmente na manutenção de códigos pela sua maior facilidade no entendimento. No próximo tópico, será apresentada a linguagem de programação Java, que é completamente voltada ao paradigma de orientação a objetos. TEMA 2 – HISTÓRIA DO JAVA Neste tópico vamos discutir o histórico, a origem e a importância da linguagem Java. Conhecer este contexto nos ajuda a compreender a função dos principais atores tecnológicos da computação. 2.1 PRIMEIROS ANOS 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 6/19 A Linguagem Java surgiu no início dos anos 1990 em uma importante empresa de tecnologia chamada SunMicrosystems. A equipe responsável pelo desenvolvimento desta linguagem atuava no chamado Green Project e foi liderada pelo cientista da computação James Gosling. O Green Project tinha por objetivo gerar tecnologias voltadas para conectividade de equipamentos domésticos. O primeiro produto foi um dispositivo chamado StarSeven, que semelhante a um tablet, poderia receber comandos de toque e controlar os demais dispositivos. A comunicação entre os dispositivos deveria se dar por meio de uma linguagem de programação que fosse independente de plataforma. A equipe de Gosling a princípio tentou adaptar o C++ para esta tarefa, mas, por fim, optou por desenvolver uma linguagem própria, que chamaram na época de Oak (do inglês, carvalho). A linguagem Oak possuía o diferencial de ser uma interpretada por uma máquina virtual fornecida pela Sun, e todo o dispositivo que rodasse a máquina virtual da Sun seria capaz de executar códigos Oak sem a necessidade de compilação específica para o dispositivo em questão. Embora o projeto de conectividade doméstica não tenha emplacado como planejado, a tecnologia de uma linguagem independente de plataforma casou muito bem a internet e os navegadores que se popularizaram muito na época. Por questões legais e de registro de marca, a linguagem Oak mudou seu nome para Java em 1995. Com isso, popularizou-se muito o uso de pequenos programas chamados applets, os quais eram baixados de um servidor web e poderiam ser executados na máquina dos clientes independentemente da plataforma, desde que eles possuíssem uma máquina virtual Java previamente instalada. 2.2 O JAVA MODERNO Nas décadas de 1990 e 2000, a popularização da internet levou a uma grande popularização da linguagem Java, que recebeu suporte de grandes companhias de informática, tais como a IBM. De certa forma, o objetivo inicial do Green Project foi atingido com o Java sendo utilizado para conectar todo o tipo de dispositivo móvel, tais como celulares, tablets, computadores e até mesmo uma das primeiras sondas espaciais robóticas a atingir o solo marciano em 2004. Figura 2 – Opportunity, sonda espacial que realizou missão exploratória do solo marciano 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 7/19 Créditos: rzulev/Shutterstock. A linguagem Java adotou licença de software livre GPL v3 em 2006, o que significa que os programas feitos pela Sun para permitir o funcionamento do Java e de suas bibliotecas possuem código aberto para consulta, cópia e modificação, desde que o desenvolvedor que faça modificações também disponibilize seu código livremente. A Sun Microsystems foi adquirida pela Oracle em 2010, que é quem oferece suporte ao Java até hoje. Embora applets não sejam mais usualmente adotadas, a popularidade do Java se mantém, de forma que essa linguagem é adotada nos aplicativos do sistema operacional Android, em diversos tipos de servidores, em leitores de livros digitais como Kindle e TV digital DTVI e até no tradicional programa de Imposto de Renda brasileiro, dentre outros muitos exemplos. No momento da edição deste documento, a linguagem Java se encontra na versão 13, lançada em setembro de 2019. Trata-se de uma linguagem Orientada a Objetos com sintaxe baseada na linguagem C. No próximo tópico, discutiremos questões técnicas da arquitetura e organização das soluções Java. TEMA 3 – ORGANIZAÇÃO DO JAVA 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 8/19 Agora, vamos debater em detalhes a tecnologia Java em si. Mais que uma linguagem e bibliotecas, o Java necessita de um ambiente próprio para o seu funcionamento. Ele também acompanha um conjunto completo de programas que também iremos apresentar. Tradicionalmente, as linguagens de programação passam por um processo denominado compilação, o qual transforma o código de alto nível escrito pelo programador no que chamamos de código de máquina ou binário. Esse código nativo é lido pelo processador que executa as instruções. Os programas .exe do Windows são um exemplo de binário. Em contrapartida, existem também linguagens que são interpretadas que não passam por esse processo de compilação. O código escrito pelo programador em tempo de execução é traduzido para código de máquina. Códigos interpretados são essencialmente menos eficientes que códigos compilados pela quantidade extra de instruções que requer a interpretação dele. Porém, possuem a vantagem de serem facilmente portados para diferentes plataformas justamente por não necessitarem de recompilação para cada plataforma. Dessa forma, um mesmo código interpretado sem alterações pode ser executado em diferentes computadores com sistema operacional Linux, Windows ou Mac. Quanto ao Java, dependendo do ambiente de execução, é possível trabalhar com ele tanto interpretado quanto compilado. Porém, ele tipicamente funciona em um processo em dois passos. Primeiro, o código de alto nível é compilado para um formato chamado bytecode. Esse código bytecode posteriormente é interpretado por um programa chamado máquina virtual Java, em inglês Java Virtual Machine. Ao longo dos nossos estudos, chamaremos pela sigla JVM. As JVM para as principais plataformas são mantidas pela Oracle, mas podem ser desenvolvidas de forma independente para os mais diversos dispositivos por qualquer equipe, visto que possuem licença livre. Portanto, um mesmo bytecode pode ser executado em qualquer sistema que possua uma JVM. Pelo fato de o Java utilizar JVM para interpretar seus bytecodes, existe uma perda em desempenho quando comparado a um código compilado nativo. Porém, as JVM evoluíram muito ao longo dos anos, e uma das principais tecnologias neste sentido é o chamado Hotspot. Estudos estatísticos mostram que, na grande maioria dos programas, 80% do processamento se concentra em somente 20% do código. O Hotspot é uma tecnologia que identifica esses trechos de código com muito processamento e executa uma compilação dos mesmos durante a execução do código. 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 9/19 Essa tecnologia de compilação em tempo de execução é chamada de Just in time compilation, mais conhecida pela sigla JIT. A combinação das duas tecnologias, dentre outras melhorias, tornou o Java muito eficiente e diminuiu a distância em relação às linguagens compiladas. No contexto da computação, nós chamamos de Benchmark os testes que buscam comparar desempenho. Na figura 3, vemos um benchmark do Java comparado ao C++ em três algoritmos diferentes. Em um dos testes, o Java chega a apresentar um tempo de execução melhor que o C++. No link presente na legenda da figura, mais testes podem ser vistos. Figura 3 – Benchmark comparando Java ao C++ em três algoritmos distintos. Versão dos compiladores: Java, openjdk13 17-9-2019; C++, g++ 9.2.1-9ubuntu2 Fonte: <https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/java-gpp.html>. Quando se deseja apenas executar bytecodes do Java, é necessário instalar em sua máquina o Ambiente de Execução Java (em inglês, Java Runtime Environment), mais conhecido pela sigla JRE. Ele é composto principalmente pela JVM e bibliotecas padrão do Java. O JRE pode ser encontrada para as mais diversas plataformas na página oficial da Oracle. Agora, quando desejamos programar em Java, precisamos instalar o Kit de desenvolvimento Java (em inglês, Java Development Kit), mais 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 10/19 conhecido pela sigla JDK. Ele é composto por um conjunto de utilitários, como o compilador de bytecode, além de uma JRE. A JDK também é encontra na página oficial da Oracle. Neste tópico, vimos muitas siglas e termos. Para facilitar o entendimento e disponibilizar uma rápida referência, vamos agrupar todos no quadro a seguir: Quadro 2 – Termos e siglas relacionados ao Java Nome Tradução Definição Java Virtual Machine JVM Máquina Virtual Java Programa responsável por interpretar e executar o códigoBytecode Java Bytecode Código em byte O equivalente ao executável Java, o Bytecode é gerado após o processo de compilação dos códigos fontes Java Java Development Kit JDK Kit de desenvolvimento Java Conjunto de bibliotecas, compiladores e demais ferramentas para o desenvolvimento de programas Java Java Runtime Environment JRE Ambiente de execução Java Conjunto de biblioteca padrão Java e JVM para execução de códigos Bytecode Just in time compilation JIT Compilação dinâmica Técnica que permite a JVM compilar partes críticas do código em linguagem de máquina em tempo de execução, oferecendo significativo ganho de memória Garbage Collection Coletor de Lixo Técnica que isenta o programador da responsabilidade de desalocar memória, a JVM regularmente se encarrega de liberar memória alocada não utilizada Fonte: Gomes, 2020. No próximo tópico, daremos sequência ao nosso estudo e faremos nosso primeiro código Java. TEMA 4 – VERSÕES DO JAVA E PRIMEIRO CÓDIGO Neste tópico, vamos finalmente colocar a mão na massa. Faremos nosso primeiro projeto Java com base no programa Eclipse. 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 11/19 4.1 VERSÕES DO JAVA E A IDE ECLIPSE No caso do Java, assim como na grande maioria das linguagens de programação, é possível codificar utilizando qualquer editor de texto e, posteriormente, por meio de um compilador dedicado, gerar o seu binário (Bytecode, no caso do Java). Porém, é muito mais produtivo, especialmente em projetos de grande escala, utilizar um programa próprio direcionado ao desenvolvimento de códigos que combine editor de texto, compilador, depurador, bibliotecas, entre outras funcionalidades. Esse tipo de programa é conhecido como um ambiente de desenvolvimento integrado, do inglês Integrated Development Environment, ou apenas IDE. Existem diversas IDEs de excelente qualidade para o Java, das quais destacamos o Netbeans, da própria Oracle; o IntelliJ IDEA, da empresa JetBrains; e o mais popular de todos, o Eclipse, inicialmente da IBM, mas, hoje, com licença software livre. O Eclipse é o que utilizaremos em nossos estudos, mas todas funcionam de forma análoga. O Eclipse, originalmente desenvolvido como IDE para Java, foi adaptado por plugins desenvolvidos pela comunidade para as mais diversas linguagens de programação, podendo ser encontrado no site: <https://www.eclipse.org/>. O Java conta com três versões principais, Java Micro Edition (ME), Standard Edition (SE) e Enterprise Edition (EE). A seguir, mencionamos suas características: O Java ME visa à construção de softwares para dispositivos embarcados, sistemas de propósito específico com poucos recursos computacionais. Ele é compatível com uma biblioteca básica de classes e se torna especialmente importante no contexto de soluções desenvolvidas pensando na Internet das Coisas; Java SE é a edição padrão do Java com o principal conjunto de bibliotecas, perfeita para desenvolver programas desktop e de console. Por console, entenda programas com interface puramente em modo texto, que são geralmente executados por prompt de comando do sistema operacional Windows ou terminal do Linux; Java EE é a edição mais completa que já vem equipada com bibliotecas prontas para soluções empresariais, especialmente voltadas para internet e banco de dados. Trata-se de uma série de especificações que foi desenvolvida integral ou parcialmente na forma de servidor de aplicações por diversos fornecedores. É uma importante tecnologia que ajuda a formar a espinha dorsal da internet atual. https://www.eclipse.org/ 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 12/19 A IDE do Eclipse conta com diversas opções para instalação. Para nosso estudo, busque a versão SE ou EE. 4.2 PRIMEIRO CÓDIGO As principais IDEs incluindo Eclipse possuem o conceito de projeto. O projeto engloba todas as classes e bibliotecas necessárias para a geração de um programa. Na figura 4, vemos a estrutura de um projeto Java na IDE Eclipse. Os principais elementos que compõem o projeto são: Bibliotecas: são bytecodes com funcionalidades específicas implementadas. Permitem ao programador reaproveitar códigos geralmente desenvolvidos por equipes diversas e que já são muito bem testados e eficientes. O Eclipse já inclui uma biblioteca básica em todos os projetos; Pacotes: conceito semelhante ao de pasta/diretório para organizar a estrutura dos códigos Java. Supondo que temos um projeto grande com muitos códigos, podemos agrupar os arquivos ligados a bancos de dados de um pacote que esteja ligado à interface visual de outro, por exemplo. Usualmente, o pacote principal de um projeto é nomeado com o inverso do domínio da sua instituição. Por exemplo, empresa.com se torna com.empresa. Essa é uma prática comum, porém, não é necessária. Esse pacote principal fica inserido dentro de uma pasta nomeada src (que vem da palavra source, isto é, código, em inglês); Classe: os códigos são descritos em arquivos com extensão .java, geralmente um arquivo por classe. Figura 4 – Estrutura de projeto básico Eclipse com uma única classe Uma vez aberto o programa Eclipse, para criar um projeto novo basta ir à opção File/New Project. Em seguida, dê um nome apropriado ao projeto e utilize as opções padrões. O projeto 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 13/19 criado estará vazio. Para criar uma primeira classe Java que receberá o método principal, basta clicar com o botão direito sobre a pasta com o nome do projeto e ir à opção New/Class. Dê um nome para a classe e um nome para o pacote. Por se tratar da primeira classe com o método principal (equivalente ao main do C/C++), é interessante marcar no checkbox a opção public static void main(String[] args). Um arquivo com aproximadamente o seguinte código deve surgir: Vamos analisar linha por linha o código acima: packagecom.empresa; Indica o nome do pacote no qual a classe está; publicclass PrimeiraClasse Esta é a linha na qual se informa o nome da classe. O comando public indica que a classe pode ser acessada de forma pública por outras classes. Os conceitos de classes públicas e privadas e suas implicações serão discutidos em detalhes em conteúdo posterior; public static void main(String[] args) { Esta linha é a declaração do método, na qual static indica que o método pertence à classe, e não ao objeto – o conceito de métodos estáticos será discutido com detalhes em conteúdo posterior –; main é o nome do método principal, equivalente à função principal em linguagens como C/C++ e indica que esse método será o primeiro a ser executado pelo programa; e String [] args é a declaração de um array (estrutura semelhante a uma lista) de objetos da Classe String como parâmetro de entrada do método. Caso o programa seja executado em modo console, eventuais parâmetros de execução na chamada do programa serão lidos e direcionados para a variável args. As chaves { } representam blocos de código, marcam onde começa e termina a classe e onde começa e termina o método. Como primeiro comando, escreva dentro do bloco de código do método main o seguinte comando: 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 14/19 Esse é o comando que imprime a mensagem que estiver entre aspas na tela em modo console. Atenção ao ponto-e-vírgula ao final de cada comando Java. Para executar e testar o seu primeiro programa, vá na opção Run/run ou utilize o atalho CTRL + F11. Se tudo ocorrer bem, você verá a sua mensagem impressa na tela. Parabéns pelo seu primeiro programa Java! Dica: o Eclipse conta com um atalho para o comando acima, basta escrever sout e fazer o comando CTRL + Espaço. Existem diversos atalhos dentro do Eclipse, assim, procure os principais na internet ou no próprio Eclipse, dentro de Help/Show Active Keybindings. Dominar alguns atalhos contribuirá para um aumento significativo na produtividade em longo prazo. Alguns dos comandos Java parecemlongos e intimidadores quando comparados com os de outras linguagens, porém, com a experiência, você notará que eles seguem uma padronização que se torna intuitiva e clara com o tempo. O Java conta com uma biblioteca padrão muito extensa que permite um grande reaproveitamento de códigos. No próximo tópico, faremos um apanhado geral sobre os principais comandos Java. TEMA 5 – VISÃO GERAL SOBRE O CÓDIGO JAVA Neste tópico, vamos avançar a discussão sobre a linguagem Java, mas sem entrar em detalhes sobre a orientação a objetos. Além disso, também vamos passar brevemente pelos principais comandos e estruturas de dados disponíveis nessa linguagem. 5.1 PRINCIPAIS COMANDOS A sintaxe da linguagem Java é baseada em C/C++, portanto, quem as conhece automaticamente já domina grande parte dos principais comandos Java. No entanto, mesmo quem vem de outras linguagens como Python terá facilidade, visto que a lógica continua a mesma e muda apenas a forma de descrever certos comandos. 5.1.1 ENTRADA E SAÍDA 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 15/19 Vimos em conteúdo anterior, um primeiro comando de impressão no console, porém, a seguir vemos algumas de suas variantes: Quanto à leitura de dados, é necessário realizar alguns passos. A seguir, temos um código Java que utilizaremos para exemplificar. Primeiro precisamos importar a biblioteca java.util.Scanner, que possui as definições da classe Scanner necessárias para a leitura. Veja o código a seguir na linha com a Obs 1, o comando import é utilizado para esta tarefa, e as importações devem vir sempre logo abaixo da declaração do nome do pacote. Em seguida, declaramos uma variável (objeto) do tipo (classe) Scanner. Essa classe é responsável por ler os dados de alguma fonte passada por parâmetro, no caso, o parâmetro deve ser System.in, que aponta a entrada padrão do sistema, o teclado. Veja a Obs 2 no código, o nome do objeto pode ser qualquer um, no caso, optou-se pelo nome teclado. Na sequência, devemos utilizar o objeto que declaramos para fazer a leitura. Para ler um valor inteiro, teclado.nextInt(); para um valor real, teclado.nextFloat() ou teclado.nextDouble(); e para ler uma string, teclado.next(). Veja a Obs 3 no código para um exemplo. 5.1.2 COMANDOS DE DESVIO 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 16/19 Assim como nas principais linguagens de programação, o principal comando de desvio é o if(). Entre parênteses, colocamos a expressão associada, se a expressão for verdadeira, o fluxo do código é desviado. As variantes com else if e a variante com else também estão presentes na linguagem. No exemplo a seguir, o código que imprime verifica o valor de uma variável idade e imprime a mensagem Criança, Adolescente ou Adulto, dependendo do valor. Atenção: o ponto-e-vírgula não aparece depois do comando if. O comando switch case também está presente na linguagem Java, permitindo o desvio de fluxo. Primeiro, a expressão dentro do switch é avaliada, e o código é desviado para o case pertinente ou default, caso nenhum esteja adequado. A seguir, um exemplo genérico do seu uso: 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 17/19 5.1.3 COMANDOS DE REPETIÇÃO Os principais comandos de repetição também estão presentes em Java: while, do-while e for. Entre parênteses vai a condição que deve ser avaliada para analisar se o loop deve repetir ou não. Atenção: o ponto-e-vírgula não aparece depois do comando while. O comando for é dividido em três partes separadas por ponto-e-vírgula. Na primeira, trata-se do que deve ser executado antes do loop, sendo geralmente a inicialização de alguma variável de controle. Na sequência, a condição de continuidade do loop, semelhante à condição do while e, por fim, o que deve ser executado ao final de cada iteração do loop, geralmente um incremento. 5.2 TIPOS DE DADOS No Java, os dados são tipados, ou seja, antes de criar uma variável, é necessário declará-la e indicar o tipo de dado. No Java, chamamos de primitivas as variáveis dos tipos básicos presentes nas principais linguagens de programação, como a seguir. Em um nível de abstração maior, os dados podem ser armazenados também em tipos não primitivos, como String, Array e Classes. No quadro a seguir, temos as primitivas: 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 18/19 Quadro 3 – Tipos básicos no Java Tipo Tamanho Descrição byte 1 byte Números inteiros (-128 até 127) short 2 bytes Números inteiros (-32.768 até 32.767) int 4 bytes Números inteiros (-2.147.483,648 até 2.147.483.647) long 8 bytes Números inteiros (-9.223.372.036.854.775.808 até 9.223.372.036.854.775.807) float 4 bytes Armazena números inteiros e fracionários até 6 e 7 dígitos decimais double 8 bytes Armazena números inteiros e fracionários até 15 dígitos decimais boolean 1 bit Armazena apenas 0 ou 1 (false ou true) Char 2 bytes Armazena um único caractere, letra Stores a single character/letter or ASCII values Fonte: Gomes, 2020. 5.2.1 STRING As strings ou sequência de caracteres no Java são representadas com uma classe chamada justamente de String. No Java, constantes da classe String devem ser escritas entre aspas duplas. Elas possuem diversos métodos internos. No código a seguir, temos um exemplo com comentários: 5.2.2 ARRAYS Os arrays também são essencialmente classes que trabalham de forma análoga ao C/C++ e muito semelhante às listas do Python. Podem ser declarados entre chaves e acessados com colchetes indexados por meio do valor zero. Segue o exemplo: 03/11/2022 11:20 UNINTER https://univirtus.uninter.com/ava/web/roa/ 19/19 Os arrays também contam com diversos métodos, tais como o método length(), que como na classe String, retorna a quantidade de itens do array. Considerando o exemplo anterior, o comando nomes.length() retornaria o número 4. FINALIZANDO Nesta etapa, iniciamos nosso aprendizado introduzindo o contexto histórico dos paradigmas de programação e da linguagem Java. Aprendemos a arquitetura da linguagem, quais suas versões e fizemos nosso primeiro programa. Por fim, realizamos uma visão geral sobre a linguagem Java e os principais comandos. Ainda não entramos em contato direto com Programação Orientada a Objetos em si, mas preparamos o terreno oferecendo o ferramental para nos aprofundarmos utilizando o Java como base para o estudo. Posteriormente, exploraremos mais a criação e a utilização das classes, o principal conceito dentro da programação orientada a objetos. 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 1/24 PROGRAMAÇÃO ORIENTADA A OBJETOS AULA 2 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 2/24 Prof. Leonardo Gomes CONVERSA INICIAL Nesta aula, vamos abordar o principal conceito dentro do paradigma de programação orientado a objetos: as classes. As classes dentro de orientação a objetos são compostas principalmente por atributos e métodos, e é por meio delas que geramos os objetos que dão nome ao paradigma. Além da definição dos conceitos, teremos exemplos do uso das classes e objetos com maiores detalhes de como aplicar esses conceitos. Ao final desta aula, esperamos atingir os seguintes objetivos, que serão avaliados ao longo da disciplina da forma indicada: Quadro 1 – Objetivos Objetivos Avaliação 1. Aplicar os conceitos de classes e objetos em linguagem Java. Questionário e questões dissertativas 2. Desenvolver algoritmos que combinam, agrupam e interagem com diferentes objetos. Questionário e questões dissertativas 3. Aplicar o conceito de construtor em linguagem Java. Questionário e questões dissertativas TEMA 1 – CLASSES E ATRIBUTOS Neste tema, vamos debater os dois conceitos mais importantes da Programação Orientada a Objetos (POO), as classes e objetos. 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 3/24 Quando programamospensando em POO, o objetivo é modelar o mundo real dentro do contexto que nos interessa. Esse modelo deve ser simples e considerar apenas os elementos que forem relevantes para o problema abordado. Os objetos são os elementos em si que compõem o nosso sistema, enquanto as classes são a descrição desses objetos, e como o nome sugere, classificam um conjunto de objetos que pertençam a um mesmo conjunto. Por exemplo, suponha que desejamos criar um jogo eletrônico que implemente uma corrida de carros. É pertinente representar todos os diferentes carros que participam dessa corrida. Cada carro individualmente possui suas características próprias, uma cor, um valor de velocidade máxima, um nível de combustível, uma localização na pista de corrida, entre outros. Cada carro individualmente, portanto, é um objeto. Ainda no exemplo da corrida, observe que todos os carros são representados pelo mesmo conjunto de características, embora possuam valores diferentes para cada variável. E dentro da POO o código que descreve os atributos que todos os carros possuem é chamado de classe. Em resumo, enquanto o termo carro em si de maneira global se refere à classe, se falamos do carro vermelho que está liderando a corrida, estamos falando de um carro específico, portanto, de um objeto. De forma geral cada objeto possui três aspectos principais: Atributos: São as variáveis que descrevem o objeto. Métodos: São como funções que dizem o que cada objeto faz. Estado: Seria o valor de cada atributo que representa aquele objeto específico. O conceito de registro (ou struct) é presente em diversas linguagens de programação e, semelhante ao registro, as classes possuem atributos que caracterizam seus objetos. Na Figura 1, novamente utilizamos o exemplo de uma classe Carro para ilustrar esse conceito. Todos os carros possuem os mesmos atributos, porém, em estados diferentes. Figura 1 – Representação da classe Carro com os atributos cor, modelo e velocidade com 3 objetos distintos cada um com um estado 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 4/24 Crédito: Colorlife/Shutterstock. Já os métodos representam o que cada objeto da classe é capaz de fazer, são funções associadas a cada objeto. A classe carro, por exemplo, poderia ter o método acelerar(int), que receberia um valor inteiro e modificaria a velocidade do objeto pelo valor passado por parâmetro. A chamada do método acelerar com o parâmetro 50 associado ao objeto Sally: Sally.acelerar(50) faria o estado do atributo Velocidade do objeto Sally ser modificado de 210 para 260, por exemplo. 1.1 CLASSE EM JAVA O Java é uma linguagem orientada a objetos, o que significa que todo o código que escrevemos está dentro de alguma classe e as interações entre os dados se dão por meio de métodos e objetos. A convenção entre os programadores Java é a de criar um arquivo separado para cada Classe Java. O arquivo que contém o método main também é uma classe própria geralmente. Anteriormente, fizemos o nosso primeiro programa (código abaixo) e nele observe a linha: A palavra public diz respeito à visibilidade quais outras classes poderão visualizar o código. Estudaremos mais detalhes sobre visibilidade posteriormente, por hora basta entender que é 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 5/24 necessário o comando public. Na sequência, temos o comando class PrimeiraClasse, que indica que entre chaves está o código de uma classe chamada PrimeiraClasse. Como exemplo, vamos fazer um programa Java com duas classes. A classe Principal e uma classe Aluno que representará quais dados cadastrais possuem os alunos de uma instituição. Você já aprendeu, anteriormente, como fazer um programa básico com uma única classe contendo o método main. Para a primeira classe, dê o nome de Principal e marque a opção no checkbox a opção public static void main(String[] args). Para a segunda classe, certifique-se de que a nova classe fique no mesmo pacote que a classe Principal e dê um nome de Aluno. As demais opções devem ser as padrões do sistema, especialmente a opção public static void main(String[] args), só pode existir um único método main no projeto. A estrutura do seu projeto deve ficar como na Figura abaixo. Figura 2 – Projeto Eclipse contendo duas classes Na classe Aluno, vamos declarar como atributo dados que desejamos representar. Para uma classe com nome, número de matrícula e CPF, ficaria assim: 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 6/24 De volta à classe Principal, dentro do método main, podemos criar objetos do tipo Aluno, modificar e comparar seus atributos. No código a seguir, declaramos dois alunos (Mario e Luigi) e queremos imprimir o nome do aluno mais antigo, ou seja, aquele que possui a menor matrícula. Confira o código: 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 7/24 No POO, um objeto pode ser chamado de instância de uma classe e criar uma nova instância, o que é chamado de instanciação. Na linha 2 e 7, temos os objetos sendo instanciados pelo comando new, seguido do nome da classe com abre fecha parênteses, esses parênteses estão presentes, pois se trata de um construtor, que funciona semelhante a um método que especifica detalhes de como o objeto deve ser inicializado. Veremos mais sobre construtores no futuro. O comando new reserva um espaço de memória para aquele objeto. Veja que, na linha 11, uma variável chamada antigo do tipo Aluno está sendo criada, porém, sem ser instanciada com o comando new. Nesse caso, a variável é apenas um ponteiro e serve para referenciar outros objetos. No caso, ela irá referenciar qual dos dois alunos (Mario ou Luigi) é o que possui a menor matrícula. Na linha 18 antigo.nome irá imprimir o nome Super Mario. Se mario.nome fosse alterado para outro valor a alteração passaria a valer para antigo.nome e vice-versa, mario e antigo são referências 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 8/24 (ponteiros) para o objeto criado na linha 2. Nas linhas 3, 4, 5, 8, 9 e 10 os atributos de cada objeto estão sendo acessados e modificados. O código orientado a objeto no caso geral é mais legível que na programação estruturada. Em uma versão estruturada cada aluno deveria ser representando com 3 variáveis diferentes para cada aluno, assumindo um sistema em que os alunos sejam representados por 50 atributos diferentes rapidamente o código ficaria muito difícil de administrar sem uso de classe ou registro/struct. Como desafio, considere o código anterior e modifique-o para termos um terceiro aluno, Yoshi. Descubra qual é o mais antigo dentre os três e imprima todos os dados dele. TEMA 2 – MÉTODOS Neste tema, vamos discutir os métodos que representam as ações que podem desempenhar cada objeto de uma determinada classe. Mais do que agrupar um conjunto de variáveis, as classes também possuem o que chamamos de métodos, que são equivalentes às funções em programação estruturada, um bloco de código que só é executado quando chamado. Os métodos podem receber dados de entrada (parâmetros) e opcionalmente um valor de retorno. A diferença básica do método em relação à função, é que o método está sempre associado a um objeto e consegue acessar os dados internos do objeto associado. Suponha a classe Aluno que criamos anteriormente. Dentro da classe, poderíamos criar um método conforme no código abaixo: 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 9/24 Na linha 5, criamos o método info() que irá imprimir na tela todos os dados referentes ao aluno, os atributos nome, matricula e CPF são acessados de dentro do contexto do método. No entanto, vale o questionamento: qual aluno está tendo os atributos acessados pelo método? Será aquele que está associado ao método? Vamos exemplificar com o código a seguir, supondo o seguinte código na main: 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 10/24 Naslinhas 1 até 9, declaramos os objetos. Na sequência, quando acessamos mario.info(); o método info() será executado considerando os dados dos atributos do objeto mario, enquanto luigi.info(); será executado considerando os atributos do objeto luigi. 2.1 EXERCÍCIOS Desenvolva os exercícios listados aqui e depois compare sua resposta com os códigos apresentados na seção Apêndice ao final deste documento. 1. Crie uma classe Nota, com três atributos reais chamados: nota1, nota2, nota3. E crie também dois métodos, cada um para calcular e retornar diferentes tipos de média. Média Aritmética; e Média ponderada (pesos 2, 3 e 4 respectivamente). 2. Crie uma classe Conta, para administrar contas correntes de um banco com os seguintes atributos: String correntista; float saldo; float limiteSaque; E os métodos: void sacar( float valor) void depositar( float valor) void info() 3. Complemente o exercício anterior implementando um método abaixo: transferir(Conta destino, float valor); O método deve transferir o valor passado por parâmetro do objeto conta que executa o método para a conta destino passada por parâmetro. TEMA 3 – PADRÕES E MODIFICADOR STATIC 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 11/24 Neste tema, vamos discutir dois assuntos importantes dentro da programação Java: os padrões de nomenclatura da linguagem e os usos do modificador static. 3.1 PADRÕES DE NOMENCLATURA Embora a linguagem Java em si não imponha um padrão de nomenclatura, aceitando códigos escritos com qualquer estilo, a comunidade de programadores Java adota certos padrões que são amplamente utilizados. Desde as principais e mais elaboradas bibliotecas internas do Java até os projetos mais simples utilizam os mesmos padrões que apresentaremos aqui facilitando a leitura dos códigos e padronizando códigos desenvolvidos por equipes de diversos programadores. O padrão principal da linguagem é o Camel Case, que consiste em descrever uma palavra composta ou frase sem dar espaços ou utilizar underline (ou sublinha), mas utilizando letras maiúsculas para indicar a letra inicial da próxima palavra. Suponha uma variável que representa o nome completo de um usuário poderia ser declarada no código como String nomeCompleto (letra maiúscula quando começa outra palavra) ao invés de nome_completo ou nomecompleto dentre outras opções. O nome Camel Case vem da semelhança das letras maiúsculas se sobressaindo no nome com as corcovas nas costas de um camelo. A Figura 2 ilustra a brincadeira com o nome. Figura 2 – Camel Case, padrão de escrita na programação Java Crédito: Eric Isselee/Shutterstock. 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 12/24 Dentro do Java, os padrões são os seguintes: Pacotes: são descritos inteiramente em letras minúsculas. Ex: com.empresa Classes: inicia com letra maiúscula e segue o Camel Case. Ex: Aluno Métodos, atributos e variáveis: iniciam com letra minúscula e seguem o Camel Case. Ex: nomeCompleto Constantes: inteiramente com letras maiúsculas separadas por underline. Ex: VALOR_PI A palavra reservada static possui dois usos na linguagem JAVA. Um quando é associada a um método e outro quando é associada a um atributo. Nos dois casos significa que o atributo ou método poderá ser acessado de forma independente de instâncias. Métodos e atributos sempre são relativos a um objeto, porém métodos e atributos estáticos são independentes. Um atributo estático pode ser entendido como uma variável global da classe, todas as instâncias podem trabalhar sobre a mesma variável. Veja o exemplo a seguir. As variáveis numeroComum e numeroEstatico se comportam de maneira diferente quando o método incremento for invocado por diferentes objetos. Se dois objetos invocarem o método incremento duas vezes cada um. numeroComum apresentará os valores 0 e 1 duas vezes, enquanto numeroEstatico apresentará os valores 0, 1, 2 e 3. No caso dos métodos estáticos, eles funcionam de forma semelhante a uma função comum do paradigma estruturado. Um bloco de código associado a um nome. Observe que o método main que 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 13/24 inicia a execução dos códigos Java também possui o modificador static. No exemplo anterior, temos uma classe com um método estático, que pode ser invocado por qualquer outra classe sem a necessidade de instanciar, mas colocando nome da classe antes do método com no comando: resultado = Aritmetica.somar(3,2); Esse comando irá chamar o método somar da classe Aritmética passando os valores 3 e 2 como parâmetro e retornando 5 para armazenar em uma variável de nome resultado. Como desafio experimente implementar os métodos somar, subtrair, multiplicar e dividir de forma estática dentro de uma classe denominada Aritmética. Acesse depois estes métodos a partir de outra classe. TEMA 4 – INTERAÇÃO ENTRE OBJETOS Neste tema, vamos reforçar o conceito de objetos e demonstrar as possibilidades de interação entre eles. A ideia da programação orientada a objetos consiste em mapear o problema considerando os objetos e a relação entre eles. Uma forma visual e muito prática de representar graficamente classes e suas relações é por meio da Unified Modeling Language (UML), em português, Linguagem de Modelagem Unificada. A UML é muito utilizada na documentação de projetos, especialmente de grande escala por sua facilidade de compreensão. É especialmente útil durante a etapa de projeto, pois conseguimos representar os elementos que compõe o domínio do nosso problema sem a necessidade de implementação. Na UML existem diversos tipos de diagramas que representam diferentes aspectos do projeto de software, entre eles o diagrama de classes que, como o nome sugere, representa justamente as 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 14/24 classes. Cada classe é graficamente apresentada com um retângulo contendo geralmente três áreas. Na parte superior, o nome da classe; no meio, os atributos; e na parte inferior, os métodos. Na Figura 3, a classe Aluno é representada. Figura 3 – Classe Aluno, com atributos métodos descritos Outra vantagem do UML é a possibilidade de demonstrar a relação entre as classes. Podemos, por exemplo, ter atributos de uma classe sejam objetos de outra classe ou que seus métodos recebam objetos como parâmetros. Suponha, por exemplo, que desejamos criar uma classe que represente uma turma de alunos. Podemos representar a classe turma da seguinte forma. 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 15/24 Nas linhas 5 até 7, temos os atributos. Cada turma é composta por uma quantidade variável de alunos portanto o primeiro atributo é um ArrayList, uma classe que implementa arrays com grande facilidade, pois possui diversos métodos para adicionar, remover, contar e buscar elementos de forma dinâmica. Para utilizar essa classe, é necessário importar o arquivo onde está definida, o comando de importação está na linha 2. Dentro do operador <> podemos definir o tipo do ArrayList, que no caso é um ArrayList da classe Aluno, ou seja, todo o elemento desse array representará um aluno diferente que está matriculado naquela turma, lembrando novamente que o comando new ArrayList() gera uma instância nova da classe ArrayList, sem esse comando listaAlunos seria uma referência, um ponteiro. Na linha 6, temos um elemento da classe Professor que representa o orientador daquela turma, também um objeto de uma classe que é um atributo nesta. Suponha que a classe Professor composta por alguns poucos atributos e um método info() análogo ao aluno. Nas linhas 9 até 11 da classe Turma, temos o método que adiciona um novo aluno no ArrayList que compõem todos os alunos. O método add da classe ArrayList adiciona ao final do array, se necessário, o método de forma transparente aloca memória extra para realizar a adição do elemento. Abaixo, na Figura 4 representamos a relação entre essas classesno diagrama de classes UML. No caso Turma, possui uma relação que chamamos de composição com relação às duas outras classes. O paradigma orientado a objetos tenta representar o domínio dos problemas de forma mais natural e semelhante ao problema real. Portanto, assim como na vida real, as turmas são compostas por um grupo de alunos da mesma forma a relação que entre elas é chamada de composição. Na Figura a indicação 0..1 significa que cada turma possui de zero até um professor e 0..* significa que a turma possui de zero até vários alunos. Mais detalhes sobre o digrama de classes UML serão apresentados na nossa disciplina em um momento oportuno. 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 16/24 Figura 4 – Classes Aluno, Professor e Turma representadas TEMA 5 – CONSTRUTORES No momento que instanciamos um objeto no Java internamente um bloco de código é executado, esse bloco de código é denominado construtor. Neste Tema vamos discorrer sobre como criar e utilizar os construtores. No bloco de código de um construtor qualquer código pode ser escrito, mas usualmente utilizamos para carregar alguma informação, especialmente informações que sejam cruciais para o funcionamento do objeto no momento da sua criação. Os construtores são criados de forma semelhante aos métodos, porém, devem possuir o mesmo nome da classe e não possuem valor de retorno. É possível também possuir diversos construtores para uma mesma classe variando apenas os parâmetros de entrada. Abaixo segue um código que exemplifica isso: 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 17/24 Mais uma vez exemplificamos utilizando a classe Aluno. Dessa vez criamos três construtores diferentes, linhas 6, 11 e 14. No primeiro construtor, temos três parâmetros sendo passados, ou seja, é permitido instanciar o objeto passando o nome, a matrícula e o CPF. Conforme vemos nas linhas 7, 8 e 9, os parâmetros passados para os atributos da classe Aluno. A palavra reservada this serve para distinguir os atributos dos parâmetros, visto que ambos possuem os mesmos nomes. Aluno mario = new Aluno(“Super Mario”, 1001, "111.111.111-1" ); Ao instanciar aluno desta maneira, ele já terá valores em todos os seus atributos sem necessidade de indicar um a um individualmente. Aluno luigi = new Aluno(“Super Luigi”); 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 18/24 Por termos criado três construtores, temos três opções de instanciação. Esta instanciação por ter apenas um parâmetro String invoca o construtor da linha 11 que também possui apenas um parâmetro String e atribui um valor inicial para o nome baseado no parâmetro do construtor, os demais atributos são ignorados. Note que os atributos são o que distingue diferentes construtores. Aluno yoshi = new Aluno(); Se instanciamos um objeto sem parâmetros, o construtor sem parâmetros é chamado, aquele presente na linha 14 irá imprimir uma mensagem. Quando criamos uma classe, um construtor vazio implícito que não executa nenhum código é criado. No entanto, a partir do momento que criamos um construtor qualquer, esse construtor vazio implícito deixa de existir. Para testar isso, observe que se apagarmos apenas o construtor da linha 14, essa instanciação vazia não vai funcionar, porém se apagarmos todos os construtores ele volta a funcionar novamente. 5.1 EXERCÍCIO Crie uma classe Horario com os atributos inteiros, hora, minuto e segundo. Crie três construtores, um que recebe três parâmetros e inicia os três atributos com os valores passados, outro que recebe apenas a hora e outro vazio. Caso algum dos valores inicializados não esteja no intervalo adequado (hora entre 0 e 23, minutos e segundos entre 0 e 59), inicialize o valor em questão em zero e emita uma mensagem de erro. FINALIZANDO Nesta aula, iniciamos propriamente dito o conteúdo relativo à orientação a objetos. Vimos o conceito de classe e objeto que é o mais importante dentro desse Paradigma. Também trabalhamos com métodos, o modificador static e vimos o conceito de construtores. Com o conteúdo desta aula, o(a) aluno(a) dá um passo importante na compreensão da orientação a objetos. Nessa fundamentação, o aluno tem a base para os conceitos mais aprofundados que seguem posteriormente. Em outra oportunidade, exploraremos os conceitos de visibilidade e encapsulamento, importantes para diminuir inconsistências nos códigos orientados a objeto. 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 19/24 APÊNDICE 1. Crie uma classe Nota, com três atributos reais chamados: nota1, nota2, nota3. E crie também dois métodos, cada um para calcular e retornar diferentes tipos de média. Média Aritmética; e Média ponderada (pesos 2 3 4). E na classe com o método main para testar: 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 20/24 2. Crie uma classe Conta, para administrar contas correntes de um banco com os atributos abaixo. 3. Complemente o exercício anterior implementando um método abaixo. (Código responde os exercícios 2 e 3) transfererir(Conta destino, float valor); E os métodos: 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 21/24 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 22/24 Na main para testar o código: O método deve transferir o valor passado por parâmetro do objeto conta que executa o método para a conta destino passada por parâmetro. 4. Crie uma classe Horario com os atributos inteiros, hora, minuto e segundo. Crie três construtores, um que recebe três parâmetros e inicia os três atributos com os valores passados. Outro que recebe apenas a hora e outro vazio. Caso algum dos valores inicializados não esteja no intervalo adequado (hora entre 0 e 23, minutos e segundos entre 0 e 59), inicialize o valor em questão em zero e emita uma mensagem de erro. 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 23/24 REFERÊNCIAS BARNES, D. J.; KÖLLING, M. Programação orientada a objetos com Java. 4. ed. São Paulo: Pearson Prentice Hall, 2009. DEITEL, P.; DEITEL, H. Java Como programar. 10. ed. São Paulo: Pearson, 2017. LARMAN, C. Utilizando UML e Padrões: Uma Introdução à Análise e ao Projeto Orientados a Objetos e ao Desenvolvimento Iterativo. 3. ed. Porto Alegre: Bookman, 2007. MEDEIROS, E. S. de. Desenvolvendo software com UML 2.0: definitivo. São Paulo: Pearson Makron Books, 2004. PAGE-JONES, M. Fundamentos do desenho orientado a objetos com UML. São Paulo: Makron Book, 2001. PFLEEGER, S. L. Engenharia de software: teoria e prática. 2. ed. São Paulo: Prentice Hall, 2004. 03/11/2022 11:22 UNINTER https://univirtus.uninter.com/ava/web/roa/ 24/24 SINTES, T. Aprenda programação orientada a objetos em 21 dias. 5. reimp. São Paulo: Pearson Education do Brasil, 2014. SOMMERVILLE, I. Engenharia de software. 9. ed. São Paulo: Pearson, 2011. 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 1/27 PROGRAMAÇÃO ORIENTADA A OBJETOS AULA 3 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 2/27 Prof. Leonardo Gomes CONVERSA INICIAL Nesta aula, vamos abordar a questão da visibilidade nas classes. Nas linguagens de programação estruturadas, existem diferentes técnicas para limitar quem tem acesso a determinadas funções e variáveis. Essa estratégia permite, entre outras coisas, esconder atributos e métodos que são utilizadas apenas internamente. Na orientação a objetos, isso é feito por meio de modificadores próprios que veremos em detalhes na sequência. Também vamos discutir algumas bibliotecas importantes dentro do Java que podem facilitar o desenvolvimento de aplicações. Objetivos da aula: ao final desta aula, esperamos atingir os seguintes objetivos que serão avaliados ao longo da disciplina da forma indicada. Quadro 1 – Objetivos Objetivos Avaliação 1 – Aplicar os conceitos de encapsulamentodentro da orientação a objetos. Questionário e questões dissertativas 2 – Desenvolver algoritmos que fazem uso correto dos modificadores public e private. Questionário e questões dissertativas 3 – Conhecer outras classes internas e importantes ao Java. Questionário e questões dissertativas TEMA 1 – VISIBILIDADE 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 3/27 Neste tema, vamos debater o conceito de visibilidade por meio dos modificadores public, protected e private que definem quais outras classes podem acessar seus atributos e métodos. Na orientação a objetos, à medida que os projetos crescem em tamanho, desenvolvemos um grande número de classes e se torna cada vez mais difícil lembrar de todos os métodos e atributos pertinentes para cada situação. Neste sentido, como já discutimos em aulas anteriores, é importante aplicarmos boas práticas na programação como escolher bons nomes para todos os elementos da classe e seguir padronizações no estilo de codificação. Outra prática que nos ajuda a simplificar o uso das classes é esconder métodos e atributos que sejam de uso interno da classe, de forma que, ao fazermos uso da classe posteriormente, não seja exibido detalhes de implementação, e sim apenas os métodos e atributos que sejam pertinentes. Antes da definição de cada método, atributo e classe, podemos colocar um dos três modificadores: Public: o elemento é público e pode ser acessado por qualquer outra classe sem restrições. Private: o elemento é privado e só pode ser acessado internamente na classe. Protected: o elemento é protegido e será acessado somente de dentro da própria classe, outras classes no mesmo pacote e também por classes filhas. A definição de classe filha será abordada em detalhes na aula de herança. Default (sem nenhum modificador): o elemento, neste caso, é acessível por classes dentro do mesmo pacote. Tabela 1 – Tabela demonstrativa dos modificadores de visibilidade 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 4/27 1.1 EXEMPLO COM CÓDIGO No exemplo a seguir, temos um código que demonstra o uso dessas palavras reservadas. 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 5/27 Em relação ao código acima, digamos que o atributo matrícula não seja uma informação de interesse para quem utiliza a classe Aluno, mas que internamente na classe é uma informação importante para talvez vincular o aluno em um banco de dados, por exemplo. Para essas situações, atributos como matricula podem ser definidos como privados, garantindo uma abstração que invisibiliza informações que sejam pertinentes apenas para o contexto interno da classe. Ainda no exemplo, os atributos cpf e nome, por serem pertinentes para quem for utilizar a classe, ficam públicos. Observe que o atributo notas foi definido como protected, por algum motivo poderia não ser interessante permitir seu público e direto ao array que guarda os dados, mas ao mesmo tempo suponha que existam algumas classes específicas que gostaria de oferecer acesso, nesta situação, nem public e nem private atendem a necessidade, protected concede visibilidade apenas 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 6/27 para classes relacionadas a classe Aluno, mais especificamente suas classes filhas, o conceito de classe filha e Herança será visto em detalhes nas próximas aulas. 1.2 VISIBILIDADE NO DIAGRAMA DE CLASSES UML Nas aulas anteriores, demonstramos como representar classes utilizando diagrama de classes UML. Nesse diagrama, podemos também representar a visibilidade dos métodos e atributos utilizando os seguintes símbolos: Quadro 2 – Símbolos e significados Símbolo Significado + Público - Privado # Protegido A seguir, o exemplo da classe Aluno. Figura 1 – Classe Aluno Desafio: seguindo o exemplo da classe Aluno, desenvolva o diagrama de classe UML para descrever um ITEM qualquer que seja comercializado por uma loja on-line, não existe uma resposta certa, cada contexto requer atributos e métodos diferentes, mas pense como imagina sendo a melhor forma. 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 7/27 Quais informações você acredita serem importantes armazenar para exibir ao comprador e registrar a venda na loja? Quais atributos imagina que seriam privados por serem utilizados apenas internamente? E quais seriam públicos por interagir com outros objetos? TEMA 2 – ENCAPSULAMENTO Entende-se que o Paradigma Orientado a Objetos possui três pilares, herança, polimorfismo e o encapsulamento. Alguns autores defendem a abstração como um quarto pilar, no entanto, ela pode também ser entendida como parte do encapsulamento. Neste tema, vamos debater em mais detalhes os benefícios e práticas do encapsulamento. Quando pensamos em uma cápsula no mundo real, fora do contexto da programação, imaginamos o invólucro de algum objeto sensível e/ou perigoso, que serve tanto para proteger o conteúdo interno do mundo exterior quanto o mundo exterior desse conteúdo interno. Se pensarmos no monitor para computadores, ele é um exemplo de encapsulamento. Seus componentes ficam resguardados pela estrutura de plástico que o envolve, evitando que quem manipula o equipamento receba descargas elétricas ou danifique o aparelho. Na programação orientada a objetos, tentamos abstrair no código a interação entre os objetos reais, portanto, a lógica do encapsulamento é a mesma, como boa prática de programação orientada a objetos, devemos utilizar as propriedades public, private e protected para invisibilizar os componentes internos das classes que não são pertinentes e deixar visível o estritamente necessário. Dessa forma, o programador que fará uso da classe encapsulada tem uma camada extra de segurança no momento que fizer uso da classe. No contexto da computação, chamamos de interface os elementos responsáveis por conectar de forma física ou lógica diferentes objetos ou partes distintas de um sistema. No caso do exemplo dado do monitor, a conexão hdmi compõe sua interface, já no caso de uma classe sua interface se dá por meio dos seus métodos que recebem e devolvem informações. Em uma classe que segue boas práticas de encapsulamento, seria possível trocar a classe por outra que possua a mesma interface (métodos com os mesmos nomes e parâmetros) e, por mais que as suas implementações internas mudem, o sistema continuará funcional sem maiores mudanças. 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 8/27 No mundo físico, mais uma vez o exemplo do monitor, se trocarmos o equipamento por outro, o sistema continua funcionando sem maiores complicações, desde que ambos possuam a mesma interface (cabo HDMI) basta desconectar um e conectar o outro, mesmo que sejam monitores com especificações diferentes (tecnologia LCD ou LED, tamanhos diferentes etc.). Já no contexto da computação acontece o mesmo se temos duas classes com uma mesma interface, mas que internamente resolve códigos de maneira distintas, por exemplo, utilizando diferentes estruturas de dados ou aplicando diferentes algoritmos para ordenarem seus dados, o restante do código ficaria inalterado. O que possibilita inclusive diferentes equipes que não mantém contato algo produzirem soluções que conversem. Tal qual o exemplo do monitor que mesmo quando produzidos por uma empresa diferente do restante do equipamento continua funcionando. Em resumo, a vantagem do encapsulamento são: 1. A abstração oferecida em que o funcionamento interno dos objetos da classe não fica visível ao programador que utiliza a classe. 2. A possibilidade de acrescentar funcionalidades à classe desde que respeitando a interface original manterá o sistema funcional sem alterações. 3. Simplificação da utilização dos objetos em um alto nível acelera o desenvolvimento dos códigos. 4. O sistema fica robusto a mudanças internas, mesmo uma substituição completa do código que poderia até mesmo ser desenvolvidopor outra equipe que não manteve contato com a primeira, bastando respeitar a interface. 2.2 EXEMPLO JAVA DO PARADIGMA ORIENTADO A OBJETO Uma das práticas do encapsulamento consiste em criar métodos chamados de getter e setter para conceder acesso aos atributos da classe. A ideia está em deixar todos os atributos (variáveis internas da classe), como privadas e aquelas que convém ao usuário acessar são disponibilizadas por meio desses métodos. No inglês, get significa pegar, e os métodos getters são métodos que pegam os valores daqueles atributos e retornam para quem chamou o método enquanto set significa definir, servindo justamente para definir os atributos com o valor passado por parâmetro. Essa lógica é aplicada às mais diversas linguagens de programação com pequenas variações, mas a ideia de restringir ao 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 9/27 acesso, encapsulando a classe, é a mesma. No caso do Java, vejamos um exemplo a seguir com uma classe que representa horários. Observe o padrão de nomenclatura das funções setHora e getHora para o atributo hora, esse padrão é amplamente adotado na comunidade de programadores sempre com a mesma funcionalidade, definir e retornar o valor para determinado atributo. No caso, é possível inclusive realizar validação no momento de definir o dado para garantir a integridade a informação. Neste exemplo, não seria possível definir uma hora fora do intervalo 0-23. Suponha que essa classe seja adota em aplicações críticas como as bancárias então garantir a integridade se torna ainda mais importante. Desafio: desenvolva uma classe Data, com atributos, dia, mês e ano encapsulados com get/set. Para simplificar, assuma que todo mês pode seja composto por 30 dias. 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 10/27 TEMA 3 – COLLECTIONS Neste Tema, vamos debater uma importante API em Java chamada Collections, essa API consiste em um conjunto de classes que implementam diferentes estruturas de dados, essas estruturas são encapsuladas respeitando uma mesmo acordo, interface, o que traz diversos facilidades. Por estrutura de dados entenda a estratégia que você utiliza para organizar seus dados na memória. Você certamente deve estar familiarizado com a estrutura de dados array (ou lista) e matriz. Porém, existem diversas outras estruturas, como pilha, fila, hash, árvores, lista encadeada, entre outros. O estudo de estrutura de dados é todo um campo dentro da ciência da computação com diversas ramificações e que tem uma importância muito grande, adotar a estrutura de dados correta em cada situação pode ser a diferença entre um algoritmo que leva dias para executar ou poucos minutos. No entanto, implementar as estruturas de dados adequadamente toma tempo e, por possuir soluções bem conhecidas, a API Collections já nos traz as classes prontas com essas estruturas; dessa forma, não precisamos “reinventar a roda”. 3.1 PRINCIPAIS CLASSES DA COLLECTIONS Dentro das Collections, existem diversas estruturas de dados, de forma geral, elas são divididas em quatro grupos, dispostos em azul na Figura 1. O grupo list (listas), que funciona como uma sequência ordenada de valores, o grupo set (conjuntos), que forma um agrupamento bde itens sem ordem definida, o grupo map (mapas), que mapeia dados chamados chaves para outros dados chamados de valores e, por fim, o grupo queue (filas), que implementam um tipo de array em que a posição de cada elemento define a prioridade dele em relação aos demais, uma abstração chamada de fila de prioridades. Na Figura 2, vemos os quatro grupos e suas classes e, ao longo do texto, descrevemos algumas das que consideramos mais importantes. Figura 2 – Tabela demonstrativa dos modificadores de visibilidade 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 11/27 ArrayList é uma das classes mais comuns dentro da API Collections, como já apresentada anteriormente ele representada um array dinâmico. Os elementos dentro dela possuem uma ordem definida e trazem métodos de manipulação, como remoção, inserção, busca, entre outros. LinkedList é outra classe que também implementa um array dinâmico com as mesmas funcionalidades do ArrayList tradicional, no entanto, sua implementação interna utiliza a estratégia de lista ligada e realiza as operações de remoção e inserção de forma muito mais rápida e a busca por elementos de forma muito mais lenta em comparação ao ArrayList tradicional. De maneira geral, é mais comum ao longo da execução de um programa que mais buscas sejam executadas do remoções/inserções, portanto, o ArrayList de forma geral é o mais indicado, entretanto, para aqueles casos em que isso não ocorre, contamos com essa alternativa. HashSet na computação, o termo Hash diz respeito a uma função que transforma um valor em outro, e a palavra Set tem diversos significados diferentes sendo que, nessa situação específica, significa conjunto. Então uma HashSet é um conjunto de elementos organizados por meio de uma função Hash. Ela realiza operações de adição, remoção e busca de forma muito rápida, contudo, não garante uma ordem dos elementos. LinkedHashSet é semelhante a HashSet, porém, ele armazena a ordem em que os elementos foram adicionados. HashMap é a estrutura de dados também baseada em Hash, com a diferença que é possível mapear (daí o nome Map) uma ID de um tipo diverso. Por exemplo, podemos ordenar os filmes de 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 12/27 um catálogo não por um valor inteiro, mas por uma string contendo o nome do filme seguido do ano de exibição. Não possui ordem garantida. TreeMap semelhante a HashMap, entretanto, também armazena a ordem dos itens, essa ordem pode ser livremente manipulada combinando as características de em um array. LinkedHashMap é semelhante a HashMap, todavia, internamente também armazena a ordem em que os elementos foram adicionados. Queue é uma estrutura de dados geralmente adotada para representar filas de prioridade, queue no inglês significa fila. Ela pode implementar uma fila de prioridade comum, semelhante a uma fila convencional no mundo real em que o primeiro elemento a entrar é o primeiro a ser atendido. Stack é outra classe semelhante a fila de prioridades, mas implementa uma fila reversa à ordem de inserção, o último elemento adicionado é o primeiro a ser tratado, conceito denominado pilha, se empilharmos diversos objetos um sobre o outro, o último objeto empilhado será o primeiro que vamos acessar. 3.2 EXEMPLO DE USO DE ARRAYLIST/LINKEDLIST A seguir, demonstramos alguns métodos aplicados nas classes ArrayList e LinkedList. 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 13/27 3.3 EXEMPLO DE USO DE HASHMAP A seguir, o código demonstra o uso da classe HashMap. As classes baseadas na estrutura de mapa possuem o conceito de chave e valor. A chave é o que indexa ela e o valor o conteúdo dentro daquele índice. No código a seguir, o HashMap capitais indexa capitais (valor) por meio do nome do país (chave). É diferente de termos um array composto de uma struct contendo o par de strings, pois, nesse caso, o índice continuaria sendo um inteiro, marcando a posição, já na Hash, o que marca a posição é o próprio nome da capital. 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 14/27 3.4 EXEMPLO DE USO DE HASHSET A seguir, o código demonstra o uso da classe HashSet. As classes baseadas na estrutura de Conjunto armazenam dados sem se preocupar em manter uma ordem, o conceito de ordem em conjunto simplesmente não existe, se adicionarmos um item primeiro, ele não estará na frente do que adicionarmos por segundo. Sem ter a necessidade de se preocupar com ordem, certos métodos se tornam mais rápidos, por exemplo, descobrir se determinado elemento existe ou não é muito mais rápido em uma estrutura de dados de Conjunto em comparação à Lista. 03/11/2022 11:31 UNINTERhttps://univirtus.uninter.com/ava/web/roa/ 15/27 3.5 EXEMPLO DE USO DE PRIORITYQUEUE A seguir, o código demonstra o uso da classe PriorityQueue. As classes baseadas no grupo das filas de prioridade armazenam dados se preocupando de forma muito restrita com a ordem, existem filas em que desejamos visualizar os elementos conforme a ordem que foram adicionados (fila tradicional) ou na ordem reversa ao que foram adicionados (pilha). É indicado adotar esse tipo de estrutura quando temos dois tipos de entidades distintas, um tipo produzindo algum tipo de dado e outro consumindo os dados. O exemplo clássico é a gestão de documentos de uma impressora. Podemos ter vários serviços gerando dados para serem impressos e existe a impressora que consome (imprime) os dados na ordem que foram adicionados na fila. 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 16/27 3.6 MÉTODOS ESTÁTICOS COLLECTIONS Além das classes, existem vários métodos estáticos dentro do framework Collections que implementam soluções para problemas que são relativamente comuns entre os algoritmos. Por exemplo, o método sort implementa a ordenação dos elementos que compõem um objeto da classe Collections, ou seja, podemos com uma única chamada colocar os itens de um ArrayList em ordem crescente. A seguir, uma lista com exemplos de alguns dos métodos mais importantes: Sort (List<> lista): coloca em ordem crescente os itens da lista passada por parâmetro. Shuffle (List<> lista, Random rnd): embaralha de forma aleatória os elementos da lista passada por parâmetro, a aleatoriedade do embaralhamento é dada pelo objeto da classe Random passado por parâmetro também. Max (Collection<> coll, Comparator<> comp): retorna o maior elemento, aceita tanto lista, quanto hash. Como segundo parâmetro, você pode indicar como deseja realizar a comparação com um objeto da classe Comparator, caso passe null como segundo parâmetro, a ordem natural será adotada. 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 17/27 Min (Collection<> coll, Comparator<> comp): análogo ao max, porém, retorna o menor elemento. Reverse (List<> lista): coloca todos os itens em ordem reversa. O código a seguir exemplifica o uso desses métodos: 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 18/27 TEMA 4 – ITERATOR 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 19/27 Neste tema, vamos discutir formas de navegar pelos dados de uma das classes presentes no framework Collections, vamos dar destaque especial a uma estratégia chamada Iterator. Quando desejamos visitar os dados em uma estrutura de dados, as estratégias mudam dependendo da estrutura, listas contam com índices inteiros, mapas são indexados pelas chaves que foram definidas, conjuntos não possuem forma de indexação alguma. No entanto, os iterators são uma ferramenta poderosa nesse sentido, pois com eles é possível navegar pelos dados independentes da classe Collections utilizada. Vamos ver alguns exemplos de código. 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 20/27 Nesse código, temos três formas diferentes de calcular a soma dos elementos de um ArrayList, vamos discutir cada uma dessas formas: 1 - Das linhas de código 7 até 10, temos a forma tradicional, utilizando um for indexando a lista pelos seus índices indo de 0 até o tamanho total da lista.size(). 2 - Na sequência, temos o que chamamos de um for each, nas linhas 12 até 15, um comando de repetição for que em vez de ser dividido em três partes é dividido em duas e que dispensa o uso de índices, ele executa o loop para cada elemento daquele Collection que for passada depois dos dois pontos, no caso lista. A cada execução, a variável que vai antes dos dois pontos, no caso item, receberá um valor distinto. Esse tipo de for é interessante por ser simples e também se aplicar a diferentes classes dentro das Collections, no entanto, ela é bastante engessada não permitindo operações mais elaboradas, como remover um item específico que foi visitado, entre outras operações. 3 - Na sequência, linha 17 em diante, temos a demonstração do uso do Iterator. Ele é compatível com diversos estruturadas de dados diferentes, nas linhas 18, 19 e 20, vemos o iterator sendo utilizado respectivamente com mapa, conjunto e lista. O código é o mesmo para todos. o iterator é uma espécie de ponteiro para o elemento da Collection. Na linha 21, o método hasNext() verifica se existe um próximo elemento e retorna verdadeiro ou falso. Na linha 22, o método next() atualiza o iterador para o próximo item da coleção. Como os ponteiros iteradores podem apontar para qualquer tipo primitivo ou objeto, é necessário indicar ao compilador como aquele item deve ser interpretado, no caso (int) é o que chamamos de cast-type na programação e serve para indicar ao compilador que o comando que vem na sequência deve ser lido como um inteiro. Importante observar que o cast-type não é uma conversão, ele não modifica o dado, apenas muda a forma como aquele dado é visualizado pelo compilador, o uso inadequado desse comando pode gerar exceções na execução do programa. O iterator é bastante simples e compatível com diversas estruturas de dados, o que o torna particularmente útil para criar um código flexível e independente da estrutura de dados adotada. Além do exemplo visto no código anterior, seria possível também navegar de forma reversa, de trás para frente como no código a seguir. 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 21/27 Observe que aqui é utilizada a classe ListIterator em vez de apenas Iterator, como visto no exemplo anterior. Neste caso, é necessário especificar que o iterator age sobre listas, pois nelas existe a ideia de uma ordem sequencial dos dados, em outras estruturas, como Map e Set, essa ordem não existe por padrão. O método listIterator (linha 1) aceita como parâmetro uma posição, 0 para primeira posição, 1 para segunda posição e assim por diante. No caso, o tamanho da lista é o parâmetro, portanto, o retorno será um iterator que aponta para a última posição. O método hasPrevious() do inglês se traduz como “existe um anterior?” e como o nome sugere ele retorna true ou false como resposta. Por sua vez, o método previous(), do inglês “anterior”, retorna o iterator em si da posição anterior. Em outras palavras, enquanto existir um elemento anterior, o programa segue imprimindo na tela o anterior do anterior do anterior e assim por diante. Também é possível remover elementos apontados pelo Iterator, segue novo código abaixo. 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 22/27 03/11/2022 11:31 UNINTER https://univirtus.uninter.com/ava/web/roa/ 23/27 No código acima, temos uma lista de strings com nomes de frutas e todos os elementos são impressos na tela, antes e depois da string “Laranja” ser removida da lista. Na linha 17, vemos o loop utilizando while e o método “hasNext()” já discutido anteriormente, na linha 19, fazemos uma comparação para decidir se a string que o iterator aponta é realmente “Laranja”, se for o caso, ela é removida com o método remove(), então o loop é encerrado utilizando a instrução break. TEMA 5 – CLASSE LOCALDATE Em diversos projetos, nos deparamos com o desafio de como lidar com a representação de datas e horários, essa é uma questão especialmente comum em projetos quando envolve banco de dados e acesso web. O Java conta com algumas soluções implementadas internamente. Neste Tema, vamos discutir as principais soluções. Originalmente, nas primeiras versões do Java, foi implementada uma classe para datas chamada java.util.Date, essa classe originalmente possuía diversas limitações e, por isso, em uma atualização do Java, surgiu a classe java.util.Calendar, que também não atendia às necessidades da comunidade de desenvolvimento Java, por isso, se popularizou muito uma biblioteca chamada Joda Time. A Oracle, ao identificar
Compartilhar