Introdução á Linguagem de Programação JAVA www.primebean.com.br [email protected] www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA Introdução á Linguagem de Programação Java por Joey Decurcio Edição de 31/03/2014 © 2014 Primebean – Soluções em Multiplataforma. Todos os direitos reservados. Tecnologia O Conteúdo desta apostila foi elaborada através de pesquisas realizadas via internet, livros, revistas, etc. Primebean – Soluções em Tecnologia Multiplataforma. www.primebean.com.br [email protected] +55 (18) 99111-0896 www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA Sumário 1. Introdução.........................................................................................................................................1 1.1 Oque é Java................................................................................................................................1 1.2 Histórico.....................................................................................................................................1 1.3. Padronização.............................................................................................................................3 1.4. Principais Características da Linguagem Java..........................................................................3 1.5. Máquina Virtual Java................................................................................................................4 1.6. Extensões..................................................................................................................................6 1.7. Frameworks..............................................................................................................................7 1.8. Ambientes de desenvolvimento................................................................................................7 1.9. Certificações.............................................................................................................................8 1.10. Comunidade............................................................................................................................9 1.11. Licença....................................................................................................................................9 1.12. O que é necessário para programar em JAVA.........................................................................9 2. Desenvolvendo o Primeiro Programa em Java...............................................................................11 2.1. public class MeuPrimeiroPrograma........................................................................................12 2.2. public static void main............................................................................................................12 2.3. (String[ ] args).........................................................................................................................13 2.4. Inicio e Fim { }.......................................................................................................................13 2.5. System.out.println...................................................................................................................13 2.6. ("Bem vindo ao mundo Java!")...............................................................................................13 3. Regras e convenções de nomenclatura...........................................................................................14 3.1. Nome de Classes.....................................................................................................................15 3.2. Nome de Pacotes.....................................................................................................................15 3.3. Criando Pacotes......................................................................................................................16 3.4. Definindo Pacotes...................................................................................................................17 3.5. Importando Pacotes.................................................................................................................17 3.6. importando um pacote usamos o comando import.................................................................18 3.7. Nome de atributos ou variáveis..............................................................................................19 3.8. Nome de atributos finais ou constantes..................................................................................19 3.9. Tipos de dados e declaração de atributos................................................................................20 3.10. Atribuição de Valores a Variáveis ou Atributos....................................................................22 3.11. Inicialização de variáveis ou atributos..................................................................................22 3.12. Método de Saída Padrão.......................................................................................................25 3.13. Controle de Texto..................................................................................................................26 3.14. Apresentando valores de variáveis ou atributos....................................................................27 3.15. Concatenação........................................................................................................................28 3.15.1. Cuidados ao concatenar.................................................................................................30 www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 3.16. Operadores e Processos........................................................................................................31 4. Controle de Fluxo...........................................................................................................................32 4.1. Execução condicional - IF e ELSE.........................................................................................33 4.2.1. Usando IF........................................................................................................................33 4.2.2. Usando ELSE..................................................................................................................34 4.3. Switch, Case e Default............................................................................................................35 4.3.1. Default.............................................................................................................................36 4.4. Break e Continue....................................................................................................................37 4.4.1. Break...............................................................................................................................38 4.4.2. Continue..........................................................................................................................38 4.3. Estruturas de Repetição..........................................................................................................39 4.3.1. While....................................................................................................................................40 4.3.2. Do While..............................................................................................................................41 4.3.3. For........................................................................................................................................41 5. O que são e para que servem as Classes e Objetos.........................................................................43 5.1. O que são Classes e Objetos em Java.....................................................................................43 5.2. Utilidade das Classes e Objetos em Java................................................................................44 5.2.1. Agrupar coisas semelhantes............................................................................................44 5.2.2. Crie uma vez, use quantas vezes quiser..........................................................................45 5.2.3. Altere uma parte do código, e a mudança se propagará em todo o código.....................45 5.2.4. Classe à parte, vida à parte..............................................................................................45 5.2.5.Como saber quando usar Classes e Objetos em Java.......................................................46 5.3. Criação de Classe....................................................................................................................47 5.4. Métodos Construtores.............................................................................................................48 6. Estrutura de Dados.........................................................................................................................49 6.1. Vetores e Matrizes...................................................................................................................52 6.2. Vetor........................................................................................................................................53 6.2.1 Inicialização direta de Vetor.............................................................................................55 6.3. Matrizes..................................................................................................................................55 6.4. ArrayList.................................................................................................................................56 6.4.1. O que são ArrayList em Java..........................................................................................57 6.4.2. Como declarar e usar ArrayList em Java........................................................................58 6.4.3. Exemplo de uso do ArrayList..........................................................................................58 7. Constantes.......................................................................................................................................61 8. Funções...........................................................................................................................................63 8.1. Criando funções sem argumentos...........................................................................................63 8.2. Funções com argumentos........................................................................................................64 8.3. Funções que retornam valores................................................................................................65 9. Igualdade de Objetos em java - equals() e hashCode()..................................................................67 9.1. Equals:....................................................................................................................................69 9.2. HashCode:...............................................................................................................................71 10. Representação textual de objetos - método toString()..................................................................73 www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 11. Instanciando Objetos....................................................................................................................76 12. Auto Referencia de Objetos - This...............................................................................................77 13. Sobrecarga de métodos.................................................................................................................78 14. Acesso a Membros e Métodos......................................................................................................81 15. Encapsulamento - public, private e protected...............................................................................84 15.1. Public....................................................................................................................................85 15.2. Private...................................................................................................................................86 15.3. Protected...............................................................................................................................86 15.4. Sem Modificador (Padrão)....................................................................................................86 15.5. Métodos Acessores - Getters e Setters..................................................................................87 15.5.1. Set..................................................................................................................................87 15.5.2. Get.................................................................................................................................88 15.5.3. Is....................................................................................................................................88 16. Herança.........................................................................................................................................89 17. Enum.............................................................................................................................................93 18. Interfaces......................................................................................................................................98 18.1. Usando uma Interface em uma Classe..................................................................................98 19. Annotations.................................................................................................................................102 19.1. Uso de Annotations.............................................................................................................102 19.2. Criando uma Annotation.....................................................................................................103 19.3. Adicionar Annotations ao Javadoc......................................................................................105 20. Classes Abstratas e Métodos Abstratos......................................................................................105 21. Polimorfismo..............................................................................................................................110 22. Typecast - Casting.......................................................................................................................112 22.1. Typecast de Dados Primitivos.............................................................................................113 22.2. Typecast de Classes e Objetos.............................................................................................114 23. Instanceof....................................................................................................................................116 24. Generics......................................................................................................................................117 24.1.Criando classes usando generics..........................................................................................117 24.2. Instanciar uma classe genérica............................................................................................119 25. Exceções.....................................................................................................................................121 25.1. Try e Catch..........................................................................................................................121 25.2. Finally.................................................................................................................................122 26. Classes Numéricas......................................................................................................................124 26.1. Obtendo Tipo Primitivo de um Objeto Numérico..............................................................125 26.2. Comparando Números........................................................................................................126 26.7. Classes Integer, Float, Short, Byte, Long e Double............................................................126 26.7.1. Análise de Dados.........................................................................................................126 26.7.2. Conversão Para String.................................................................................................128 26.8. Classe Math.........................................................................................................................128 26.8.1. Constantes...................................................................................................................129 26.8.2. Máximo e Mínimo......................................................................................................130 www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 26.8.3. Potências e raízes........................................................................................................130 26.8.4. Logaritmo....................................................................................................................131 26.8.5. Arredondamentos e Valores Absolutos........................................................................132 26.8.6. Trigonometria..............................................................................................................133 26.8.7. Números Randômicos.................................................................................................134 27. String..........................................................................................................................................135 27.1. Concatenação de Strings.....................................................................................................137 27.2. Tamanho da string - length()...............................................................................................137 24.3. Letras Maiúsculas e Minúsculas.........................................................................................138 24.4. Comparação........................................................................................................................138 24.5. Início e fim..........................................................................................................................140 24.6. Caracter na posição.............................................................................................................141 24.7. Índice da String...................................................................................................................141 24.8. Substituir string ou parte dela.............................................................................................142 24.9. Verificar conteúdo da string................................................................................................143 24.10. Dividindo em vários vetores ou arrays.............................................................................143 24.11. Substring...........................................................................................................................144 25. Manipulando datas em Java........................................................................................................145 25.1. Date(java.util.Date).............................................................................................................146 25.3. DateFormat(java.text.DateFormat).....................................................................................148 26. Uma Introdução à API Swing.....................................................................................................151 26.1. JoptionPane.........................................................................................................................151 26.2. Caixas de Diálogo Input Text.............................................................................................152 26.3. Caixas de Diálogo Confirm................................................................................................153 26.4. Caixa de Diálogo de Mensagem.........................................................................................154 26.5. Input Dialogs.......................................................................................................................156 26.5.1. Obter valor de showInputDialog.................................................................................158 26.5.2. Input Dialog com lista de opções................................................................................159 www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 1 1. Introdução 1.1 Oque é Java Java é uma linguagem de programação orientada a objeto desenvolvida na década de 90 por uma equipe de programadores chefiada por James Gosling, na empresa Sun Microsystems. Diferentemente das linguagens convencionais, que são compiladas para código nativo, a linguagem Java é compilada para um "bytecode" que é executado por uma máquina virtual. A linguagem de programação Java é a linguagem convencional da Plataforma Java, mas não sua única linguagem. 1.2 Histórico Em 1991, na Sun Microsystems, foi iniciado o Green Project, o berço do Java, uma linguagem de programação orientada a objetos. Os mentores do projeto eram Patrick Naughton, Mike Sheridan, e James Gosling. O objetivo do projeto não era a criação de uma nova linguagem de programação, mas antecipar e planejar a “próxima onda” do mundo digital. Eles acreditavam que, em algum tempo, haveria uma convergência dos computadores com os equipamentos e eletrodomésticos comumente usados pelas pessoas no seu dia-a-dia. Para provar a viabilidade desta idéia, 13 pessoas trabalharam arduamente durante 18 meses. No verão de 1992 eles emergiram de um escritório de Sand Hill Road no Menlo Park com uma demonstração funcional da idéia inicial. O protótipo se chamava *7 (leia-se “StarSeven”), um controle remoto com uma interface gráfica touchscreen. Para o *7, foi criado um mascote, hoje amplamente conhecido no mundo Java, o Duke. O trabalho do Duke no *7 era ser um guia virtual ajudando e ensinando o usuário a utilizar o equipamento. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 2 O *7 tinha a habilidade de controlar diversos dispositivos e aplicações. James Gosling especificou uma nova linguagem de programação para o *7. Gosling decidiu batizá-la de “Oak”, que quer dizer carvalho, uma árvore que ele podia observar quando olhava pela sua janela. O próximo passo era encontrar um mercado para o *7. A equipe achava que uma boa idéia seria controlar televisões e vídeo por demanda com o equipamento. Eles construíram um demo chamado MovieWood, mas infelizmente era muito cedo para que o vídeo por demanda bem como as empresas de TV a cabo pudessem viabilizar o negócio. A idéia que o *7 tentava vender, hoje já é realidade em programas interativos e também na televisão digital. Permitir ao telespectador interagir com a emissora e com a programação em uma grande rede cabos, era algo muito visionário e estava muito longe do que as empresas de TV a cabo tinham capacidade de entender e comprar. A idéia certa, na época errada. Entretanto, o estouro da Internet aconteceu e rapidamente uma grande rede interativa estava se estabelecendo. Era este tipo de rede interativa que a equipe do *7 estava tentando vender para as empresas de TV a cabo. E, da noite para o dia, não era mais necessário construir a infra-estrutura para a rede, ela simplesmente estava lá. Gosling foi incumbido de adaptar o Oak para a Internet e em janeiro 1995 foi lançada uma nova versão do Oak que foi rebatizada para Java. A tecnologia Java tinha sido projetada para se mover por meio das redes de dispositivos heterogêneos, redes como a Internet. Agora aplicações poderiam ser executadas dentro dos browsers nos Applets Java e tudo seria disponibilizado pela Internet instantaneamente. Foi o estático HTML dos browsers que promoveu a rápida disseminação da dinâmica tecnologia Java. A velocidade dos acontecimentos seguintes foi assustadora, o número de usuários cresceu rapidamente, grandes fornecedores de tecnologia, como a IBM anunciaram suporte para a tecnologia Java. Desde seu lançamento, em maio de 1995, a plataforma Java foi adotada mais rapidamente do que qualquer outra linguagem de programação na história da www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 3 computação. Em 2003 Java atingiu a marca de 4 milhões de desenvolvedores em todo mundo. Java continuou crescendo e hoje é uma referência no mercado de desenvolvimento de software. Java tornou-se popular pelo seu uso na Internet e hoje possui seu ambiente de execução presente em web browsers, mainframes, SOs, celulares, palmtops e cartões inteligentes, entre outros. 1.3. Padronização Em 1997 a Sun Microsystems tentou submeter a linguagem a padronização pelos orgãos ISO/IEC e ECMA, mas acabou desistindo. Java ainda é um standard de fato, que é controlada através da JCP Java Community Process. Em 13 de Novembro de 2006, a Sun lançou a maior parte do Java como Software Livre sob os termos da GNU General Public License (GPL). Em 8 de Maio de 2007 a Sun finalizou o processo, tornando praticamente todo o código Java como software de código aberto, menos uma pequena porção que a Sun não possui copyright. 1.4. Principais Características da Linguagem Java A linguagem Java foi projetada tendo em vista os seguintes objetivos: • Orientação a objeto - Baseado no modelo de Smalltalk e Simula67; • Portabilidade - Independência de plataforma - "write once run anywhere"; • Recursos de Rede - Possui extensa biblioteca de rotinas que facilitam a cooperação com protocolos TCP/IP, como HTTP e FTP; • Segurança - Pode executar programas via rede com restrições de execução; Além disso, podem-se destacar outras vantagens apresentadas pela linguagem: www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 4 • Sintaxe similar a Linguagem C/C++. • Facilidades de Internacionalização - Suporta nativamente caracteres Unicode; • Simplicidade na especificação, tanto da linguagem como do "ambiente" de execução (JVM); • É distribuída com um vasto conjunto de bibliotecas (ou APIs); • Possui facilidades para criação de programas distribuídos e multitarefa (múltiplas linhas de execução num mesmo programa); • Desalocação de memória automática por processo de coletor de lixo (garbage collector); • Carga Dinâmica de Código - Programas em Java são formados por uma coleção de classes armazenadas independentemente e que podem ser carregadas no momento de utilização. 1.5. Máquina Virtual Java Programas Java não são traduzidos para a linguagem de máquina,como outras linguagens estaticamente compiladas e sim para uma representação intermediária, chamada de bytecodes. Os bytecodes são interpretados pela máquina virtual Java (JVM - Java Virtual Machine). Muitas pessoas acreditam que por causa desse processo, o código interpretado Java tem baixo desempenho. Durante muito tempo esta foi uma afirmação verdadeira. Porém novos avanços têm tornado o compilador dinâmico (a JVM), em muitos casos, mais eficiente que o compilador estático. Java hoje já possui um desempenho próximo do C++. Isto é possível graças a otimizações como a compilação especulativa, que aproveita o tempo ocioso do processador para pré-compilar bytecode para código nativo. Outros mecanismos ainda mais elaborados como o HotSpot da Sun, que guarda informações disponíveis somente em tempo de execução (ex.: número de usuários, processamento usado, memória disponível), para otimizar o funcionamento da JVM, possibilitando que a JVM vá www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 5 "aprendendo" e melhorando seu desempenho. Isto é uma realidade tão presente que hoje é fácil encontrar programas corporativos e de missão crítica usando tecnologia Java. No Brasil, por exemplo, a maioria dos Bancos utiliza a tecnologia Java para construir seus home banks, que são acessados por milhares de usuários diariamente. Grandes sítios como o eBay utilizam Java para garantir alto desempenho. E a cada ano Java tem se tornado mais rápido, na medida que se evolui o compilador dinâmico. Essa implementação no entanto tem algumas intrínsecas. A pré-compilação exige tempo, o que faz com que programas Java demorem um tempo significativamente maior para começarem a funcionar. Soma-se a isso o tempo de carregamento da máquina virtual. Isso não é um grande problema para programas que rodam em servidores e que deveriam ser inicializados apenas uma vez. No entanto isso pode ser bastante indesejável para computadores pessoais onde o usuário deseja que o programa rode logo depois de abri-lo. A próxima versão da máquina virtual produzida pela Sun promete novos recursos que irão minimizar este fato. O Java ainda possui uma outra desvantagem considerável em programas que usam bastante processamento numérico. O padrão Java tem uma especificação rígida de como devem funcionar os tipos numéricos. Essa especificação não condiz com a implementação de pontos flutuantes na maioria dos processadores o que faz com que o Java seja significativamente mais lento para estas aplicações quando comparado a outras linguagens. Os bytecodes produzidos pelos compiladores Java podem ser usados num processo de engenharia reversa para a recuperação do programa-fonte original. Esta é uma característica que atinge em menor grau todas as linguagens compiladas. No entanto já existem hoje tecnologias que "embaralham" e até mesmo criptografam os bytecodes praticamente impedindo a engenharia reversa. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 1.6. Extensões Extensões em Java: • J2SE (Standard Edition) • J2EE (Enterprise Edition) • J2ME (Micro-Edition for PDAs and cellular phones) • JCE (Java Cryptography Extension) • JMF (Java Media Framework) • JNDI (Java Naming and Directory Interface) • JSML (Java Speech API Markup Language) • JDBC (Java Database Connectivity) • JMS (Java Message Service) • JAAS (Java Authentication and Authorization Service) • JDO (Java Data Objects) • JAIN (Java API for Integrated Networks) • JDMK (Java Dynamic Management Kit) • Jini (a network architecture for the construction of distributed systems) • Jiro • JXTA (open source-based peer-to-peer infrastructure) • Java Card • JavaSpaces • JMI (Java Metadata Interface) • JMX (Java Management Extensions) • JSP (JavaServer Pages) • JSF (JavaServer Faces) • JNI (Java Native Interface) • J3D (A high level API for 3D graphics programming) www.primebean.com.br www.primebean.com.br/joeydecurcio 6 Introdução á Linguagem de Programação JAVA 7 • JOGL (A low level API for 3D graphics programming, using OpenGL) • OSGi (Dynamic Service Management and Remote Maintenance) • SuperWaba (JavaVMs for handhelds) • MARF (Modular Audio Recognition Framework) • JavaFX 1.7. Frameworks É possível utilizar frameworks para facilitar o desenvolvimento de aplicações. Dentre os mais utilizados pode-se destacar: • Hibernate ferramenta para ORM; • Spring ferramenta que auxilia principalmente implementação de injeção de dependências e inversão de controle; • Log4j ferramenta para facilitar a criação de logs na aplicação; • Junit ferramenta para auxiliar na criação de testes unitários; • Struts controlador MVC (Model 2) web. • JSF – Framework para desenvolvimento WEB MVC – Atual Especificação Java 1.8. Ambientes de desenvolvimento É possível desenvolver aplicações em Java através de vários ambientes de desenvolvimento integrado (IDE's). Dentre as opções mais utilizadas pode-se destacar: • Eclipse — um projeto aberto iniciado pela IBM; • NetBeans — um ambiente criado pela empresa Sun Microsystems; www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 8 • JBuilder — um ambiente desenvolvido pela empresa Borland; • JDeveloper — uma IDE desenvolvida pela empresa Oracle; • JCreator — um ambiente desenvolvido pela Xinox. • BlueJ — um ambiente desenvolvido por uma faculdade australiana(muito bom para iniciantes). • Greenfoot — bem parecido com o BlueJ • JGRASP — bom para intermediários, feito pela equipe do projeto GRASP. • IntelliJ IDEA — uma IDE desenvolvida pela JetBrains (considerada por muitos a melhor IDE do mercado). 1.9. Certificações A linguagem Java está consolidada entre as mais utilizadas em todo mundo, com ela podemos desenvolver diversos tipos de sistemas, dos mais simples aos mais robustos funcionando em diferentes plataformas. Uma ótima maneira conseguir uma oportunidade nesse mercado tão promissor é conhecendo a fundo como a linguagem funciona, e uma certificação Java com certeza é um ótimo caminho para isso. Os benefícios que uma certificação pode trazer são muitos, na visão do mercado um profissional certificado comprova não só proficiência na tecnologia, mas também outras qualidades como disciplina, autodidatismo e dedicação além de é claro diferenciação em relação a outros candidatos com experiência equivalente. Embora a valorização do seu currículo no mercado seja muito importante, o benefício maior será o aprendizado que você será capaz de adquirir para ser um bom profissional. Alguns pontos que podem ser destacados em relação ao aprendizado que www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 9 essa certificação pode trazer são: •Melhor entendimento de orientação a objetos; •Melhor capacidade de analisar e resolver problemas; •Melhor qualidade de código; •Conhecimento diferenciado da linguagem Java. 1.10. Comunidade A comunidade de desenvolvedores Java reúne-se em grupo denominados JUGs (Java User Groups). No Brasil o movimento de grupos de usuários expandiu-se bastante e tem formado alguns dos maiores grupos de usuários Java do mundo, como por exemplo o PortalJava e o GUJ. 1.11. Licença A Sun disponibiliza a maioria das distribuições Java gratuitamente e obtém receita com programas mais especializados como o Java Enterprise System. Em 13 de novembro de 2006, Sun liberou partes de Java como software livre, sob a licença GNU General Public License (GPL). 1.12. O que é necessário para programar em JAVA Para programar em Java, não é necessário ter programado antes. Porém, ficaria mais fácil se tiver conhecimento em linguagem Orientada a Objeto, porque Java é totalmente estruturada em objetos (Classes, métodos, abstração, etc). www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 10 Para começar a programar será necessário fazer o download do JDK (Java Development Kit - Kit de desenvolvimento Java) que é gratuito e pode ser obtido direto do site da Oracle, a Oracle comprou a Sun Microsystem e atualmente mantém a tecnologia Java. Além disso, também, um compilador de Java. Existem vários tipos, uns mais leves e simples e outros mais pesados e complexos de usar. Se não souber qual usar, verifique a lista abaixo. Para baixar os compiladores ou para mais informações, clique no nome do compilador. Nome Eclipse JBuilder JEdit JDeveloper Gratuito Descrição sim Eclipse é uma IDE de código aberto desenvolvido inicialmente pela IBM e posteriormente doada para a comunidade do sofware livre. Utilizada largamente, tem grandes diferenciais como a possibilidade de instalação de vários plug-ins. Uma versão em português é mantida no site oficial que é conhecida como Eclipse Europa. sim JBuilder é uma IDE para desenvolvimento de aplicações mais gráficas, a partir de JFames. O JBuilder foi desenvolvido pela Borland (a mesma que produz o C++ Builder) utilizando tecnologias da comunidade do Eclipse Europa. O site CodeGear que faz a distribuição dos softwares da Borland mantém duas versões: uma Enterprise (pago) e a versão trial (mais básica, porém gratuita). O problema maior do JBuilder é para quem não tem internet de banda larga, pois os arquivos de downloads chegam a exagerados 1,8 Gb. sim JEdit é um Ambiente de Desenvolvimento Integrado criado pela Xinox Software com o núcleo desenvolvido por Slava Pestov. Atualmente, distribuído sobre a licença GPL 2.0 (software livre) tem uma interface mais limpa e simples que outras IDEs, bom para quem está começando. sim IDE desenvolvido pela Oracle. Cobre todo processo de produção do software em java, desde o desenvolvimento do código até a implantação do software. Oferece uma ótima estrutura de UML com diagramação do código. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA NetBeans sim 11 O compilador que faz parte da própria gama de produtos da Sun Microsystems. Com capacidade de programação em vários ambientes como C++, Desenvolvimento para sofwares de celular (mobile), Ruby on Rails e vários outros. Netbeans é uma ferramenta de desenvolvimento Java poderosa, mas todo este poder requer uma máquina não muito modesta. Então, mãos à obra, instale um compilador e comece seu projeto. 2. Desenvolvendo o Primeiro Programa em Java Veremos aqui o nosso primeiro código em linguagem Java. A única coisa que esse programa faz é imprimir (mostrar) na tela uma mensagem dizendo: Bem vindo ao mundo Java!. //Primeiro programa em Java public class MeuPrimeiroPrograma { public static void main(String[] args) { System.out.println("Olá, Mundo!"); } } Primeiramente, iremos entender algumas estruturas básicas da linguagem. // Usamos // para indicar que foi iniciado um comentário. Um comentário serve apenas para documentar o código. Isso quer dizer que, ao ser executado este programa, as linhas marcadas como comentário serão ignoradas. Este tipo de comentário é de linha única, ou seja, começa nas barras e termina no final da linha. Se quisermos criar comentário de várias linhas podemos utilizar /* */, no www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 12 qual /* inicia o comentário e */ termina. Por exemplo: //Este é um comentário de uma linha /*Este um é um comentário de várias linhas*/ 2.1. public class MeuPrimeiroPrograma public class MeuPrimeiroPrograma é a criação da classe. Como Java é totalmente orientado a objeto, sua programação é feita dentro de classes e mais classes. O assunto de classes será abordado mais afrente. O importante a princípio é entender que o programa para funcionar deve ter pelo menos uma classe com o método principal (main). 2.2. public static void main public static void main é o método principal do código. Quando executamos um programa é esse método que é chamado. Em outras palavras, sem ele não há programa. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 13 2.3. (String[ ] args) (String[] args) é o argumento passado ao método main. Qualquer programa pode ser iniciado ou não com argumentos que modificam sua execução, trataremos futuramente de argumentos com programas. 2.4. Inicio e Fim { } As chaves são usadas para marcar o inicio e o fim de um bloco de dados. No caso deste algorítmo, ele marca o código que será executado na classe MeuPrimeiroPrograma e também todo o código que será executado quando o método main for chamado. 2.5. System.out.println System.out.println é a saída padrão de Java. É este método que indica o que deve aparecer na tela. 2.6. ("Bem vindo ao mundo Java!") ("Bem vindo ao mundo Java!") é o argumento do método System.out.println. Neste caso é o que deve ser apresentado na tela. Toda linha de comando em Java termina com um ponto-e-vírgula (;). www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 14 Bem, isso é o necessário para começarmos a programar em Java. Logicamente, muitos conceitos foram deixados de lado nesta pequena prévia, mas veremos mais aprofundadamente nas próximas páginas. 3. Regras e convenções de nomenclatura Quando programamos em Java, devemos levar em consideração as convenções de nomenclatura para deixar nosso código o mais legível e documentável possível, pois um dos objetivos da programação orientada a objetos é o reaproveitamento do código. É muito provável que quem não tenha experiência com programação sinta dificuldade de identificar todos os termos utilizados neste artigo, mas garantimos que tudo que será visto aqui será detalhado mais adiante, embora que este artigo se torna trivial a medida que programamos. Portanto, quem já conhece programação em algum outro tipo de linguagem (como Delphi ou C++) aconselhamos que prossiga para a próxima página. Porém, se nunca programou antes, com certeza, este artigo será didático o suficiente para que entenda essas regras. Muitos compiladores como Eclipse e NetBeans dão um grande auxilio na hora de criarmos nosso projeto nos informando sobre as convenções de nomenclatura no momento que estamos criando os pacotes, classes, etc... www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 15 3.1. Nome de Classes Por convenção, toda classe deve começar com uma letra maiúscula e, de preferência, não pode conter letras não ASCII (caracteres de língua de origem latina, como caracteres acentuados). Portanto, não é possível declarar uma classe com qualquer caracter especial (@, #, $, %, &, *, _, etc...) ou número. Caso o nome de uma classe seja composto por mais de uma palavra, a primeira letra de cada palavra deve ser em maiúscula. O nome da classe deve ser exatamente o mesmo nome de seu arquivo fonte ( .java ). O nome da classe deve fazer referência total ao seu objeto (atributos e métodos contidos dentro da classe). Por exemplo: se tivermos uma classe com os atributos canal, volume e sintonia; e os métodos mudarCanal (), aumentarVolume () e diminuirVolume (); então, possivelmente chamaríamos esta classe de TV ou Televisao. Contudo, em uma classe que contivesse o atributo corDasPenas e o método voar () jamais chamaríamos de Pessoa (por que pessoas não tem penas e nem voam). Exemplos de nomes de classes: Pessoa, ImpostoDeRenda, Conta, AgenciaDeEmprego, ... 3.2. Nome de Pacotes O padrão da sun para dar nome aos pacotes é relativo ao nome da empresa que desenvolveu a classe: br.com.nomedaempresa.nomedoprojeto.subpacote br.com.nomedaempresa.nomedoprojeto.subpacote2 www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 16 br.com.nomedaempresa.nomedoprojeto.subpacote2.subpacote3 Os pacotes só possuem letras minúsculas, não importa quantas palavras estejam contidas nele. Esse padrão existe para evitar ao máximo o conflito de pacotes de empresas diferentes. Usamos pacotes para organizar as classes semelhantes. Pacotes, a grosso modo, são apenas pastas ou diretórios do sistema operacional onde ficam armazenados os arquivos fonte Java e são essenciais para o conceito de encapsulamento, no qual são dados níveis de acesso as classes. PS: Java possui um pacote padrão que é utilizado quando programamos. As classes do pacote padrão de bibliotecas não seguem essa nomenclatura, que foi dada para bibliotecas de terceiros. O nome do pacote deve fazer referência total às funções exercidas pelas classes dentro do pacote, pois pacotes servem basicamente para organizar os arquivos de código fonte de nosso projeto. Exemplos de nomes de pacotes: br.com.nomedaempresa.nomedoprojeto.criptografia; br.com.nomedaempresa.nomedoprojeto.entidade; br.com.nomedaempresa.nomedoprojeto.dao; 3.3. Criando Pacotes Muitas IDE's criam automaticamente os pacotes como uma forma eficaz de organização, mas a criação de pacote pode ser feita diretamente no sistema operacional. Basta que criemos uma pasta e lhe demos um nome. Após isso, devemos gravar todos os arquivos fonte de java dentro desta pasta. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 17 3.4. Definindo Pacotes Agora que já possuímos a pasta que será nosso pacote, devemos definir em nossa classe a qual pacote ela pertence. Isso é feito pela palavra reservada package. Package deve ser a primeira linha de comando a ser compilada de nossa classe. Portanto, se tivéssemos criado uma sequencia de pastas: br.com.primebean e fossemos criar uma classe nesta pasta (pacote), o começo de nosso código seria: br.com.primebean;. 3.5. Importando Pacotes Java possui vários pacotes com outros pacotes internos e várias classes já prontas para serem utilizadas. Dentre os pacotes Java podemos determinar dois grandes pacotes: o pacote java, que possui as classes padrões para o funcionamento do algorítmo; e o pacote javax, que possui pacotes de extensão que fornecem classes e objetos que implementam ainda mais o pacote java. Exemplo: o pacote AWT (Abstract Windowing Toolkit) possui as classes necessárias para se criar um ambiente gráfico API (Janelas) e está fortemente ligado as funções nativas do Sistema Operacional, ou seja, ele pertence ao pacote java. Mas, o pacote SWING não é ligado fortemente as funções nativas do Sistema Operacional, mas as funções do AWT, ou seja, SWING complementa o AWT, portanto SWING faz parte do pacote de extensão javax. Para utilizar as milhares de classes contidas nos inúmeros pacotes de Java devemos ou nos referenciar diretamente a classe ou importá-la. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 18 3.6. importando um pacote usamos o comando import. Para separar um pacote de seu sub-pacote usamos um ponto (como no acesso a membros de classe). Ao importarmos um pacote podemos utilizar um coringa, o asterísco (*). O asterísco serve para importar todos os sub-pacotes e classes do pacote que está definido. Ex.: import java.awt.*;. Isso importará todos os sub-pacotes pertencentes ao pacote AWT. Ou podemos definir diretamente qual pacote desejamos. Ex.: import javax.swing.JoptionPane;. Isso irá importar apenas o sub-pacote JOptionPane do pacote SWING. A diferença entre as duas formas de importação de pacotes é o consumo de recursos do computador. Como o asterisco importa todos os sub-pacotes, o consumo de memória será alto e, muito provavelmente, não usaremos todas as classes de todos os pacotes importados. Por isso, o recomendado é sempre importar apenas o pacote que será utilizado. Para consolidar o que foi visto até aqui, o código abaixo ilustra o uso de pacotes. package br.com.primebean.mensagem; import javax.swing.JOptionPane; public class Mensagem { public static void main (String args[]){ JoptionPane.showMessageDialog(null, "Bem vindo ao mundo de Java!"); } } A classe acima está no pacote br.com.primebean.mensagem. No nosso programa estamos utilizando o método showMessageDialog que pertence à classe JOptionPane que está no pacote de extensão SWING que tivemos que importar. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 19 3.7. Nome de atributos ou variáveis Para quem já programou antes em alguma linguagem de programação não orientada a objetos, deve achar estranho o termo atributo porque, na verdade, está mais acostumado com o termo variável. Mas, qual a diferença entre atributos e variáveis? Nenhuma. Atributos e variáveis são a mesma coisa em questão de funcionalidade. Ambos são endereços de memória que tem um espaço ou tamanho definido de acordo com o tipo de dado que será guardado, por exemplo: caracter, número, número decimal, etc. Em Java, costumamos utilizar o termo atributo, que é nada além do que uma variável que está dentro de uma classe. Como tudo que fazemos em Java está contido dentro de uma classe, então usamos o termo atributo ao invés de variável. Os atributos (variáveis) podem começar com qualquer letra e os caracteres $ ou _, porém não podem começar com números. Caso o nome de um atributo (variável) seja composto por mais de uma palavra, a primeira letra de cada palavra deve ser em maiúscula. Exemplos de nomes de atributos ou variáveis: x, y, resultado, valorDeX, valorDeY, ligado, ... 3.8. Nome de atributos finais ou constantes Os atributos finais (constantes) devem ser escritos em letras maiúsculas. Usamos underline (_) para separar nomes compostos de atributos finais (constantes). Exemplos de nomes de PARAR_DE_EXECUTAR, … www.primebean.com.br www.primebean.com.br/joeydecurcio atributos finais ou constantes: TAMANHO, Introdução á Linguagem de Programação JAVA 20 3.9. Tipos de dados e declaração de atributos Todo programa de computador deve ser capaz de lidar com dados para conseguir fazer seus processos como, por exemplo, somar, multiplicar, dividir, etc... Usar atributos é a melhor forma de manipular os dados. Os tipos de dados são o que definem a quantidade de memória do computador que será utilizado para guardar tal dado. Cada tipo de dado tem um tamanho diferente e por consequência seu alcance também. O que queremos dizer é que se declararmos um atributo para guardar um número inteiro, jamais poderemos guardar um número decimal, porque um número decimal ocupa mais espaço de memória que um inteiro. Para declararmos qualquer tipo de atributo, usamos a seguinte ordem: primeiro o tipo de dado e depois o nome do atributo. Se não souber como nomear um atributo, veja as regras e convenções de nomenclatura. Vamos iniciar com os tipos de dados inteiros que são os mais simples. Em Java, os números inteiros são divididos em quatro tipos: byte, short, int e long. Esses quatro guardam o mesmo tipo de dado, mas ocupam espaços de memória diferente, o que afeta em seu alcance. O tipo byte é o de menor alcance entre os inteiros. Como o próprio nome sugere, ele consome apenas um byte (8 bits) e pode guardar valores entre -128 e 127. O tipo short guarda inteiros de 2 bytes (16 bits) e pode guardar números entre -32.768 a 32.767. O tipo int é o tipo de dado mais comum. Ele consome 4 bytes (32 bits) e guarda valores entre -2.147.483.648 e 2.147.483.647. Long é o tipo de dado com maior alcance entre os inteiros. Consequentemente, também é o que ocupa mais espaço (8 bytes ou 64 bits). Tem um grande alcance que fica entre -9,22E+18 (exatos -9.223.372.036.854.775.808) e 9,22E+18 (exatos 9.223.372.036.854.775.807). Existe os tipos de dados próprios para caracteres que é o char. O tipo char ocupa 2 bytes, o que torna Java ideal para programar em língüas latinas, asiáticas ou qualquer outra que utilize caracteres diferentes do padrão ASCII. O www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 21 padrão ASCII utiliza apenas um byte que fornece 256 letras diferentes, mas o padrão utilizado em Java (ISO) nos dá a possibilidade de até 65.536 caracteres diferentes. Para números decimais utilizamos dois tipos de dados, dependendo da necessidade de seu alcance e precisão (números após a vírgula). O tipo de dado mais comum para número decimal é o float. Em um tipo de dado float, podemos guardar números grandes que vão desde 1,4E-45 até 3,4028235E+38. Para número decimais com grande precisão ou valores extraordinários (geralmente utilizados em matemática aplicada e complexa como cálculos físicos, químicos, astrológicos, meteorológicos, etc) utilizamos o tipo de dado double. Double é o tipo de dado mais complexo que há em Java e o maior valor possível de se armazenar é 1,797.693.134.862.315.7E+308. Muito mais do que qualquer programador precisa. Para ilustra melhor essa explicação, abaixo está um pequeno algorítmo com alguns atributos e seus valores mínimos e máximos. public class TiposDeDados { public static void main(String[] args) { System.out.println("Tipos de dados em Java: \n" + "\nMenor Byte: " + Byte.MIN_VALUE + "\nMaior Byte: " + Byte.MAX_VALUE + "\nMenor Short Int: " + Short.MIN_VALUE + "\nMaior Short Int: " + Short.MAX_VALUE + "\nMenor Int: " + Integer.MIN_VALUE + "\nMaior Int: " + Integer.MAX_VALUE + "\nMenor Long: " + Long.MIN_VALUE + "\nMaior Long:" + Long.MAX_VALUE + "\nMenor Float: " + Float.MIN_VALUE + "\nMaior Float: " + Float.MAX_VALUE + "\nMenor Double: " + Double.MIN_VALUE + "\nMaior Double: " + Double.MAX_VALUE); } } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 22 3.10. Atribuição de Valores a Variáveis ou Atributos Como vimos, há vários tipos de dados em Java, cada um com um consumo de memória determinado que afeta diretamente o seu alcance. Veremos agora como atribuir valores a esses endereços de memória (atributo ou variável). Para atribuirmos valor a uma variável ou atributo usamos o operador =. Neste caso, o sinal de igual não significa igualdade, mas que um valor será atribuído. A regra básica é que sempre o que estiver à esquerda do "=" receberá o valor que estiver à direita. Por exemplo: se expressarmos var1 = 10 queremos dizer que a variável var1 receberá o número 10. Pronto! Agora, temos o número 10 gravado na memória. Podemos também atribuir valores contidos em outras variáveis. Por exemplo: var1 = 20; var2 = var1; A variável var1 recebe o número 20, depois a variável var2 recebe o valor de var1 (que é 20). Pronto! Agora, temos duas variáveis guardando o mesmo número (20). 3.11. Inicialização de variáveis ou atributos Muitas vezes, precisamos inicializar as variáveis ou atributos para que possuam um valor desde o início do programa. Como há muitos tipos de dados em Java, seus criadores desenvolveram formas de escrita para que diferenciam os vários tipos de dados. Primeiramente, começaremos com os mais simples: os inteiros. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 23 Os número inteiros comuns e do tipo byte são os mais simples de se inicializar, pois basta atribuirmos seu valor diretamente. Logicamente, precavendo-se dos limites de alcance do tipo inteiro vistos na página de tipos de dados. Por exemplo: int var1 = 10; int var2 = 500; int var3 = 65000; byte var1 = -100; byte var2 = 50; Os números inteiros longos têm duas formas de serem inicializados. Podemos escrevê-lo diretamente se, e somente se, seu valor for menor que o alcance de um inteiro comum. Mas se o valor atribuído for maior que o valor permitido por um inteiro comum, então, no final deve ser acrescentado uma letra L (maiúscula ou minúscula, não há diferença aqui). Exemplo: long var1 = -65000; long var2 = 3590; long var3 = 15000000000L; long var4 = -6740000000L; A inicialização do tipo double e float é um pouco diferente. É possível apenas digitar um número como sendo inteiro que o compilador entenderá facilmente, porém, se quisermos utilizar as casas decimais, devemos utilizar um ponto para separar a parte inteira da decimal. Outro fato ao utilizar casas decimais é que o tipo float deve ser diferenciado do tipo double. Conseguimos fazer isso facilmente digitando uma letra F ao final do número (não importa se a letra é maiúscula ou minúscula). www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 24 Exemplo: double var1 = 12045741359; float var1 = 745621; double var2 = 10.658745965; float var2 = 0.5f; Char deve ser inicializado com uma letra entre aspas simples. O importante é entender que em uma variável do tipo char só pode ser colocada uma letra, não uma frase. Além do mais, neste caso há diferença entre maiúsculas e minúsculas. Exemplo: char var1 = 'a'; char var2 = 'A'; Se quisermos criar uma frase devemos guarda-la em uma string. Apesar de String não ser um tipo de dado em Java, mas sim uma classe, este é com certeza o elemento mais utilizado. Uma cadeia de caracteres (string) pode ser inicializada de três formas: 1) Como uma string inexistente, ou seja, sem valor algum. Para isso utilizamos a palavra reservada null; 2) Como uma frase vazia; 3) Como uma string completa. Com exceção da inexistente, toda string deve estar dentro de aspas duplas ( " " ). Se por acaso, precisarmos digitar uma aspas dentro de uma string, estas aspas devem vir precedidas de uma barra invertida (\). Exemplo: String var1 = null; String var2 = ""; String var3 = "Cadeia de caracteres"; www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 25 String var4 = "entre aspas: \"String em Java\"."; O tipo booleano possui apenas dois valores: verdadeiro e falso. True para verdadeiro e False para falso. Exemplo: boolean var1 = true; boolean var2 = false; Neste tipo de dado não há possibilidade de ter outro valor. 3.12. Método de Saída Padrão Um método de saída é utilizado para mostrar alguma coisa ao usuário. No caso de Java, existe um método padrão que utiliza uma saída padrão (monitor de vídeo) para criar a comunicação com o usuário – estamos falando de println. O método println faz parte da classe System que controla a maioria das funcionalidades do computador, e se tratando de uma saída, mais especificamente de out. Basicamente, o método println imprime na tela uma string (cadeia de caracteres frase) que é passada ao método como argumento entre parênteses. A saída padrão é exibida sempre no console e não em uma janela. O importante é saber que o método PRINTLN sempre pulará uma linha quando seu argumento chega ao final. Então, procedemos da seguinte maneira: 1) A classe ao qual pertence (System); 2) o membro que indica a saída (out); 3) o método (println); 4) O argumento contendo a string que deve ser apresentada na tela. O método, resumidamente, ficaria assim: System.out.println ("string") www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 26 public class ExemploDeSaidaPadrao { public static void main(String[] args) { System.out.println("Saída Padrão em Java"); System.out.println("Linha 1"); System.out.println("Linha 2"); System.out.println("Linha 3"); } } Uma outra forma de saída padrão é o print. A única diferença entre println e print é que ao final de seu argumento ele não irá pular nenhuma linha. Dessa forma podemos criar uma linha contínua com vários print em linhas diferentes. public class ExemploDeSaidaComPrint { public static void main(String[] args) { System.out.print("Saída Padrão "); System.out.print("usando "); System.out.print("o método "); System.out.print("print"); } } 3.13. Controle de Texto Outra possibilidade interessante nos métodos de saída são os controles de texto. Os controles de texto são dados por caracteres chaves que são indicados com uma barra invertida antes dele. Veja a lista abaixo: \n - pula uma linha \t - cria uma tabulação (o mesmo que apertar a tecla TAB) \b - retorna o cursor um carácter www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 27 \r - retorna o cursor ao início da linha public class ExemploDeControleDeTexto{ public static void main(String[] args) { System.out.print("Empresa:\t"); // cria uma tabulação System.out.print("primebean\n"); //pula uma linha System.out.print("Soluções em Tecnologia Multiplataforma\r"); // põe o cursor no início da linha } } 3.14. Apresentando valores de variáveis ou atributos Podemos facilmente demonstrar o valor de uma variável ou atributo bastando apenas dar como argumento a variável. O próprio método println ou print se encarrega de converter o valor em uma string, ou seja, ele transforma o valor número em um texto que o representa. Veja o exemplo: public class ApresentandoVariaveis{ public static void main(String[] args) { int inteiro = 200; float decimal = 0.5f; char letra = 'J'; System.out.println (inteiro); System.out.println (decimal); System.out.println (letra); } } Também é possível exibir o resultado de uma operação matemática (processo) executado dentro da própria saída padrão. public class ApresentandoResultados{ public static void main(String[] args) { int inteiro = 200; float decimal = 0.5f; www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 28 System.out.println (inteiro + decimal); } } Obs.: Tenha cuidado ao apresentar resultados de números junto com texto, pois nesse caso haverá a concatenação de string, ou seja, a junção de duas ou mais cadeias de caracteres. 3.15. Concatenação Concatenação é o ato de unir duas ou mais cadeias de caracteres (strings). Por muito tempo, operações envolvendo strings eram os pesadelos de qualquer programador, pois havia a necessidade de tratar o elemento pelo seu dado bruto, ou seja, carácter por carácter. Então, juntar por exemplo, duas frases era um trabalho árduo. Com o surgimento da orientação a objeto e o advento do Java, as operações envolvendo strings foram muito simplificadas. A melhoria mais significativa nesse assunto, sem sombra de dúvidas, foi utilizar a concatenação de strings. A concatenação de strings é dada pelo operador +, mas não o confunda com o operador de adição que utiliza o mesmo símbolo. Dessa forma, com apenas este símbolo, podemos unir duas cadeias de caracteres diferentes em apenas uma. Veja este exemplo, que apesar de bobo, ilustra exatamente o que acontece na concatenação: João + zinho = Joãozinho; Passa + tempo = Passatempo; beija + - + flor = beija-flor. Acredite, simples desse jeito. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 29 Colocando isso em um código ficaria: public class ConcatenacaoSimples { public static void main(String[] args) { String palavra1 = "tele"; String palavra2 = "fone"; System.out.println(palavra1 + palavra2); } } O melhor da concatenação é que não precisa ser uma palavra que faça sentido porque o computador não verifica se faz sentido, ele simplesmente junta a cadeia de caracteres. Portanto, poderíamos muito bem fazer isso: public class ConcatenacaoComposta { public static void main(String[] args) { String part1 = "De"; String part2 = "se"; String part3 = "nc"; String part4 = "or"; String part5 = "aj"; String part6 = "ad"; String part7 = "o"; System.out.println(part1+part2+part3+part4+part5+part6+part7); } } A concatenação de strings ajuda muito no momento que usamos o método de saída padrão println, porque ao invés de utilizarmos várias vezes o mesmo método, podemos apenas concatenar a string anterior com a string posterior, ou seja, juntar a string de cima com a string da linha de baixo. Veja o exemplo: public class ConcatenacaoComPrintln { public static void main(String[] args) { System.out.println("Bem vindo ao mundo Java!\n\n" + www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 30 "Este é um exemplo prático de concatenação de string.\n" + "Aqui, a string da linha de cima é " + "sempre concatenada com a string da linha de baixo" ); } } 3.15.1. Cuidados ao concatenar Apesar da concatenação ser algo bem simples de ser feito, devemos ter alguns cuidados. Pois como podemos perceber, ele também é o símbolo utilizado para fazer operações de adição. O que queremos dizer é que, se por exemplo, quisermos marcar um número de telefone em uma única string e tivermos na verdade dois números inteiros distintos, o resultado será desastroso. Veja: Telefone: 998 + 1234, resultaria em Telefone: 2232. Acabamos de perder o número de telefone. Então, o mais sensato é se lembrar que concatenação só ocorre entre uma string e outro dado (não necessariamente precisa ser uma string também). Então, para conseguirmos juntar os dois números acima, pelo menos um deles deve ser uma string. Telefone: "998" + 1234, ou Telefone: 998 + "1234". Esse pensamento se torna mais complicado a medida que temos que concatenar uma uma operação no meio da string. Exemplo: "CCXXVI em algarismos romanos são " + 200 + 20 + 6. Aqui, ao invés de representar a soma de 200 + 20 + 6, que seria 226, é representada a total concatenação de todos os elementos. O que resultaria em "CCXXVI em algarismos romanos são 200206". Mas este problema é fácil de resolver, basta indicarmos com os parênteses que a operação matemática deve ser executada primeiro. Representando ficaria: "CCXXVI em algarismos romanos são " + (200 + 20 + 6). O que consequentemente, www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 31 representaria "CCXXVI em algarismos romanos são 226". 3.16. Operadores e Processos Os processos são contas matemática (cálculos) que podem ser feitos com números, variáveis ou ambos. Abaixo está uma tabela com os operadores mais comuns. + adição ou concatenação - Subtração * Multiplicação / Divisão % Módulo (divisão no qual é obtido o resto) ++ Incremento de 1 -- Decremento de 1 Java segue a convenção de expressões matemáticas. Por exemplo: Se você fizer 10-2/4, o resultado será -9,5 e não 2, pois a divisão deve ser calculada primeiro. Para esta conta dar 2 devemos indicar que a subtração deve ser feita antes da divisão. Ela ficaria assim, (10-2)/4. O que está entre parênteses deve ser calculado primeiro. Em Java, podemos facilmente simplificar operações que envolvam a própria variável. Por exemplo, vamos imaginar que o novo valor de var1 seja o valor da própria variável var1 mais o valor da variável var2. Podemos construir, então, a seguinte sentença -> var1 = var1 + var2, ou podemos simplificá-la em -> var1 += var2. Veja abaixo a tabela de todas as operações possíveis: Símbolo www.primebean.com.br www.primebean.com.br/joeydecurcio Operação Introdução á Linguagem de Programação JAVA 32 += somar (quando os dados forem algum número) += concatenar (quando um dos dados for String) -= subtração *= multiplicação /= divisão %= módulo (a variável à esquerda recebe o resto da divisão dele com a variável à direita) 4. Controle de Fluxo Controle de fluxo é a habilidade de ajustar a maneira como um programa realiza suas tarefas. Por meio de instruções especiais, chamadas comandos, essas tarefas podem ser executadas seletivamente, repetidamente ou excepcionalmente. Não fosse o controle de fluxo, um programa poderia executar apenas uma única seqüência de tarefas, perdendo completamente uma das características mais interessantes da programação: a dinâmica. Podemos classificar os comandos aceitos pela linguagem Java em basicamente quatro categorias: Comando Palavras-chave Tomada de decisões If-else, switch-case Laços ou repetições For, while, do-while Apontamento e tratamento de excessões Try-catch-finally, throw Outros break,continue,label:,return www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 33 4.1. Execução condicional - IF e ELSE Uma ação muito importante que o processador de qualquer computador executa, e que o torna diferente de qualquer outra máquina, é a tomada de decisão definindo o que é verdadeiro e o que é falso. Se quisermos fazer um bom programa, esse programa deve ser capaz de definir caminhos diferentes de acordo com decisões que o próprio programa toma. Para isso, precisamos de uma estrutura seletiva da qual o único valor possível é o bit 1 ou 0, resumindo: retornar o valor VERDADEIRO ou FALSO. Em Java, como em muitas linguagens de programação, quem faz isso é o IF (SE traduzindo). O ELSE é o que chamamos de caso contrário, ou seja, se for falso execute o que está no ELSE. Exemplificando: Se (IF) for tal coisa, faça isso! Caso contrário (ELSE), faça aquilo! 4.2.1. Usando IF Para usar o IF basta digitar entre parênteses o que deve ser comparado. IMPORTANTE: IF é uma palavra reservada que não aceita ponto-e-vírgula (;) no final. Se for verdadeiro, o programa executará a primeira linha logo abaixo do if. Mas, e se quisermos executar várias linhas se if for verdadeiro? Se o if tiver que executar várias linhas, todas as linhas que devem ser enquadradas dentro do bloco de dados - as chaves ({}). www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 34 4.2.2. Usando ELSE O ELSE só existe se tiver um IF. O else só será executado se o IF for falso. Else executará só a primeira linha abaixo dele. Se o else tiver que executar várias linhas, vale a mesma regra de if. Todas as linhas a ser executadas deverão estar contidas dentro do bloco de dados ({}). Para que IF chegue a uma decisão de falso e verdadeiro são necessários operadores lógicos. Dos quais destacam-se 6: • > - maior que • < - menor que • >= - maior ou igual a • <= - menor ou igula a • == - igual a • != - diferente de Importante O operador lógico ! (negação) serve para inverter o valor, ou seja, se algo for falso, irá se tornar verdadeiro e vice-e-versa. Uma construção sem comparação entre duas variáveis é sempre entendida como sendo verdadeira. Ex.: if (var1) -> entenda como: se var1 for verdadeiro. Uma construção sem comparação entre duas variáveis será entendida como false se usarmos o operador de negação antes da variável. Ex.: if (!var1) -> entenda como: se var1 for falso. public class UsandoIf { public static void main(String args[]) { www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 35 boolean var1 = true; // Se var1 for verdadeiro if (var1) { System.out.println("var1: Verdadeiro"); } else { System.out.println("var1: Falso"); } // Se var1 for falso if (!var1) { System.out.println("!var1: Verdadeiro"); } else { System.out.println("!var1: Falso"); } } } 4.3. Switch, Case e Default Uma estrutura muito utilizada em programação é o switch. A estrutura switch verifica uma variável e age de acordo com seus cases. Os cases são as possibilidades de resultados que são obtidos por switch. Basicamente, o switch serve para controlar várias ações diferentes de acordo com o case definido dentro dele. A estrutura do Switch é: SWITCH (variável) { CASE valor : Código a ser executado caso o valor de case seja o mesmo da variável de switch } Então, detalhadamente, switch recebe uma variável e abre um bloco de dados ( { } ), dentro desse bloco de dados há os cases. Cada case recebe um valor único, ou www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 36 seja, que não pode ser repetido no mesmo bloco de dados. Então, marcamos cada case com dois pontos ( : ). Após os dois pontos colocamos todo código que deverá ser executado que pode conter quantas linhas nós quisermos. Dica importante: É um bom costume sempre terminar um código após o case com um comando break. Assim, nós evitamos que o resto do código seja executado por acidente. E vale também ressaltar que case não gera resultados booleanos, portanto, não há a possibilidade de fazer comparações (Ex. Isso está totalmente errado-> case var1 > var2:). 4.3.1. Default Como switch pode receber várias possibilidades, pode ocorrer de algum caso estar fora do alcance ou não definido. Nesse momento, default faz seu papel. Default pega qualquer resultado que não esteja definido no case. Ou seja, ele é o bloco de código padrão que deve ser executado quando nenhum case for satisfeito. Podemos colocá-lo onde quisermos dentro de switch , mas, geralmente, o colocamos no final. Para exemplificar, vamos ver o código abaixo. public class ExemploSwitch { public static void main(String args[]) { int diaDaSemana = 1; switch (diaDaSemana) { case 1: System.out.println("Domingo"); break; case 2: System.out.println("Segunda-feira"); break; case 3: System.out.println("Terça-feira"); break; case 4: System.out.println("Quarta-feira"); www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 37 break; case 5: System.out.println("Quinta-feira"); break; case 6: System.out.println("Sexta-feira"); break; case 7: System.out.println("Sábado"); break; default: System.out.println("Este não é um dia válido!"); } } } Como podemos perceber, existe uma variável inteira chamada diaDaSemana. Essa variável é passada ao switch e dentro desse switch há 7 cases que correspondem aos dias da semana. Como o valor inicial é 1, então, o bloco logo abaixo de case 1 é executado, ou seja, ele imprimirá Domingo no monitor. Para evitar que o código dos outros cases sejam executados, logo após o método println há um comando BREAK; Se quiser, copie este código e modifique o valor inicial de diaDaSemana para verificar os possíveis resultados e como este algoritmo funciona. 4.4. Break e Continue Break e Continue são dois comandos de controle de estruturas largamente utilizados em loops (repetições) como for e while. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 38 4.4.1. Break O comando break serve para determinar uma quebra de estrutura, ou seja, ele faz com que, por exemplo, um loop (repetição) pare. No comando switch, por exemplo, ele determina que não pode ser executado o case seguinte, e assim por diante. No exemplo abaixo, temos uma repetição que se inicia em 1 e deve terminar em mil (1.000), mas dentro desta estrutura há uma condição: se a variável for igual a 10 saia da estrutura de repetição. Vejamos: public class ExemploBreak { public static void main (String args []){ for (int contador=1; contador<=1000; contador++){ System.out.println("Esta é a repetição nr: "+contador); if (contador==10) break; } } } Como podemos observar, mesmo a estrutura de repetição for determinando que a repetição deve ir até 1000, ao executarmos esse código, apenas conseguimos chegar até a repetição número 10. Isso ocorre porque quando if for verdadeiro ele executa o break. Dessa forma, conseguimos sair do loop sem ele ter terminado. 4.4.2. Continue Continue também é muito utilizado em estruturas e repetição e sua função é ignorar o código, e não sair como acontece com o break. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 39 Exemplificando, faremos um código contendo uma estrutura de repetição que irá contar de 1 a 100, mas sempre que o número não for múltiplo de 5 o código para apresentar o número na tela será ignorado e a repetição continuará com o número seguinte. public class ExemploContinue { public static void main (String args []){ for (int contador=1; contador<=100; contador++){ if (contador%5!=0) continue; /* Se o contador não for múltiplo de 5 * Todo o código abaixo será ignorado * e o loop continua com o próximo nr */ System.out.println("Contador: "+contador); } } } Ou seja, desta forma, apenas os múltiplos de 5 entre 1 e 100 aparecem na tela. 4.3. Estruturas de Repetição Trata-se de comandos que permitirão a execução repetida de vários outros comandos descritos no algoritmo. Usaremos uma estrutura de repetição para executar repetidas vezes comandos, em função de uma condição que determinará o numero de repetição a serem executadas . As repetições poderão ser controladas de varias formas diferentes . Em geral aparecerá a figura de uma variável que será utilizada como elemento de controle das repetições. A está variável daremos o nome de contador. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 40 4.3.1. While While é uma estrutura de repetição. O mesmo executa uma comparação com a variável. Se a comparação for verdadeira, ele executa o bloco de instruções ( { } ) ou apenas a próxima linha de código logo abaixo. Procedemos da seguinte maneira: While(comparação) O problema com estruturas de repetição, principalmente com while, é o que chamamos de looping infinito. Damos esse nome ao fato de que o programa fica repetindo a mesma sequência de códigos esperando por um resultado que nunca irá acontecer. Portanto, é imprescindível que uma determinada variável seja modificada de acordo com cda loop. Veja o exemplo public class ExemploWhile { public static void main(String args[]) { int contador = 0; while (contador < 50) { System.out.println("Repetição nr: " + contador); contador++; } } } Como podemos ver, existe a variável contador que é iniciada valendo 0, a cada www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 41 loop executado (repetição) é somado 1 ao contador. Perceba que o while irá manter a repetição enquanto a variável contador for menor que 50. Outro ponto importante é que a variável contador é inicializada antes de chegar ao while, porque o while irá comparar a sentença e só depois permitirá a execução do bloco. Se quisermos fazer todo o bloco primeiro e só depois fazer a comparação, devemos utilizar o comando do While 4.3.2. Do While Do While é uma estrutura de repetição, tal como o próprio while. A principal diferença entre os dois é que Do While irá fazer a comparação apenas no final do bloco de código, sendo representado da seguinte forma: DO { código } WHILE (comparação); Neste caso, devemos ter as mesmas precauções quanto while, no que diz respeito a looping infinito. Mas não é necessário inicializar a variável antes do bloco de código como acontece com while, pois a comparação só será feita após todo o código ter sido executado. 4.3.3. For For é uma estrutura de repetição que exerce a mesma função que WHILE e DO WHILE. A principal diferença entre eles é a sintaxe e também a forma de trabalhar. O For necessita de três parâmetros: a inicialização da variável, a condição que irá manter o looping (repetição) e o modificador da variável inicializada que pode ser incrementada ou decrementada, ou seja, pode aumentar seu valor ou diminuir. Um ponto www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 42 importante é que todos os parâmetros devem ser separados por ponto-e-vírgula ( ; ). Dessa forma, temos resumidamente a seguinte construção: FOR (inicialização ; condição ; incremento ou decremento). Por exemplo, vamos criar um código que nos dá o resultado do fatorial de 5. Como sabemos para calcular o fatorial de algum número basta multiplicarmos ele pelo número anterior regressivamente até 1, ou seja, seria algo como 5 × 4 × 3 × 2 × 1. Dessa forma, sabemos exatamente em quanto devemos começar nossa conta (5), sabemos por quanto tempo o looping irá continuar executando (enquanto a variável for maior que 1) e sabemos quanto devemos modificar essa variável (para cada repetição irá subtrair decrementar - 1). Em um código ficaria: public class Fatorial { public static void main (String args[]){ int fator, resultado=1; for (fator=5; fator>1; fator--) resultado*=fator; System.out.println(resultado); } } Observemos apenas um detalhe, como toda variável é automaticamente inicializada como nulo (NULL), então, necessitamos inicializar a variável resultado em 1, porque seria impossível multiplicar a variável resultado pela variável fator (ex. NULL × 5 = ?). www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 43 5. O que são e para que servem as Classes e Objetos O conceito de orientação a objetos, é, sem dúvida, o mais importante em Java. Por ser um conceito um pouco abstrato, é normal que demore um pouco até entender tudo. E até entender bem, vai demorar mais ainda. Porém, vamos ensinar, ao longo de vários exemplos, divididos em várias seções, estes tão importantes detalhes. Até este momento só vimos o básico e laços da programação Java, vamos apenas ensinar como declarar as classes, instanciar os objetos (com e sem construtores) e como usar testes condicionais dentro das classes que criamos. Isso dará uma idéia do que são classes e objetos, e é importante que se habitue a estas idéias. 5.1. O que são Classes e Objetos em Java Classes podem ser vistas como abstrações ou definições maiores das coisas , já um objeto já é algo mais real, mais concreto, é um elemento ou tipo daquela classe. Usando essas definições, é realmente difícil entender os conceitos, por isso vamos usar exemplos. Por exemplo, podemos ver "Pessoa" como uma classe. É uma classe que representa seres humanos, que possuem cabeça, coração, cérebro etc. É uma generalização maior. Podemos declarar você, caro leitor, como um objeto dessa classe, com seu nome e características específicas de uma "Pessoa". Você pertence a classe "Pessoa". Eu também, pois possuímos cabeça, coração, cérebro etc. Nós temos essas características gerais, que todos da classe "Pessoa" possuem. Ou seja, www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 44 em Java, dizemos que somos instâncias da classe "Pessoa". 5.2. Utilidade das Classes e Objetos em Java Esse tipo de representação vai nos ajudar muito em programação Java. Por exemplo, imagine que você foi contratado para criar um aplicativo Java para uma empresa. Você precisará cadastrar os milhares de funcionários da empresa. É claro que você não vai declarar milhares de strings para armazenar o nome de cada um, nem de inteiros para armazenar seus números nem de floats para armazenar seus salários. Seria humanamente impossível fazer isso. 5.2.1. Agrupar coisas semelhantes Aí que entra a vantagem da programação orientada a objetos. Podemos ver todos esses funcionários de uma mesma maneira: como a classe Funcionario. O que a classe "Funcionario" tem em comum? Tem um nome, uma idade, uma data de contratação, um salário, um setor em que trabalham e outras coisas específicas da empresa. Pronto. Você pode ver essa classe como um tipo de dado. Assim como 'int' ou 'float', agora existe o tipo 'Funcionario'. Toda vez que entrar alguém novo na empresa, você declara esse elemento como fazendo parte do tipo 'Funcionario'. Ou seja, estará criando um objeto dessa classe. O objeto, diferente da classe, é algo mais específico, ele que terá as informações pessoais de cada funcionário. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 45 5.2.2. Crie uma vez, use quantas vezes quiser A grande vantagem desse tipo de 'visão', é que, ao declarar a classe, você declara dentro dela os tipos: string, float, int etc, que estão dentro da classe. Então, quando for criar um objeto, automaticamente esses dados estarão criados! Aí que reside a beleza do Java e da orientação a objetos. É muito, mas muito útil e prático. É um novo jeito de pensar e ver o mundo. 5.2.3. Altere uma parte do código, e a mudança se propagará em todo o código Ok, você criou seu aplicativo usando a classe "Funcionario". Porém, a pessoa que te contratou - que muitas vezes não são da área de TI - esqueceu de te informar que os funcionários devem ter uma informação no cadastro: se possuem carro ou não. E aí? Alterar tudo? Começar do zero? Claro que não. Simplesmente vá na classe e coloque esse atributo (informação), e automaticamente todos os objetos passarão a ter esse dado, "carro". Então é só pedir para os funcionários preencherem esse dado no seu aplicativo de cadastro. 5.2.4. Classe à parte, vida à parte Uma coisa interessante que a programação orientada a objetos nos proporciona é a divisão das partes do programa. Dois programadores podem programar duas classes de forma totalmente independente e fazer com que elas funcionem perfeitamente. Coisa que em outros paradigmas de programação é quase impossível. Por exemplo, você criou a classe "Funcionario". www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 46 Nessa classe você precisa a informação do salário de cada funcionário, porém você não tem acesso aos detalhes financeiros da empresa. Ora, nem precisa e nem deve ter, é algo mais restrito. Outro programador, responsável pelo setor financeiro, pode ter criado a classe "Salario" que recebe os dados de cada pessoa, sua posição na empresa, bônus, horas extras etc etc, e te dá somente o resultado final: o número. Esse dado é o que você vai usar na sua classe "Funcionario". Isso tudo pode ser feito de uma maneira totalmente eficiente, segura e independente, tanto por você como pelo programador que fez a outra classe. A única troca de informação é que você pega um float dele e ele pega o nome do seu funcionário ou código dele da empresa. O mais importante disso é: em nenhum momento foi necessário um ver o código do outro! Na hora de trabalhar, isso nos diz muito em termos de rendimento! 5.2.5.Como saber quando usar Classes e Objetos em Java Como você pode notar, através dos exemplos dos Carros, das Pessoas e dos Funcionários, as Classes são nada mais que um grupo de informações. Sempre que quiser usar essas informações, declare um Objeto daquela classe. Ou seja, sempre que quiser generalizar ou criar um grupo com características parecidas, não tenha dúvida, use Classe e Objetos. Em um jogo, Worms Armageddon ou Counter-Strike, por exemplo. Existem vários jogadores. Ora, eles são parecidos, tem semelhanças e características em comum. Não perca tempo declarando seus atributos individualmente, use classes e objetos. Na verdade, em Java, tudo são classes e objetos, então não há muito essa preocupação. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 47 Em C, não existe Orientação a Objetos. Em C++, você escolhe se usa ou não. Adiante, veremos que uma classe pode se parecer com uma e outra, pegar 'emprestado' detalhe de outras, implementar ou estender outras. Existem vários recursos para serem usados nas Classes, inclusive de segurança, que permitem que alguns objetos tenham acesso a alguns dados, outros não. Recursos gráficos: por exemplo, as janelas dos aplicativos Java, botões, menu e tudo mais são classes. Como dissemos, Java gira em torno de orientação a objetos, e Java é uma linguagem de programação riquíssima e ilimitada. Logo, o que é possível fazer com as classes e objetos também é bem vasto. 5.3. Criação de Classe Começaremos agora a ver a alma da programação Java que é a orientação a objeto. Sempre que programamos em Java, devemos pensar em como montar as definições de nosso objeto. Ou seja, quais atributos uma classe deve conter, simplificando, quais características tem tal objeto. É como pensar em alguma coisa. Por exemplo, se pensarmos em relógio, a primeira coisa que nós vem a cabeça é hora, minuto, segundo e assim por diante. Nós também podemos ajustar as horas, ajustar o alarme, etc. A princípio, vamos nos ater aos detalhes técnicos da programação de uma classe. Para criar uma classe usamos a palavra chave class, e após a definição do nome de nossa classe, nós definimos seus atributos. Para exemplificar, criaremos uma classe que terá as características mais simples de uma televisão. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 48 pubic class TV{ int tamanho; int canal; boolean ligada; } Pronto, esses são os atributos de uma classe, ou seja, nós definimos que existe um objeto chamado TV e que ele tem três características: uma dessas características é o tamanho, outra é um valor inteiro identificado por canal e mais outra característica que determina se ele está ligado ou não. Como podemos perceber, isso é mais um conceito (paradigma) de como devemos pensar. Uma classe (ou objeto) pode ser muito implementado, tornando-se um objeto com várias características que pode ser facilmente manipulado e incorporado por outros objetos. Isso é o que chamamos de reutilização de código, que envolve vários aspectos importantes da orientação a objeto como herança, interface, enumeradores, sobrecarga de métodos entre outros que nós estudaremos nas próximas páginas. 5.4. Métodos Construtores Vimos anteriormente que é simples criar uma classe. Mas, para realmente conseguirmos utilizar a classe, ela deve conter pelo menos um método construtor. O método construtor é desenvolvido da mesma forma que uma função, a única diferença é que ele tem o mesmo nome da classe. Isso se deve ao fato de que um objeto deve ser construído cada vez que chamamos a classe. E a responsabilidade de fazer isso é do construtor. Isso parte do princípio que podemos ter dois objetos com a mesma característica, mas que não são os mesmos objetos. Ou seja, nós podemos ter uma TV de 29" ligada no canal 15 e nosso amigo tem www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 49 uma outra TV que também é de 29" e está ligada no canal 15. Perceba que ambas as TVs têm as mesmas características, mas continuam sendo duas TVs diferentes. Sempre que criamos uma classe, Java automaticamente vincula um método construtor padrão interno com o mesmo nome da classe, mas sem inicializar nenhum atributo. Para demonstrar um método construtor, criaremos um construtor padrão sem argumentos no qual já contém os valores dos atributos definidos por nós mesmos. Então, vamos imaginar que sempre que uma TV é construída, o seu padrão é tamanho 21", desligada e no canal 0. Então, podemos defini-lo como: public class TV { int tamanho; int canal; boolean ligada; TV(){ tamanho=21; canal=0; ligada=false; } } 6. Estrutura de Dados Hoje em dia, a grande maioria das pessoas utilizam a agenda do celular para armazenar seus contatos. As tarefas de uma agenda de contatos são basicamente duas: 1.Definir como as informações dos contatos serão armazenadas. Uma informação armazenada em algum lugar (pedaço de papel, livro, computador, etc) é um dado. 2.Disponibilizar operações para criar, recuperar, ordenar, atualizar e remover contatos. Além de operações para informar o estado da agenda (a quantidade de contatos existentes na agenda ou a quantidade de espaço disponível para novos www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 50 contatos). A primeira tarefa é crucial para o desempenho. Se a agenda armazena as informações de uma forma desorganizada então será muito mais complicado manipular os dados de forma eficiente. A escolha de como guardar as informações deve levar em consideração as operações que serão disponibilizadas pela agenda. Por exemplo, seria interessante manter os contatos em ordem alfabética para facilitar a busca. Mas, apesar da importância de como os contatos são armazenados, a organização interna da agenda não precisa e não deve ser exposta ao usuário. Afinal de contas, o que o usuário deseja é usar a agenda através das operações e que tudo seja feito o mais rápido possível. A única coisa que precisa ser mostrada para o usuário são as operações que ele pode fazer na agenda (inserir, recuperar, atualizar, remover contato, saber quantos contatos estão na agenda, etc). Este conjunto de operações é interface que o usuário tem com a agenda. Cada celular pode implementar a sua agenda de contatos de uma forma totalmente diferente um do outro, na tentativa de obter mais performance, ser mais confiável ou gastar menos memória. Porém o conjunto básico de operações oferecidas pelas agendas é sempre o mesmo. Isso facilita a vida do usuário pois se ele tiver que trocar de celular não vai ter que aprender novamente como usar uma agenda de contatos. Essa é a grande vantagem em se pensar em interface. Mantida a interface, podemos trocar uma agenda que não é tão eficiente ou que já não atende mais as nossas necessidades por outra mais eficiente ou adequada, sem problemas em ter de aprender a usar a nova agenda: troca-se a implementação, mas não mudamos a interface. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 51 Uma agenda de celular pode ser vista como uma estrutura de dados. Uma estrutura de dados mantém os dados organizados seguindo alguma lógica e disponibiliza operações para o usuário manipular os dados. É importante, quando programar, não misturar dado e estrutura de dados em uma coisa só. Um dado é uma informação armazenada e estrutura de dados é quem administra os dados. O ideal é que a estrutura de dados seja o mais independente possível dos dados que ela vai armazenar. Desta forma pode-se aproveitar a mesma estrutura de dados para diversos tipos de dados. Por exemplo, é melhor ter uma agenda genérica do que uma agenda de telefones. Uma agenda genérica pode ser utilizada para guardar telefones, ou emails, ou até mesmo guardar uma outra estrutura dentro dela: contatos, que seriam compostos por nome, telefone e email. Algumas estruturas de dados são apenas agrupamentos de dados sem um objetivo de aplicar algum algoritmo ou tirar proveito de sua estrutura. Um exemplo seria a estrutura Contato. Algumas outras estruturas são mais espertas e trabalhosas, como a Agenda, assim como Listas Ligadas, Vetores, Tabelas de Espalhamento e outras que veremos no decorrer da apostila. Estas estruturas, por sua característica mais complexa e de poder ser reutilizada em outros contextos, devem ser criadas da forma mais independente possível dos dados que estarão dentro dela. Em outras palavras, não devemos misturar a Agenda e o Contato de maneira rígida, para que com isso possamos criar outras Agendas, como por exemplo uma Agenda de Fornecedor. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 52 6.1. Vetores e Matrizes Vetores e Matrizes são estruturas de dados muito simples que podem nos ajudar muito quando temos muitas variáveis do mesmo tipo em um algoritmo. Imagine o seguinte problema: Você precisa criar um algoritmo que lê o nome e as 4 notas de 50 alunos, calcular a média de cada aluno e informar quais foram aprovados e quais foram reprovados. Conseguiu imaginar quantas variáveis você vai precisar? Muitas né? Vamos fazer uma conta rápida: 50 variáveis para armazenar os nomes dos alunos, (4 * 50 = ) 200 variáveis para armazenar as 4 notas de cada aluno e por fim, 50 variáveis para armazenar as médias de cada aluno. 300 variáveis no total, sem contar a quantidade de linhas de código que você vai precisar para ler todos os dados do usuário, calcular as médias e apresentar os resultados. Mas eu tenho uma boa notícia pra você. Nós não precisamos criar 300 variáveis! Podemos utilizar Vetores e Matrizes (também conhecidos como ARRAYs). Vetor (array uni-dimensional) é uma variável que armazena várias variáveis do mesmo tipo. No problema apresentado anteriormente, nós podemos utilizar um vetor de 50 posições para armazenar os nomes dos 50 alunos. Matriz (array multi-dimensional) é um vetor de vetores. No nosso problema, imagine uma matriz para armazenar as 4 notas de cada um dos 50 alunos. Ou seja, um vetor de 50 posições, e em cada posição do vetor, há outro vetor com 4 posições. Isso é uma matriz. Cada item do vetor (ou matriz) é acessado por um número chamado de índice. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 53 6.2. Vetor Vetores, também muito conhecidos como arrays, são variáveis que servem para guardar vários valores do mesmo tipo de forma uniforme na memória. Por exemplo, se tivemos que criar 20 variáveis do mesmo tipo que querem dizer a mesma coisa, nós não criaríamos -> int var1, var2, var3, var4, var5, ... ao invés disso, criaríamos apenas uma variável de vetor para guardar todos os 20 números de uma vez. Como um vetor pode guardar vários valores temos que definir quantos valores ele deve guardar para que seja reservado o espaço necessário em memória. Primeiramente, vamos aprender como declarar um vetor. Para declarar um vetor devemos especificar o tipo ou classe de dado que será armazenado nele. Após isso, damos um nome a esse vetor. E, para finalizar, indicamos que ele é um vetor, simplesmente abrindo e fechando colchetes ( [ ] ). Portanto, se quiséssemos um vetor de números inteiros chamado meu vetor, declararíamos da seguinte forma: int meuVetor [ ]; Agora que já declaramos o vetor, devemos dar um tamanho a ele, para que seja reservado espaço suficiente em memória. Para fazermos isso, utilizaremos um instanciador chamado new. New é muito importante, pois ele irá criar de fato o vetor. Para indicarmos o tamanho usamos o instanciador new, depois o tipo de dado do vetor e entre colchetes o tamanho do vetor. Tomando o exemplo acima, vamos indicar que meuVetor terá o tamanho 4. Então, a linha de cima ficaria: int meuVetor[ ] = new int [4]; www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 54 Na memória é representado da seguinte forma: Uma única variável com 4 espaços nos quais podem ser guardados números inteiros. Acessando uma posição no Vetor Agora, para acessarmos um local específico dessa memória devemos indicar entre colchetes a posição desejada no vetor que chamamos de index. O importante mesmo é saber que não importa o tamanho do vetor, o index (número que indica a posição) sempre começa em 0. Ou seja, um vetor de tamanho 20 vai da posição 0 a 19, um vetor de tamanho 180 vai da posição 0 a 179. Portanto, um vetor de tamanho 4 vai da posição 0 a 3. Agora, se quisermos atribuir os valores 540 na posição 1 e 8456 na posição 3, faríamos: meuVetor [1]=540; meuVetor [3]=8456. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 55 Não podemos nunca nos esquecer que o limite do vetor é sempre seu tamanho menos 1. Usando o exemplo: vetor de tamanho 4, posição máxima é 3 (pois 4-1=3). Então, se atribuirmos um valor a posição 4 ocorrerá um erro. Resumidamente, jamais poderíamos fazer meuVetor [4]=200. 6.2.1 Inicialização direta de Vetor Podemos inicializar um vetor diretamente, sem a necessidade de instanciá-lo com new. Para isso, após a declaração do vetor, basta colocar seus valores em chaves, separando cada valor por vírgula. Por exemplo, se quiséssemos inicializar o meuVetor com os valores 450, 200, 1000, 700, faríamos: int meuVetor [ ] = { 450, 200, 1000, 700 }; 6.3. Matrizes Matrizes são vetores multidimensionais, ou seja, eles não são totalmente lineares, e sim, geométricos. Enquanto um vetor tem apenas uma linha com vários valores, uma matriz pode, por exemplo, tem várias linhas com vários valores, que comumente chamamos de linhas e colunas. Para criarmos um vetor multidimensional (ou matriz), procedemos da mesma forma www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 56 que um vetor normal, porém com mais um dimensionador (os colchetes). Então, se quisermos criar um vetor (matriz) bidimensional com 3 linha e 5 colunas, faríamos: int minhaMatriz [ ][ ] = new int [3][5]; Na memória é representado como: Isso também pode ser feito para adquirirmos o formato de matriz que quisermos. Ou seja, se fosse uma matriz tridimensional, bastaria ter três dimensionadores, se fosse 4D, então, 4 dimensionadores, se fosse 5D (apesar de geometricamente difícil de imaginar) seriam 5 dimensionadores. E assim por diante. 6.4. ArrayList Até o momento, nessa seção de Estrutura de Dados de nosso curso de Java, vimos o quão útil são os arrays e as operações que podemos fazer com esses arrays, também conhecidos por vetores. Porém, há um grande problema neles: são estáticos. Ou seja, tem tamanho definido, não podemos adicionar nem excluir nada neles, o que é bastante incômodo e faz com que arrays em Java sejam limitados. E por que arrays não são muito úteis? www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 57 Porque na vida real as coisas não são assim estáticas, elas mudam. O número de funcionários de um empresa tendem a crescer, em uma faculdade alunos se formam e outros se matriculam, em um jogo de RPG vamos colecionando itens no decorrer do jogo, ao passo que vamos usando outros. Agora vamos aprender como usar os ArrayList, que são arrays mais 'flexíveis', ou dinâmicos, já que podemos adicionar ou retirar elementos, além de fazer outras coisas que não são possíveis com os Arrays. 6.4.1. O que são ArrayList em Java O Java, por padrão, possui uma série de recursos prontos (APIs) para que possamos tratar de estrutura de dados, também chamados de coleções (collections). Podemos dizer que ArrayList é uma classe para coleções. Uma classe genérica (generic classes), para ser mais exato. Coleções mesmo, de qualquer tipo de 'coisa' ou dado, não somente de tipos primitivos. Você pode criar seus objetos - através de uma classe - e agrupá-los através de ArrayList e realizar, nessa coleção, várias operações, como: adicionar e retirar elementos, ordená-los, procurar por um elemento específico, apagar um elemento específico, limpar o ArrayList dentre outras possibilidades. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 58 6.4.2. Como declarar e usar ArrayList em Java Importe: import java.util.ArrayList; Por ser um tipo diferente, sua sintaxe é um pouco diferente do que você já viu até então: ArrayList< Qualquer_Tipo > nomeDoArrayList = new ArrayList< Qualquer_Tipo >(); No exemplo a seguir, vamos usar um ArrayList de String para trabalhar com o nome de várias Bandas de música: ArrayList<String> bandas = new ArrayList<String> (); 6.4.3. Exemplo de uso do ArrayList Após declarar a ArrayList 'bandas' que armazenará Strings, vamos adicionar alguns nomes. Primeiro adicionamos a banda "Rush": bandas.add("Rush"); Existe um método do ArrayList chamado 'toArray()' que coloca todos os elementos de um ArrayList em um Array. Ou seja: bandas.toArray() é um Array! Porém, já vimos que existe um método 'toString' da classe Arrays que retorna uma String com os elementos de um Array. Vamos usar esse método parar exibir todos os elementos do ArrayList, que transformamos em Array através do método 'toArray()': www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 59 Arrays.toString( bandas.toArray() ); Vamos adicionar a segunda banda, "Beatles" e imprimir, usando o mesmo método. Note que quando usamos 'add', sempre adicionamos o elemento pro fim da ArrayList. Confirme isso agora, vendo que a banda "Iron Maiden" ficará depois de "Beatles". Vamos pegar o primeiro elemento, o elemento '0', através do método 'get': bandas.get(0); Note que é a banda "Rush", pois ela foi a primeira a ser adicionada. Vamos adicionar o "Tiririca" na posição do "Rush", ou seja, na posição '0': bandas.add(0,"Tiririca"); ou bandas.add( bandas.indexOf("Rush"), "Tiririca"); Pois o método 'indexOf' retorna o índice em que ocorre "Rush". Para saber o tamanho que tem seu ArrayList, basta usar o método 'size()': bandas.size(); Feito isso, rapidamente remova o "Tiririca", pois alguém pode ver. Para tal, use o método 'remove': bandas.remove("Tiririca"); Ok. Não quer mais brincar de ArrayList? Remova tudo bandas.clear(); www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA import java.util.ArrayList; import java.util.Arrays; public class arrayLists{ public static void main(String[] args){ ArrayList<String> bandas = new ArrayList<String> (); bandas.add("Rush"); System.out.print( "Adicionando a banda Rush: " ); System.out.println( Arrays.toString( bandas.toArray() ) ); bandas.add("Beatles"); System.out.print( "Adicionando a banda Beatles: " ); System.out.println( Arrays.toString( bandas.toArray() ) ); bandas.add("Iron Maiden"); System.out.print( "Adicionando a banda Iron Maiden: " ); System.out.println( Arrays.toString( bandas.toArray() ) ); System.out.print( "Quem está na índice 0: " ); System.out.println( bandas.get(0) ); System.out.print( "Adicionando Tiririca onde estava o Rush: " ); bandas.add( bandas.indexOf("Rush"), "Tiririca"); System.out.println( Arrays.toString( bandas.toArray() ) ); System.out.print( "Número de elementos na lista: " ); System.out.println( bandas.size() ); System.out.print( "Removendo o Tiririca: " ); bandas.remove("Tiririca"); System.out.println( Arrays.toString( bandas.toArray() ) ); System.out.print( "Removendo tudo: " ); bandas.clear(); System.out.println( Arrays.toString( bandas.toArray() ) ); } } Saída www.primebean.com.br www.primebean.com.br/joeydecurcio 60 Introdução á Linguagem de Programação JAVA 61 Adicionando a banda Rush: [Rush] Adicionando a banda Beatles: [Rush, Beatles] Adicionando a banda Iron Maiden: [Rush, Beatles, Iron Maiden] Quem está na índice 0: Rush Adicionando Tiririca onde estava o Rush: [Tiririca, Rush, Beatles, Iron Maiden] Número de elementos na lista: 4 Removendo o Tiririca: [Rush, Beatles, Iron Maiden] Removendo tudo: [] 7. Constantes Constantes são o oposto das variáveis. A diferença está em não podermos atribuir um novo valor, pois ele recebe um valor final imutável. Isso ajuda na hora que temos que lembrar de algum número muito grande ou muito pequeno, ou até mesmo um valor que aparentemente não nos diz nada, mas que significa alguma coisa. Um exemplo bem simples seria 000000. Mas, o que é 000000? É difícil saber o que ele significa, mas é muito mais fácil entender que preto em Java é Color.BLACK. Ou seja, BLACK é uma constante que guarda sempre o mesmo valor (000000). Para criarmos uma constante em Java é muito simples. Primero nos atemos ao fato de que uma constante criada dentro de uma classe deve ser acessada por qualquer membro da classe, então, por definição, essa constante é também global ou estática (static). Como uma constante não muda seu valor, então, marcamos ela com a palavra chave final, que fará com que o valor nunca seja modificado. Toda constante é um dado, portanto, o seu tipo de dado também é obrigatório declarar. Então, para declarar uma constante faríamos: static final long CONST1 = 1L; ou final long CONST2 = 1L; www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 62 No qual, CONST1 seria uma constante global (ou seja, foi declarada no corpo da classe) e CONST2 seria uma constante local (ou seja, foi declarada no corpo de alguma função ou método, por exemplo, dentro de main) Para ilustrar bem o uso de constantes, vamos calcular a área e o comprimento de um círculo. O porque deste cálculo é que necessitaremos de um número constante chamado PI. PI é um número irracional, ou seja, não há uma representação exata dele, mas, para o nosso exemplo, usaremos ele com uma precisão de 8 casas decimais. Portanto, nosso pi será do tipo double que valerá 3,14159265. Então, perceba que é muito mais fácil se lembrar da palavra pi do que do número 3,14159265. Além de, obviamente, digitarmos bem menos. Então, só para esclarecer o que irá acontecer: O cálculo da área do círculo equivale a raio2 × pi, e o comprimento é medido em 2 × raio × pi, no qual o raio é a distância entre a borda do círculo e seu centro. Vamos usar um raio de 25cm. Vejamos o resultado. public class Constantes { static final float PI = 3.14159265f; public static void main(String args[]) { float raio = 25f; float comprimento = raio * 2 * PI; float area = (raio * raio) * PI; System.out.println("Dados de um círculo de " + raio + "cm:\n" + "comprimento: " + comprimento + "cm\n" + "Área: " + area + "cm2"); } } Exite uma infinidade de constantes que são implementadas em várias classes diferentes como por exemplo BLACK da classe Color, PLAIN_MESSAGE da classe JOptionPane e até mesmo o PI da classe Math com muito mais precisão do que este que www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 63 usamos no exemplo. 8. Funções Funções são rotinas ou sub-rotinas automatizadas. Sempre que pretendemos usar a mesma codificação para algo específico, criamos uma função. Dessa forma, sempre que quisermos utilizar aquela codificação, ao invés de nós a digitarmos inteira novamente, simplesmente chamamos a função. Funções são extremamente úteis e adaptáveis, e o conceito de funções é importante para mais a frente entendermos o funcionamento e criação dos métodos. 8.1. Criando funções sem argumentos Para criar uma função, temos que ter sempre em mente que toda função é global, ou seja, é estática (static). As funções mais básicas são aquelas que apenas executam uma rotina, portanto, não recebem nenhum argumento. No código, digitaríamos dentro da classe, mas fora da função main o seguinte: public static void nomeDaFunção () { código da função } Static porque pode ser acessado globalmente; void porque não retorna nenhum valor; mesmo não tendo argumentos, é necessário ter parênteses. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 64 Vamos ver o exemplo: public class ExemploFuncao { //criando a função public static void mostrarMensagem() { System.out.println("Minha Mensagem"); } public static void main(String[] args) { //chamando a função dentro do programa mostrarMensagem(); } } O código acima funciona da seguinte maneira: Primeiro é criada a função mostrarMensagem(), que em seu corpo tem apenas um println com uma mensagem. Depois iniciamos nosso programa com o main. Dentro do main chamamos a função. Para isso, basta colocar o nome da função. Quando a função é chamada, o código dentro do corpo da função é executado. Concluindo, o programa acima apenas mostra na tela a mensagem Minha Mensagem. 8.2. Funções com argumentos Funções com argumentos funcionam e são criadas da mesma forma que uma função sem argumento, porém com uma diferença. A diferença está que haverá informações necessárias para que a função processe, e essas informações serão descritas dentro dos parênteses. Uma função pode ter um ou vários argumentos desde que separados por vírgula (,). Cada argumento deve ter seu tipo de dado declarado. Então, todos os exemplos abaixo são funções válidas: www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 65 public static void funcao1 (String arg1){} public static void funcao2 (int arg1, int arg2){} public static void funcao3 (String arg1, char arg2, int arg3, float arg4, Object arg5) {} Para demonstrar este tipo de função criaremos uma função que mostra na tela o resultado fatorial de um número. Além disso, colocaremos esta função dentro de um loop que irá de 1 a 10 para ele mostrar cada um desses fatoriais. public class FatorialComFuncao { public static void fatorar(int numero) { int fator = 1; for (int i = numero; i > 1; i--) { fator *= i; } System.out.println(numero + "! = " + fator); } public static void main(String args[]) { for (int x=1; x<=10; x++) fatorar (x); } } Simplificando, x que está sendo passado pelo main para fatorar() será o valor int numero da função fatorar. 8.3. Funções que retornam valores Aqui veremos a grande vantagem de se criar uma função. Funções podem retornar valores de um processo executado dentro delas e esse valor pode ser guardado dentro de www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 66 uma variável no programa. Isso com certeza deixa nosso código mais simples, pois podemos destacar processos repetitivos e guardar em uma variável apenas o resultado daquele processo. Para criar uma função que retorna valores temos que nos ater ao fato retorno. Como todas as outras funções não retornavam valores, então, seu retorno era vazio void. Agora, temos que declarar que tipo de retorno virá da função. O retorno é dado pelo comando return, que finaliza a função e mostra o retorno. A variável ou valor que utilizarmos para return será o tipo de retorno da função. Vamos imaginar que três funções, sendo que a primeira irá retornar um inteiro, a segunda um double e a terceira uma string. Então, as criaríamos da seguinte maneira: public static int funcaoDeInteiro (){} public static double funcaoDeDouble (){} public static String funcaoDeString (){} No exemplo abaixo, nós criaremos uma função que irá retornar um valor booleano (verdadeiro ou falso). Usando este retorno, determinaremos o que fazer dentro de uma estrutura seletiva (if). public class Primo { public static boolean ehPrimo(long nr) { if (nr < 2) return false; for (long i = 2; i <= (nr / 2); i++) { if (nr % i == 0) return false; } return true; www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 67 } public static void main(String[] args) { long x = 5; if (ehPrimo(x)) // se for primo System.out.println(x + " é primo"); else // se não for primo System.out.println(x + " não é primo"); } } O algoritmo utilizado acima é muito solicitado em cursos de programação e faculdades. O que a função faz é verificar se um número é primo ou não. 9. Igualdade de Objetos em java - equals() e hashCode() Um dos maiores problemas que os programadores encontram ao inciar seu trabalho em java é o de entender os testes de igualdade. A igualdade em java não pode ser testada através do operador == , estes operador apenas verifica se duas variáveis fazem referencia a mesma instancia de um objetos. Para ser um pouco mais claro, imaginemos uma classe Pessoa, como segue abaixo. public class Pessoa { private String nome; private String cpf; public Pessoa(String nome, String cpf){ this.nome= nome; this.cpf = cpf; www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 68 } public String getNome(){ return nome; } public String getCpf() { return cpf; } } Como posso eu falar que duas pessoas são as mesmas pessoas ? a JVM (Java Virutal Machine) por se só não tem como identificar como duas pessoas podem ser ditas iguais, desta forma o teste abaixo, verifica apenas se estas são instancias de um mesmo objeto. Pessoa maria = new Pessoa("Maria da Silva","111.222.333-44"); Pessoa mariaDaSilva = new Pessoa("Maria da Silva","333.555.222-11"); Apesar dos nomes iguais de maria e mariaDaSilva, os cpfs são diferentes e desta forma posso falar que são pessoas diferentes. Pessoa mariaDaSilva2 = new Pessoa("Maria da Silva","333.555.222-11"); Os Objetos mariaDaSilva e mariaDaSilva2 são pessoas iguais, em um teste de igualdade eu vou querer que para esses 2 objetos ele seja positivo, porem são 2 instancias de de objetos diferentes, portanto: www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 69 boolean referencia = mariaDaSilva == mariaDaSilva2; System.out.println("Referencia é falso ("+ referencia +)"); Isso ocorre porque a variável mariaDaSilva aponta para um objeto enquanto a variável mariaDaSilva2 aponta para outro objeto. 9.1. Equals: Para resolver esse problema em java existe um mecanismo de igualdade que vem em todo objeto, e descende da classe Object, onde você pode testar a igualdade entre objetos através de: este teste, quando não sobrescrito apenas testa se os 2 objetos são referencia de uma mesma instancia. Antes de implementar um equals em nossos objetos é preciso saber de cinco regras. • É reflexivo: para qualquer qualquer referencia não nula a, a.equals(a) tem sempre que ser verdadeiro, ou seja, um objeto é sempre igual a se mesmo. • É simétrico: para quaisquer referencias não nulas de a e b, a.equals(b) so poderá retornar verdade se b.equals(a) retornar verdade, o mesmo raciocínio vale para falso. • É transitivo: para quisquer referencias não nulas de a,b e c, se a.equals(b) e b.equals(c) são verdade então também tem que ser verdade que a.equals(c). • É consistente - para quaisquer referencias não nulas de a e b, múltiplas invocações de a.equals(b) terá sempre que retornar true ou sempre retornar false, enquanto informações usadas na comparação do equals não sejam alteradas. • O resultado de equals() entre um objeto e nulo deve retornar sempre falso, www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 70 a.equals(null) é sempre falso. Com essa ideia podemos pensar em como implementar o equals para nossa classe Pessoa, sabemos que, duas Pessoas de mesmo nome podem ser diferente, portanto esse não pode ser nosso parâmetro para teste. Duas pessoas não podem ter o mesmo número de CPF, então este número é único, e pode identificar uma pessoa, sendo assim nosso teste de igualdade entre duas pessoa pode ser. Com essa ideia podemos pensar em como implementar o equals para nossa classe Pessoa, sabemos que, duas Pessoas de mesmo nome podem ser diferente, portanto esse não pode ser nosso parâmetro para teste. Duas pessoas não podem ter o mesmo número de CPF, então este número é único, e pode identificar uma pessoa, sendo assim nosso teste de igualdade entre duas pessoa pode ser: @Override public boolean equals(Object obj){ if(obj == null){ return false;//nenhum objeto pode ser igual a null } if(!obj instanceof Pessoa) {//uma pessoa só pode ser igual a outra pessoa return false; } final Pessoa other = (Pessoa) obj; if (getCpf() ==null)//se não houver CPF não há como testar as duas pessoas. return false; return getCpf().equals(other.getCpf()); //duas pessoas serão iguais... //se seus CPFs forem iguais... } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 71 9.2. HashCode: Assim como há um teste de igualdade, Java ainda dispõem de outro teste, onde é possível rapidamente, através de integer, restringir o campo de igualdade, através de hashCode(). assim como equals, o hashCode segue um contrato descrito abaixo: • É constante: A qualquer momento durante a excecução de um programa java, o método hashCode deve constantemente retornar o mesmo inteiro, enquanto informações usadas na comparação do equals não sejam alteradas. O hashCode não precisa ser constante de uma execução da aplicação para outra. • Se dois objetos a e b, são iguais, a.equals(b) retorna verdadeiro, então os inteiros produzidos por a e b devem ser os mesmos, ou seja a.hashCode() == b.hashCode() • O inverso não é necessariamente verdadeiro, dois objetos que produzirem o mesmo hashCode podem ser diferentes Diante disso a utilização do hashCode é principalmente para excluir igualdade, ou seja, ele serve como uma peneira, e é largamente utilizado por Collection em buscas como contains, remove, removeAll, retainAll entre outras coisas. A ideia é se os hashCode são diferentes então não é preciso testar a igualdade, pois já se garante que os objetos não serão iguais, poupando processamento no momento da busca, pois hashCode usa um calculo com int, que consome pouco processo, geralmente bem menos que o equals. Existem varias estrategias para calculo do hashCode, desde a mais simples, onde você praticamente exclui a funcionalidade do hashCode, deixando seu valor constante para qualquer objeto. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 72 @Override public int hashCode(){ return 0; } Este método acima, funciona e respeita as regras de contrato de hashCode, porem seu programa poderá perder em velocidade. É extremamente desaconselhável o uso de hashCode constante para qualquer objeto, pois várias funcionalidade que otimizam processos de busca não terão serventia com um hashCode mau projetado. A melhor estratégia para hashCode é olhar para equals, e verificar como a igualdade é exigida, e assim montar um hashCode, concatenando os hashCode dos objetos que fazem a igualdade e designando um peso para as propriedades. Por exemplo, para nossa classe Pessoa uma boa estrategia de hashCode seria: @Override public int hashCode() { int hash = 7; hash = 23 * hash + (getCpf() != null ? getCpf().hashCode() : 0); return hash; } O número 7 contido nesse hashCode é apenas um número randômico para startar o hashCode, e diferenciar de outros objetos, por exemplo, um objeto empresa poderia iniciar por 3. o número 23 é outro número randômico, usado para quando há varias propriedades e escalar o hashCode entre as varias propriedade que definem um objeto igual. Como no exemplo acima usamos o hashCode da string cpf, e como String tem seu hashCode bem implementando, podemos assim garantir que sempre que os CPF forem iguais os hashCode serão iguais. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 73 A igualdade entre objetos é uma parte fundamental da programação, e é uma das necessidades básica de logica, saber se dois objetos são iguais. A implementação destes dois métodos é importante, e deve ser implementado em todas as classes instanciáveis do projeto, de forma a prover mecanismos corretos de comparação de igualdade (equals), assim como uma forma de otimizar os processos de busca (hashCode). Muitos programadores só começam a entender a real necessidade da correta implementação destes dois métodos ao utilizar mais largamente a Java Collection Framework do pacote java.util, pois vários de seus métodos como contains, removeAll, remove, ratainAll, etc, falham quando equals não esta corretamente implementado, e perdem performance ou falham quando hashCode não esta otimizado ou corretamente implementando. 10. Representação textual de objetos - método toString() O Java usa o método toString() toda vez que for necessário converter um objeto em String, ou seja, para obter uma representação textual do objeto. Por exemplo para imprimir um objeto qualquer usando System.out.println ou para mostrar os itens de um JComboBox (usando o Renderer padrão). Esse método toString() é definido na classe Object, portanto é herdado por todos os objetos - todos os objetos são capazes de gerar uma representação textual. Mas o método do Object não conhece as classes derivadas, não sabe como o objeto deve ser representado. Por isso usa um padrão: o nome da classe seguido por um '@' e pelo hashCode em hexadecimal da instância em questão: public String toString(){ return getClass().getName() + "@" + Integer.toHexString(hashCode()); } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 74 Exemplo: public class Pessoa { private final String nome; private int idade; public Pessoa(String oNome, int aIdade){ nome = oNome; idade = aIdade; } public static void main(String[] args) { Pessoa pessoa = new Pessoa("fulano", 21); System.out.println(pessoa); //equivale a System.out.println(pessoa.toString()); } } vai imprimir algo como "Pessoa@1b533b0" (provavelemnte com outro número). Esse formato normalmente não é o que queremos! Por isso temos que sobrescrever o método toString() para obter a representação desejado. Exemplo, para mostrar o nome e a idade (entre parênteses) da pessoa, adicionamos o método toString(): public class Pessoa { private final String nome; private int idade; public Pessoa(String oNome, int aIdade) { nome = oNome; idade = aIdade; } @Override public String toString() { return nome + "(" + idade + ")"; } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 75 public static void main(String[] args) { Pessoa pessoa = new Pessoa("fulano", 21); System.out.println(pessoa); } } Dessa vez obteremos, como desejado "fulano(21)". O mesmo problema ocorre com um vetor (Array): ... public static void main(String[] args) { int[] array = {1, 2, 3}; System.out.println(array); } ... Irá imprimir algo como "[I@15497e0" - "[I" representa um array de int's. O problema é que não tem como sobrescrever o toString() de um Array, mas podemos usar a classe auxiliar Arrays do pacote java.util que contém vários métodos estáticos para trabalhar com um Array. No nosso caso podemos usar o toString(int[]): ... public static void main(String[] args) { int[] array = {1, 2, 3}; System.out.println(Arrays.toString(array)); } ... Imprimirá "[1, 2, 3]"@146c21b A em síntese o problema é sempre que obter algo como "Classe@146c21b" é porque a classe em questão não sobrescreveu o método toString(). A solução, é implementar/sobrescrever o método toString() do Objeto ou usar o Arrays.toString() se for um Array. (Exemplos acima) www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 76 11. Instanciando Objetos Objetos são estruturas de dados definidas e agrupas dentro de uma classe. Sempre que utilizamos um objeto ou classe devemos reservar espaço em memória para que aquele objeto seja manipulado sem maiores problemas. Além do mais, também podemos utilizar a mesma classe (com todos os seus métodos e atributos) para manipular outros objetos que serão tratados de forma diferente (mesmo se tiverem as mesmas características do objeto anterior), pois serão dois endereços de memória diferentes. A vantagem de Java é nos possibilitar uma instanciação rápida e simples, sem termos que nos preocupar com referência a endereços e alocação dinâmica de memória, pois quem trata de manipular a memória é o próprio Java. Sem contar que, se um objeto não é mais referenciado dentro do programa, o próprio Java trata de liberar os recursos de memória consumidos pelo objeto usando o Garbage Colletor - Coletor de Lixo. Quem faz o papel de instanciador em Java é o new. New trata de reservar memória o suficiente para o objeto e criar automaticamente uma referência a ele. Para new conseguir determinar o objeto, precisamos usar o método construtor que será usado como base para instanciar a classe e gerar o objeto. Tecnicamente, declaramos uma variável qualquer como sendo do tipo da classe (ex.: TV minhaTV; ), depois instanciamos o objeto atribuindo a variável o resultado obtido por new mais o método construtor (ex.: minhaTV = new TV(); ). Apesar de parecer muitos detalhes, isso fica mais facilmente visualizado no código abaixo. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 77 public class TV { int tamanho; int canal; boolean ligada; TV() { tamanho = 21; canal = 0; ligada = false; } public static void main(String[] args) { TV objeto1 = new TV(); TV objeto2; objeto2 = new TV(); } } No código acima, criamos uma classe chamada TV com os mesmos atributos do exemplo da página Criação de Classes, e criamos um método construtor que inicializa os atributos da classe TV com alguns valores. Declaramos duas variáveis chamadas objeto1 e objeto2 sendo do tipo TV. Depois, instanciamos o objeto usando new e o método construtor. 12. Auto Referencia de Objetos - This This é usado para fazer auto-referência ao próprio contexto em que se encontra. Resumidamente, this sempre será a própria classe ou o objeto já instanciado. Esse conceito de auto-referência é importante para que possamos criar métodos construtores sobrecarregados e métodos assessores mais facilmente. Por base, se criarmos um método que receba um argumento chamado ligado que queremos atribuir para o atributo da classe, que também se chama ligado, devemos diferenciar ambos www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 78 mostrando a quem cada um pertence. Como this se refere ao contexto empregado, então o usamos para identificar que ligado será o atributo da classe e ligado sem o this se refere ao parâmetro do método. O que resultaria nisto: public class TV { //atributos int tamanho; int canal; boolean ligada; // método contrutor com parâmetro TV(boolean ligada) { this.ligada = ligada; /** * Onde this.ligada é o atributo * e ligada é o valor do parâmetro */ } } Traduzindo, this.ligada seria: a variável ligada desta classe recebe o valor de ligada, ou seja, o único ligada que existe fora o atributo é o parâmetro. 13. Sobrecarga de métodos Java nos permite criar vários métodos com o mesmo nome desde que tenham parâmetros diferentes. Isso é o que chamamos de sobrecarga de métodos. A sobrecarga de métodos consiste em criarmos o mesmo método com possibilidades de entradas diferentes. Essas entradas, caracterizadas como parâmetros, devem sempre ser de tipos diferentes, quantidades de parâmetros diferentes ou posições dos tipos diferentes. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 79 Para visualizarmos um cenário, vejamos a classe abaixo: public TV { int canal; int volume; boolean ligada; int tamanho; } Agora, criaremos o método ligar. O método ligar, simplesmente, muda o valor dos atributos canal e volume para 3 e 25, respectivamente. void ligar (){ canal = 3; volume = 25; ligada = true; } Agora, vamos personalizar este método para que ele mude o atributo ligada de acordo com o parâmetro. void ligar (boolean ligada){ canal = 3; volume = 25; this.ligada = ligada; } Embora os dois métodos tenham o mesmo nome, poderíamos utilizar ambos os na mesma classe se quisermos, porque um possui argumentos e o outro não. void ligar (){ canal = 3; volume = 25; ligada = true; } void ligar (boolean ligada){ canal = 3; www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 80 volume = 25; this.ligada = ligada; } Porém, o mesmo não pode ser aplicado aos atributos canal e volume. Porque não é possível criar um método que recebe um inteiro e criar um outro método com o mesmo nome que também recebe um inteiro, mesmo que estes dois inteiros sejam totalmente diferentes. Se visualizarmos como Java interpreta o método, veríamos: void ligar (int volume) = void ligar (int canal) void ligar (int) = void ligar (int) Por outro lado, é perfeitamente possível criarmos dois métodos que recebam um booleano e um inteiro, inclusive se forem os mesmos, mas em posições diferentes. Isso acontece porque Java não verifica o nome do parâmetro, mas apenas o tipo dele. void ligar (boolean ligada, int canal) ≠ void ligar (int canal, boolean ligada) void ligar (boolean, int) ≠ void ligar (int, boolean) Portanto, podemos fazer muitas combinações desde que essas combinações não sejam em números iguais, de tipos iguais e nas mesmas posições. Abaixo, está a classe com algumas combinações possíveis. É um bom costume sempre referenciar para o método que recebe mais argumentos. public class TV { int canal; int volume; boolean ligada; int tamanho; void ligar() { this.ligar(3, 25, true); } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 81 void ligar(boolean ligada) { this.ligar(3, 25, ligada); } void ligar(int canal, int volume) { this.ligar(canal, volume, true); } void ligar(int canal, int volume, boolean ligada) { this.canal = canal; this.volume = volume; this.ligada = ligada; } } 14. Acesso a Membros e Métodos Vimos, até agora, como criar uma classe, definir um método construtor, sobrecarregar métodos e instanciar objetos. Nesse momento, vamos ver como acessar seus membros e métodos. Os acessos a membros ou métodos de uma classe são dados a partir do objeto instanciado usando um separador que é o ponto (.). Portanto, para acessar qualquer membro da classe, basta que usemos o nome do objeto, mais um ponto e o nome do membro que queremos acessar. Ainda tomando como exemplo a classe TV já vista antes, vamos modificar dentro do programa dois atributos: os atributos canal e volume. public class TV { int canal; int volume; boolean ligada; int tamanho; www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 82 public TV(){ this.tamanho = 21; this.ligada = true; } public static void main (String args []){ TV minhaTV = new TV(); minhaTV.canal = 3; minhaTV.volume = 25; } } Como percebemos é construído um objeto chamado minhaTV da classe TV com o tamanho de 21" e já ligada. Durante a execução do programa modificamos diretamente seu canal e volume usando o objeto que instanciamos. Da mesma forma que acessamos um atributo, também podemos acessar um método. No exemplo abaixo, criaremos o método para aumentar volume da TV. public class TV { int canal; int volume; boolean ligada; int tamanho; public TV(){ this.tamanho = 21; this.ligada = true; this.canal = 3; this.volume = 25; } public void aumentarVolume(){ this.volume += 5; } public static void main (String args []){ www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 83 TV minhaTV = new TV(); minhaTV.aumentarVolume(); } } Aqui, o objeto minhaTV começa com volume 25 e depois de chamar seu método aumentarVolume() fica com 30. Algumas considerações que devemos ter é saber diferenciar funções de métodos. Apesar da essência de ambos ser a mesma coisa, funções são chamadas estaticamente, ou seja, ela pode ser chamada diretamente sem o intermédio de nenhum objeto. Já os métodos são chamados de dentro das classes, portanto, obrigatoriamente devemos ter um objeto instanciado para conseguirmos utilizar o método. Vejamos a diferença: public class TV { int canal; int volume; boolean ligada; int tamanho; public TV(){ this.tamanho = 21; this.ligada = false; this.canal = 0; this.volume = 0; } // método da classe public void ligar(boolean ligada){ this.ligada = ligada; } // função public static void estahLigada (TV objeto){ if (objeto.ligada) System.out.println ("está ligada"); www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 84 else System.out.println ("não está ligada"); } } public static void main (String args []){ TV televisao1 = new TV(); TV televisao2 = new TV(); // chamando o método ligar televisao1.ligar(true); televisao2.ligar(false); System.out.print ("A televisão 1 "); // chamando a função estahLigada estahLigada (televisao1); System.out.print ("A televisão 2 "); estahLigada (televisao2); } Observemos que chamamos o método ligar() de cada objeto, portanto, existem dois métodos ligar distintos - o método ligar() da televisao1 e o método ligar() da televisao2. A função é estática, portanto, existe apenas uma função estahLigada(). 15. Encapsulamento - public, private e protected Se outros programadores usam nossa classe, nós queremos garantir que erros pelo mau uso não ocorram. Encapsulamento serve para controlar o acesso aos atributos e métodos de uma classe. É uma forma eficiente de proteger os dados manipulados dentro da classe, além de determinar onde esta classe poderá ser manipulada. Usamos o nível de acesso mais restritivo que faça sentido para um membro particular. Sempre usamos private, a menos que tenhamos um bom motivo para deixá-lo com outro nível de acesso. Não devemos permitir o acesso público aos membros, exceto em caso de ser www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 85 constantes. Isso porque membros públicos tendem a nos ligar a uma implementação em particular e limita a nossa flexibilidade em mudar o código. Basicamente, usamos quatro tipos de encapsulamento que são divididos em dois níveis: • Nível de classe ou topo: Quando determinamos o acesso de uma classe inteira que pode ser public ou package-private (padrão); • Nível de membro: Quando determinamos o acesso de atributos ou métodos de uma classe que podem ser public, private, protected ou package-private (padrão). Para utilizarmos estes modificadores de acesso, basta que nós os digitemos antes do nome da variável, atributo, método, função ou classe, com exceção de package-private, que é entendido como padrão, portanto, é qualquer membro ou classe que não tenha modificador especificado. Exemplo: public class MinhaClasse { //classe public private int inteiro; //atributo inteiro private protected float decimal; //atributo float protected boolean ativado; //atributo booleano package-private } 15.1. Public O modificador public deixará visível a classe ou membro para todas as outras classes, subclasses e pacotes do projeto Java. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 86 15.2. Private O modificador private deixará visível o atributo apenas para a classe em que este atributo se encontra. 15.3. Protected O modificador protected deixará visível o atributo para todas as outras classes e subclasses que pertencem ao mesmo pacote. A principal diferença é que apenas as classes do mesmo pacote tem acesso ao membro. O pacote da subclasse não tem acesso ao membro. 15.4. Sem Modificador (Padrão) Por padrão, a linguagem Java permite acesso aos membros apenas ao pacote em que ele se encontra. De forma ilustrativa, abaixo está uma tabela demonstrando todas estas características. Modificador Classe Pacote Subclasse Globalmente Public sim sim sim sim Protected sim sim sim não Sem Modificador (Padrão) sim sim não não Private sim não não não Fonte: Controlling Access to Members of a Class www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 87 15.5. Métodos Acessores - Getters e Setters Como visto anteriormente, o encapsulamento "protege" os atributos ou métodos dentro de uma classe, portanto devemos prover meios para acessar tais membros quando eles são particulares, ou seja, quando possuem o modificador private. O que torna isso possível é a criação de métodos. Em programação orientada a objetos, esses métodos são chamados de métodos acessores ou getters e setters, pois eles provêm acesso aos atributos da classe, e geralmente, se iniciam com get ou set, daí a origem de seu nome. Na verdade, não há nada de diferente entre os métodos comuns e os métodos acessores. A única importância está no fato da orientação a objeto. Pois, sempre que formos acessar um membro em Java usaremos get ou set. 15.5.1. Set Nomeamos um método acessor com set toda vez que este método for modificar algum campo ou atributo de uma classe, ou seja, se não criarmos um método acessor set para algum atributo, isso quer dizer que este atributo não deve ser modificado. Portanto, como o valor de um atributo da classe será modificado, não é necessário que este método retorne nenhum valor, por isso, os métodos setters são void. Porém, obrigatoriamente, eles tem que receber um argumento que será o novo valor do campo. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 88 15.5.2. Get Nomeamos um método acessor com get toda vez que este método for verificar algum campo ou atributo de uma classe. Como este método irá verificar um valor, ele sempre terá um retorno como String, int, float, etc. Mas não terá nenhum argumento. 15.5.3. Is Nomeamos um método acessor com is toda vez que este método for verificar algum campo ou atributo de uma classe que tenha retorno do tipo boolean. Levando em consideração as informações acima, nossa classe de exemplo TV ficaria: public class TV { private int tamanho; private int canal; private int volume; private boolean ligada; public TV(int tamanho, int canal, int volume, boolean ligada) { this.tamanho = tamanho; this.canal = canal; this.volume = volume; this.ligada = ligada; } public int getTamanho() { return tamanho; } public void setTamanho(int tamanho) { this.tamanho = tamanho; } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 89 public int getCanal() { return canal; } public void setCanal(int canal) { this.canal = canal; } public int getVolume() { return volume; } public void setVolume(int volume) { this.volume = volume; } public boolean isLigada() { return ligada; } public void setLigada(boolean ligada) { this.ligada = ligada; } } 16. Herança Enquanto programamos em Java, há a necessidade de trabalharmos com várias classes. Muitas vezes, classes diferentes tem características comuns, então, ao invés de criarmos uma nova classe com todas essas características usamos as características de um objeto ou classe já existente. Ou seja, herança é, na verdade, uma classe derivada de outra classe. Para simplificar de uma forma mais direta, vejamos: www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 90 Vamos imaginar que exista uma classe chamada Eletrodoméstico, e nela estão definidos os seguintes atributos: ligado (boolean), voltagem (int) e consumo (int). Se levarmos em conta a classe TV que estamos usando de exemplo até agora, podemos dizer que TV deriva de Eletrodoméstico. Ou seja, a classe TV possui todas as características da classe Eletrodoméstico, além de ter suas próprias características. Extends e Super Para fazermos uma classe herdar as características de uma outra, usamos a palavra reservada extends logo após a definição do nome da classe. Dessa forma: class NomeDaClasseASerCriada extends NomeDaClasseASerHerdada Importante: Java permite que uma classe herde apenas as características de uma única classe, ou seja, não pode haver heranças múltiplas. Porém, é permitido heranças em cadeias, por exemplo: se a classe Mamifero herda a classe Animal, quando fizermos a classe Cachorro herdar a classe Mamifero, a classe Cachorro também herdará as características da classe Animal. Como estamos tratando de herança de classes, toda classe tem seu método construtor. Portanto, se estamos trabalhando com duas classes, temos dois métodos construtores. Para acessarmos o método construtor da classe que está sendo herdada usamos o super(). www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 91 Podemos usar o super para qualquer construtor da classe pai, pois o Java consegue diferenciar os construtores por causa da sobrecarga de métodos. Para finalizar, iremos mostrar o exemplo citado mais acima da classe Eletrodomestico e TV. Observe: Classe 1: Eletrodomestico package br.com.primebean; public class Eletrodomestico { private boolean ligado; private int voltagem; private int consumo; public Eletrodomestico(boolean ligado, int voltagem, int consumo) { this.ligado = ligado; this.voltagem = voltagem; this.consumo = consumo; } // (...) } Classe 2: TV package br.com.primebean; public class TV extends Eletrodomestico { private int private int private int public TV(int voltagem, int consumo, int canal, int volume, int tamanho) { super(false, voltagem, consumo); this.canal = canal; this.volume = volume; this.tamanho = tamanho; } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA //(...) } Classe que mostra a instanciação de TV. package br.com.primebean; public class ExemploHeranca { public static void mostrarCaracteristicas(TV obj) { System.out.print("Esta TV tem as seguintes características:\n" + "Tamanho: " + obj.getTamanho() + "\"\n" + "Voltagem Atual: "+ obj.getVoltagem() + "V\n" + "Consumo/h: " + obj.getConsumo() + "W\n"); if (obj.isLigado()) { System.out.println("Ligado: Sim\n" + "Canal: " + obj.getCanal() + "\n" + "Volume: " + obj.getVolume()+"\n"); } else { System.out.println("Ligado: Não\n"); } } public static void main(String args[]) { TV tv1 = new TV(110, 95, 0, 0, 21); TV tv2 = new TV(220, 127, 0, 0, 29); tv2.setLigado(true); tv2.setCanal(3); tv2.setVolume(25); mostrarCaracteristicas(tv1); mostrarCaracteristicas(tv2); } } O código acima irá mostrar o seguinte resultado: Esta TV tem as seguintes características: Tamanho: 21" www.primebean.com.br www.primebean.com.br/joeydecurcio 92 Introdução á Linguagem de Programação JAVA 93 Voltagem Atual: 110V Consumo/h: 95W Ligado: Não Esta TV tem as seguintes características: Tamanho: 29" Voltagem Atual: 220V Consumo/h: 127W Ligado: Sim Canal: 3 Volume: 25 17. Enum Java nos possibilita criar uma estrutura de dados enumarada. Essas estruturas de dados enumeradas são conjuntos de constantes organizados em ordem de declaração, ou seja, o que é declarado primeiro virá primeiro. A funcionalidade principal de enum é agrupar valores com o mesmo sentido dentro de uma única estrutura, como por exemplo, meses, dias da semana, cores, tabela periódica, etc. e também limitar ou determinar número de valores que podem ser usados na programação. Embora sua funcionalidade é totalmente diferente, a criação de uma estrutura enumerada é parecida com uma classe. Basta trocarmos a palavra-chave class pela palavra-chave enum. Mas, devemos levar em consideração alguns fatores: www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 94 1. Uma estrutura enum deve ter seu próprio arquivo da mesma forma que acontece com as classes públicas. Por exemplo, se nós implementarmos uma classe pública chamada HelloWorld, então, deve haver um arquivo chamado HelloWorld.java. Se criarmos um enumerador chamado Cores, então, deve haver um arquivo chamado Cores.java. 2. Estruturas enum não são instanciáveis. Ou seja, estruturas enum não possuem um método construtor, portanto, não há como usar o instanciador new. 3. Estruturas enum são apenas declaráveis. Portanto, toda a lista de constantes declaradas dentro desta estruturas são acessados estaticamente. Ou seja, nome da variável, mais ponto (.) e o nome da constante (Suposição: mes.JANEIRO). 4. Toda estrutura enum possui um método para acessar seus valores em forma de array (vetor) chamado values(). Abaixo está uma estrutura enum: public enum Cores { PRETO, BRANCO, PRATA; } Agora que temos nosso "kit de constantes" podemos usar em nossa classe. public class TV { private int tamanho; private int canal; private int volume; private boolean ligada; //declaração da variável do tipo Enum Cores private Cores cor; public TV(int tamanho, Cores cor) { this.tamanho = tamanho; this.canal = 0; www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 95 this.volume = 25; this.ligada = false; this.cor = cor; } public int getTamanho() { return tamanho; } public int getCanal() { return canal; } public int getVolume() { return volume; } public Cores getCor() { return cor; } public static void main(String args[]) { TV minhaTV = new TV(29, Cores.PRATA); /** * acessando estaticamente (diretamente) * o valor PRATA do enum Cores **/ System.out.println("Características da minha TV:" + "\nTamanho:" + minhaTV.getTamanho() + "\nCanal atual:" + minhaTV.getCanal() + "\nVolume atual:" + minhaTV.getVolume() + "\nCor: " + minhaTV.getCor()); } } Estruturas enum também podem ser determinadas. Dessa forma, podemos atribuir mais valores a mesma constante. Por exemplo, podemos fazer uma estrutura enum da tabela periódica com os símbolos químicos tendo todos os valores possíveis da tabela (Número Atômico, Peso Atômico e Nome do Elemento). Para fazer isso, no final da enumeração, temos que declarar as constantes que foram usadas, assim: www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 96 ... private final int numero; //constante para número atômico private final double peso; //constante para peso atômico private final String nome; //constante para nome do elemento ... O fator do encapsulamento usando private aqui será muito importante, pois dessa forma não haverá um meio de alterar o valor dessas constantes por acidente. Após isso, criamos métodos para acessar esses valores. ... private int numero(); private double peso(); private String nome(); ... Então, criamos a definição usada nas constantes. Essas definições se parecem muito com os construtores de classes, mas sua função é apenas indicar o que é cada uma das informações contidas em cada constante. ... NomeDoEnum (int numero, double peso, String nome){ this.numero = numero; this.peso = peso; this.nome = nome; ... Relembrando: Todas estas definições sempre devem vir após a definição das constantes. No exemplo abaixo, está esta estrutura com apenas três elementos químicos. public enum TabelaPeriodica { // Declaração das constantes H (1, 1.00794, "Hidrogênio"), HE (2, 4.002602, "Hélio"), O (8, 15.9994, "Oxigênio"); www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA /** * Por ser um exemplo, * não foram colocados * todos os elementos químicos * da Tabela Periódica **/ // Definição das constantes private final int numero; private final double massa; private final String nome; // métodos para acessar os valores private int numero() { return this.numero; } private double massa() { return this.massa; } private String nome() { return this.nome; } //método que define as constantes private TabelaPeriodica(int numero, double massa, String nome) { this.numero = numero; this.massa = massa; this.nome = nome; } public static void main(String args[]) { System.out.println("Dados do elemento químico H:"); System.out.println("\nNúmero: " + TabelaPeriodica.H.numero() + "\nMassa: " + TabelaPeriodica.H.massa() + "\nElemento: " + TabelaPeriodica.H.nome()); } } www.primebean.com.br www.primebean.com.br/joeydecurcio 97 Introdução á Linguagem de Programação JAVA 98 18. Interfaces Interface é um recurso da orientação a objeto utilizado em Java que define ações que devem ser obrigatoriamente executadas, mas que cada classe pode executar de forma diferente. Interfaces contém valores constantes ou assinaturas de métodos que devem ser implementados dentro de uma classe. E por que isso? Isso se deve ao fato que muitos objetos (classes) podem possuir a mesma ação (método), porém, podem executá-la de maneira diferente. Usando um exemplo bem drástico, podemos ter uma interface chamada aéreo que possui a assinatura do método voar(). Ou seja, toda classe que implementar aéreo deve dizer como voar(). Portanto, se eu tenho uma classe chamada pássaro e outra chamada avião, ambas implementando a interface aéreo, então, nestas duas classes devemos codificar a forma como cada um irá voar(). Uma interface é criada da mesma forma que uma classe, mas utilizando a palavra-chave interface no lugar de class. interface nomeDaInterface { métodoAbstrato (argumentos); } 18.1. Usando uma Interface em uma Classe Como vimos anteriormente, uma classe pode extender suas funcionalidades obtendo as características de outra classe num processo que chamamos de herança. Uma interface não é herdada, mas sim, implementada. Porque todo o código dos métodos da interface deve ser escrito dentro da classe que o chama. Dessa forma, obtemos as assinaturas dos métodos da interface em uma classe usando a palavra- chave implements. A vantagem principal das interfaces é que não há limites de quantas interfaces uma classe pode implementar. O que ajuda no caso de heranças múltiplas que não é possível www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 99 ser feito em Java, pois uma classe apenas pode herdar as características de uma outra classe. Trazendo ao exemplo já usado por nós, teríamos o seguinte conceito. 1) Teríamos a classe principal que caracteriza a TV. public class TV { private int tamanho; private int canal; private int volume; private boolean ligada; public TV(int tamanho) { this.tamanho = tamanho; this.canal = 0; this.volume = 0; this.ligada = false; } // abaixo teríamos todos os métodos construtores get e set... } 2) Teríamos as ações que comumente toda televisão executa, mas que cada modelo pode executar de forma diferente. Como geralmente toda ação da TV é executada pelo controle remoto, então chamaremos esta interface de controle remoto. public interface ControleRemoto { /* * Perceba que apenas a assinatura dos métodos estão aqui. * E cada método termina com um ponto-e-vírgula (;) */ void mudarCanal(int canal); void aumentarVolume (int taxa); void diminuirVolume (int taxa); boolean ligar(); boolean desligar(); } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 100 3) Agora que temos nossa interface e a definição do que é a TV, vamos desenvolver duas TVs diferentes, imaginando que fossem duas marcas completamente distintas e que uma não tem nenhuma relação com a outra. Como ambas as TVs irão implementar a interface ControleRemoto, então, no corpo das duas classes devem conter todos os métodos da interface. No exemplo usado abaixo, apenas implementaremos os métodos ligar e desligar. A TV modelo 001 é uma TV simples, sem muitos recursos que quando acionarmos o comando desligar irá simplesmente desligar. public class ModeloTV001 extends TV implements ControleRemoto { public final String MODELO = "TV001"; public ModeloTV001(int tamanho) { super(tamanho); } public void desligar() { super.setLigada(false); } public void ligar() { super.setLigada(true); } public void aumentarVolume(int taxa) { } public void diminuirVolume(int taxa) { } public void mudarCanal(int canal) { } } O modelo SDX é uma TV mais moderna, que quando acionarmos o comando desligar irá apresentar uma mensagem dizendo "tchau!". public class ModeloSDX extends TV implements ControleRemoto { public final String MODELO = "TV-SDX"; public ModeloSDX(int tamanho) { super(tamanho); www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 101 } public void desligar() { System.out.println("Tchau!"); super.setLigada(false); } public void ligar() { super.setLigada(true); } public void aumentarVolume(int taxa) { } public void diminuirVolume(int taxa) { } public void mudarCanal(int canal) { } } Como pode ser visto, ambos possuem a mesma ação que é desligar, porém cada um executa de forma diferente. public class ExemploInterfaceamento { public static void main(String[] args) { ModeloTV001 tv1 = new ModeloTV001(21); ModeloSDX tv2 = new ModeloSDX (42); tv1.ligar(); tv2.ligar(); System.out.print("TV1 - modelo " + tv1.MODELO + " está "); System.out.println(tv1.isLigada() ? "ligada" : "desligada"); System.out.print("TV2 - modelo " + tv2.MODELO + " está "); System.out.println(tv1.isLigada() ? "ligada" : "desligada"); } // ambas as TVs estão ligadas e vamos desligá-las System.out.println("Desligando modelo " + tv1.MODELO); tv1.desligar(); System.out.println("Desligando modelo " + tv2.MODELO); tv2.desligar(); } Se prestarmos atenção, apenas a TV2 mostrará uma mensagem quando for desligada. Para visualizar melhor este exemplo, baixe o código exemplo e implemente os www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 102 métodos que faltam. 19. Annotations Annotations, traduzindo, quer dizer anotações. Annotations dão informações sobre o código que está sendo escrito ou até mesmo do próprio programa, o que se assemelha aos comentários. Porém, annotations podem ser usados como objeto semântico de compiladores, ou seja, compiladores podem interpretar as annotations. Dessa forma é possível que compiladores entendam que, por exemplo, não é para mostrar mensagens de advertências (Warnings), ou usar as annotations para detectar erros de código, criar documentações usando XML, etc. Annotations podem possui elementos ou não. Seus elementos são sempre pair values, ou seja, elemento tem um nome e um valor. 19.1. Uso de Annotations As annotations são sempre precedidas de arroba (@). Por convenção, usamos annotations antes de um elemento qualquer, por exemplo, antes da criação de uma classe ou do uso de um método. Existem annotations com vários pair values (valores diferentes) que são separados por vírgula, que contenham apenas um valor ou simplesmente nenhum valor. Exemplo: @SuppressWarnings(value = "unchecked"). Quando uma annotation possui apenas um elemento chamado value, então, apenas é necessário atribuir seu valor sem declarar o nome value. Exemplo: @SuppressWarnings("unchecked"). Quando uma annotation não possui elementos, não é necessário usar os parênteses. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 103 Exemplo: @Override. Abaixo está uma lista com algumas das annotations mais utilizadas. • @Deprecated: Sempre que algum método tem seu uso desencorajado por ser perigoso ou por ter uma alternativa melhor desenvolvida, então, ele recebe a anotação @Deprecated. • @Override: Usado principalmente em casos de polimorfismo, sempre que formos sobrescrever um método da classe-pai (superclasse) devemos indicar ao compilador com @Override. Mas, devemos tomar cuidado ao utilizar @Override, pois se marcarmos o método e ele não sobrescrever nenhum método da classe-pai (superclasse), então, o compilador gerará uma mensagem erro. • @SuppressWarnings ("deprecation"): Todos os avisos da categoria "inadequado" são ignorados. • @SuppressWarnings ("unchecked"): Todos os avisos da categoria "não verificado" são ignorados. • @SuppressWarnings ({"unchecked", "deprecation"}): Todos os avisos de qualquer categoria são ignorados. 19.2. Criando uma Annotation Antes de criarmos uma annotation, primeiramente temos que nos ater ao fato de que annotations apenas podem ser criadas em projetos que são compatíveis com JDK 5.0. Annotations são criadas de forma muito parecida com interfaces, diferenciando pelo fato de antes da palavra-chave interface há um símbolo arroba (@), cada elemento se parece com a declaração de um método abstrato, a nomenclatura utilizada é a mesma utilizada para nomear Classes e cada annotation fica em um arquivo .java da mesma forma que uma classe, classe abstrata ou interface. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA public @interface MinhaAnnotation { String elemento1(); int elemento2(); } Podemos definir um valor padrão para um elemento utilizando a palavra-chave default. public @interface MinhaAnnotation { String elemento1() default "VALOR"; int elemento2() default 123; } Também podemos utilizar vetores para a definição de um elemento. public @interface MinhaAnnotation String elemento1(); //elemento de String float elemento2(); //elemento de ponto flutuante int elemento3() default 1; //elemento inteiro que vale 1 por padrão String[] elemento4(); // elemento vetor de Strings } Abaixo está um exemplo de como usar nossa própria annotation. public @interface DetalhesSoftware { String [] desenvolvedor (); String nomeProjeto (); String software (); float versao () default 1.0f; } Agora que temos nossa anotação, basta chamá-la. @DetalhesSoftware ( desenvolvedor = ("Desenvolvedor1", "Desenvolvedor2", "Desenvolvedor3"), nomeProjeto = "Java Resources Checker", www.primebean.com.br www.primebean.com.br/joeydecurcio 104 Introdução á Linguagem de Programação JAVA 105 software = "JRC", versao = 1.0f ) public class AlgumaClasse { //código da classe } 19.3. Adicionar Annotations ao Javadoc Para fazer com que nossas annotations fiquem registradas no Javadoc toda vez que ele for gerado, devemos importar o pacote java.lang.annotation.Documented e antes de criarmos nossa annotation usarmos @Documented. Vejamos o exemplo abaixo: import java.lang.annotation.Documented; @Documented public @interface DetalhesSoftware { String software (); String nomeProjeto (); float versao () default 1.0f; String [] desenvolvedor (); } 20. Classes Abstratas e Métodos Abstratos Classes abstratas tem uma função importante na orientação a objeto em Java. De forma objetiva, uma classe abstrata serve apenas como modelo para uma classe concreta (classe que comumente usamos). www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 106 Como classes abstratas são modelos de classes, então, não podem ser instanciadas diretamente com o new, elas sempre devem ser herdadas por classes concretas. Outro fato importante de classes abstratas é que elas podem conter ou não métodos abstratos, que tem a mesma definição da assinatura de método encontrada em interfaces. Ou seja, uma classe abstrata pode implementar ou não um método. Os métodos abstratos definidos em uma classe abstrata devem obrigatoriamente ser implementados em uma classe concreta. Mas se uma classe abstrata herdar outra classe abstrata, a classe que herda não precisa implementar os métodos abstratos. Para criarmos uma classe ou método abstrato usamos a palavra-chave abstract. Para demonstrar, usaremos uma classe abstrata chamada Eletrodomestico, que servirá de modelo para todos os objetos que possam ser eletrodomésticos. package classeabstrata; public abstract class Eletrodomestico { private boolean ligado; private int voltagem; // métodos abstratos // /* * não possuem corpo, da mesma forma que * as assinaturas de método de uma interface */ public abstract void ligar(); public abstract void desligar(); // método construtor // /* * Classes Abstratas também podem ter métodos construtores, * porém, não podem ser usados para instanciar um objeto diretamente */ public Eletrodomestico(boolean ligado, int voltagem) { this.ligado = ligado; this.voltagem = voltagem; } // métodos concretos www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 107 /* * Uma classe abstrata pode possuir métodos não abstratos */ public void setVoltagem(int voltagem) { this.voltagem = voltagem; } public int getVoltagem() { return this.voltagem; } public void setLigado(boolean ligado) { this.ligado = ligado; } public boolean isLigado() { return ligado; } } Como podemos observar, criamos um modelo de classe que compreende a uma gama enorme de outros objetos. Agora, qualquer objeto que derivar desse modelo deve ter sua voltagem especificada e dizer se está ligado ou não. Então, vamos criar outras duas classes que herdam as características da classe abstrata (modelo). A primeira é a classe TV: package classeabstrata; public class TV extends Eletrodomestico { private int tamanho; private int canal; private int volume; public TV(int tamanho, int voltagem) { super (false, voltagem); // construtor classe abstrata www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA this.tamanho = tamanho; this.canal = 0; } /* implementação dos métodos abstratos */ public void desligar() { super.setLigado(false); setCanal(0); setVolume(0); } public void ligar() { super.setLigado(true); setCanal(3); setVolume(25); } //abaixo teríamos todos os métodos construtores get e set... } E essa é a classe Radio. package classeabstrata; public class Radio extends Eletrodomestico { public static final short AM = 1; public static final short FM = 2; private int banda; private float sintonia; private int volume; public Radio(int voltagem) { super(false, voltagem); setBanda(Radio.FM); setSintonia(0); setVolume(0); } /* implementação dos métodos abstratos */ public void desligar() { super.setLigado(false); www.primebean.com.br www.primebean.com.br/joeydecurcio 108 Introdução á Linguagem de Programação JAVA 109 setSintonia(0); setVolume(0); } public void ligar() { super.setLigado(true); setSintonia(88.1f); setVolume(25); } // abaixo teríamos todos os métodos construtores get e set... } Pronto, como podemos ver, temos duas classes totalmente diferentes que tem como base o mesmo modelo. Também é perceptível o fato de que em ambas as classes, os métodos abstratos ligar() e desligar() foram implementados, porém, não há a implementação dos outros métodos como setVoltagem() ou isLigado(). As classes abstratas servem de base para codificação de uma classe inteira, diferentemente das interfaces que são apenas assinaturas dos métodos. Sumarizando, quando temos que definir variáveis, constantes, regras, e pequenas ações definidas devemos usar classes abstratas. Mas, se formos apenas criar a forma como objetos devem realizar determinadas ações (métodos) devemos optar por interfaces. A boa combinação de heranças e implementações de classes abstratas e interfaces proporciona uma forma robusta de criação de softwares e uma ótima alternativa para heranças múltiplas comumente usadas em C++. Abaixo está uma classe que testa a funcionalidade dessas classes. package classeAbstrata; public class Main { public static void main(String[] args) { TV tv1 = new TV(29, 110); www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 110 Radio radio1 = new Radio(110); /* * chamando os métodos abstratos implementados * dentro de cada classe (TV e Radio) */ tv1.ligar(); radio1.ligar(); System.out.print("Neste momento a TV está "); System.out.println(tv1.isLigado() ? "ligada" : "desligada"); System.out.print("e o Rádio está "); System.out.println(radio1.isLigado() ? "ligado." : "desligado."); } } } 21. Polimorfismo Polimorfismo, que vem do grego "muitas formas". É o termo definido em linguagens orientadas a objeto - como o Java - para a possibilidade de se usar o mesmo elemento de forma diferente. Especificamente em Java, polimorfismo se encontra no fato de podemos modificar totalmente o código de um método herdado de uma classe diferente, ou seja, sobrescrevemos o método da classe pai. Portanto, polimorfismo está intimamente ligado a herança de classes. Um pequeno exemplo para simplificar essa característica segue abaixo: a. Classe 1 possui 2 métodos: métodoA() e métodoB(). b. Classe 2 herda a classe 1. c. Classe 2 reescreve todo o métodoA() que pertence a classe 1. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 111 Levando isso a um patamar mais prático. Sabemos que toda classe em Java herda implicitamente a classe Object. A classe Object possui alguns métodos, dentre eles o método toString(). O método toString() original, descreve qual instância de objeto está sendo utilizada. Resumidamente, ele cria um texto com o nome da classe mais um código hexadecimal que cada instância possui diferente de outra, chamado hash code (é como um RG daquela instância). Então, se tivéssemos a classe TV dentro do pacote primebean e usássemos o comando: System.out.println (tv1.toString()). O que apareceria no console seria algo como: primebean.TV@c17124. Então o que faremos para melhorar será usar o polimorfismo para sobrescrever o método toString(), colocando o texto da forma que desejarmos. package primebean; public class TV { private String marca; private String modelo; private int tamanho; private int canal; private int volume; private boolean ligada; public TV(String marca, String modelo, int tamanho) { this.marca = marca; this.modelo = modelo; this.tamanho = tamanho; this.canal = 1; this.volume = 0; this.ligada = false; } // métodos getters e setters public String toString() { return "TV" + "\nMarca: " + this.marca + www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 112 "\nModelo: " + this.modelo + "\nTamanho: " + this.tamanho; } public static void main(String args[]) { TV tv1 = new TV("Marca1", "SDX-22", 29); System.out.println(tv1.toString()); } } Agora, o resultado da linha System.out.println (tv1.toString()) não será mais: primebean.TV@c17124 Agora, será: TV Marca: Marca1 Modelo: SDX-22 Tamanho: 29 É possível que dependendo do seu JRE e compilador seja necessário o uso da annotation @override antes de sobrescrever o método toString(); 22. Typecast - Casting Quando lidamos com linguagens de programação fortemente tipadas como Java, nos confrontamos muitas vezes com a necessidade de variar de um tipo de dado para outro. Há casos, também, em que até mesmo o compilador não compreende que tipo de dado estamos atribuindo a uma variável. Em Java, nós podemos fazer uso do que chamamos de indução de tipo, typecast ou ate mesmo casting. O typecast dita ao compilador como tal dado deve ser interpretado www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 113 e manipulado. Essa indução de tipo ou typecast pode ser implícita ou explícita. O typecast implícito é feito automaticamente pelo compilador quando um tipo de dado pode ser facilmente manipulado no lugar de outro tipo de dado. O typecast explícito é feito diretamente no algorítmo para indicar ao compilador qual a forma de interpretação de um dado quando ele entende que há ambiguidade ou formatos incompatíveis. O typecast explícito é dado sempre dentro de parênteses que sempre vem antes do dado a ser induzido. Ex.: (int) var1, (float) var2, (Object) var3, … 22.1. Typecast de Dados Primitivos O typecast de dados primitivos é dado basicamente em questão de seu consumo de memória. Se tentamos designar um tipo de dado que consome menos memória para um que consome mais memória, o typecast é realizado implicitamente. No exemplo abaixo, atribuímos um dado inteiro (varInt) a uma variável do tipo float (varFloat). public class ExemploTypecast1 { public static void main(String[] args) { float varFloat; int varInt; varInt = 200; varFloat = varInt; System.out.println(varFloat); } } O contrário não se aplica. Tentar atribuir um tipo de dado maior para um tipo de dado menor irá resultar em um erro de tipos incompatíveis (type mismatch). Para demonstrar isso, usaremos dois tipos de dados inteiros. Porém, iremos atribuir um inteiro longo (que consome mais memória) a um dado inteiro que consome menos. Nesse caso, www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 114 somos obrigados a usar typecast explícito. public class ExemploTypecast2 { public static void main(String[] args) { long varLong; int varInt; varLong = 200; varInt = (int) varLong; System.out.println(varInt); } } 22.2. Typecast de Classes e Objetos Typecast também pode ser usado em Classes e Objetos. Sempre e uma classe for genérica, ela poderá receber qualquer tipo de objeto que será feito o typecast implicitamente. Por exemplo, vamos utilizar a classe TV que vinhamos criando até agora. package primebean; public class TV { int tamanho; int canal; int volume; boolean ligada; public TV(int tamanho, int canal, int volume, boolean ligada) { this.tamanho = tamanho; this.canal = canal; this.volume = volume; this.ligada = ligada; } } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 115 Agora, vamos instanciar uma variável da classe genérica Object com a classe TV. package primebean; public class ExemploTypecast3 { public static void main(String[] args) { Object obj = new TV(29, 1, 0, false); System.out.println("A variável obj é " + obj.getClass()); } } Como podemos perceber, o resultado de getClass da variável obj não é sua classe original (Object), mas sua instância: class primebean.TV. Agora, não será possível criar uma cópia desse objeto para uma variável do mesmo tipo de sua instância. Neste caso, devemos fazer o typecast explícito da classe. package primebean; public class ExemploTypecast4 { public static void main(String[] args) { Object obj = new TV(29, 1, 0, false); TV tv = (TV) obj; TV tv2 = new TV(29, 1, 0, false); System.out.println("A variável tv é cópia de obj" + "\nobj: " + obj.toString() + "\ntv: " + tv.toString()); System.out.println("TV2 é outro objeto: " + tv2.toString()); } } O resultado do código acima seria algo como: A variável tv é cópia de obj obj: primebean.TV@12345f www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 116 tv: primebean.TV@12345f TV2 é outro objeto: primebean.TV@abcde1 23. Instanceof No exemplo anterior, se tentássemos atribuir obj diretamente a tv ocorreria um erro de tipos incompatíveis (type mismatch). Quando lidamos com classes, podemos testar qual seu tipo de instancia usando o operador instanceof. Instanceof indica se um objeto (já instanciado) pertence a uma classe. O uso de instanceof é: objeto instanceof nomeDaClasse. Para melhorar o exemplo anterior, usaremos instanceof antes de atribuirmos obj a tv. package primebean; public class ExemploTypecast { public static void main(String[] args) { Object obj = new TV(29, 1, 0, false); TV tv = null; if (obj instanceof TV) { tv = (TV) obj; } TV tv2 = new TV(29, 1, 0, false); System.out.println("A variável tv é cópia de obj" + "\nobj: " + obj.toString() + "\ntv: " + tv.toString()); System.out.println("TV2 é outro objeto: " + tv2.toString()); } } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 117 24. Generics No artigo anterior de Java, vimos como usar typecast e instanceof. Aqui, veremos uma pequena introdução de Generics ou programação genérica, na qual será muito importante quando formos tratar de classes e interfaces de coleção como, por exemplo, a classe Vector. Generics, ou programação genérica, serve para determinar para o compilador, qual tipo de classe deve ser interpretada. Por exemplo, vamos imaginar que será criada uma classe chamada Aparelho que irá conter um objeto de alguma outra classe. Para que essa classe possa aceitar qualquer tipo de classe, devemos fazer uso de generics. Generics é indicado como um identificador entre os sinais de maior e menor (<>). 24.1.Criando classes usando generics Para criar uma classe usando generics, basta que logo após o nome da classe coloquemos o indicador genérico. Esse indicador genérico é simplesmente uma letra na qual será substituída dentro da classe no momento da execução. package primebean; public class Aparelho <T> { T objeto; public Aparelho(T objeto) { this.objeto = objeto; } public T getObjeto() { www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 118 return objeto; } public void setObjeto(T objeto) { this.objeto = objeto; } } Como a letra T identifica um tipo genérico, ela será substituída por qualquer classe. Vamos imaginar agora que temos duas classes distintas. A classe TV: package primebean; public class TV { int tamanho; int canal; int volume; boolean ligada; public TV(int tamanho, int canal, int volume, boolean ligada) { this.tamanho = tamanho; this.canal = canal; this.volume = volume; this.ligada = ligada; } //métodos get e set } E a classe Radio: package primebean; public class Radio { public static int AM = 1; public static int FM = 2; private float frequencia; private int volume; www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 119 private int banda; public Radio(float frequencia, int volume, int banda) { this.frequencia = frequencia; this.volume = volume; this.banda = banda; } // métodos get e set } 24.2. Instanciar uma classe genérica Se fossemos criar um programa que usa as duas classes de aparelhos acima, faríamos: package primebean; public class MinhaClasse { public static void main(String[] args) { Aparelho<TV> aparelho1 = new Aparelho<TV>(new TV(29, 0, 0, false)); Aparelho<Radio> aparelho2 = new Aparelho<Radio>(new Radio(88.1f, 0, Radio.FM)); System.out.println(aparelho1.getObjeto().getClass()); System.out.println(aparelho2.getObjeto().getClass()); } } Perceba o seguinte: sem o uso de generics, o compilador não conseguiria saber qual a diferença entre aparelho1 e aparelho2, pois ele os trataria da mesma forma. Nesse caso, seria obrigatório o uso de typecast para determinar ao compilador que dado está sendo processado. Se pensarmos em uma aplicação muito grande, além de ficar cansativo ter que www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 120 usar typecast toda vez que fossemos usar um aparelho, seria muito provável que erraríamos em algum momento. Java usa uma pequena convenção de nomenclatura para as letras de identificação de generics (que são vastamente utilizadas no Framework de coleções Java), sendo: • E - Elemento • K - Chave • N - Número • T - Tipo • V - Valor Generics é um assunto bastante extenso com vários tópicos que podem ser abordados, dentre os quais podemos citar: • Multiplos tipos genéricos. Ex.: <T, E, N>; • Tipos genéricos limitados. Ex.: <U extends Number>; • Wildcards; • e Subtipos; O intuito desta apostila é apenas introduzir um conceito geral de programação genérica (generics) para compreensão de classes e métodos que utilizam generics. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 121 25. Exceções As exceções são, na verdade, instâncias de classes. E como qualquer classe ou objeto, podemos facilmente manipular. Existem métodos comuns entre todas as classes de Exceções, dentre as quais podemos citar: • toString(): Converte os dados da exceção para String para visualização. • printStackTrace(): Imprime na saída de erro padrão (geralmente console) todos os frames de onde foram detectados erros. Útil para depuração no desenvolvimento, pois mostra todo o histórico do erro, além das linhas onde foram ocasionados. • getCause(): Retorna a causa da Exceção, ou null se a causa for desconhecida ou não existir. • getMessage(): Retorna uma string com o erro. É uma forma simples e elegante de mostrar a exceção causada, geralmente, utilizada como forma de apresentação ao usuário. 25.1. Try e Catch Umas das utilidades proporcionadas pela orientação a objetos de Java é a facilidade em tratar possíveis erros de execução chamados de exceções. Sempre que um método de alguma classe é passível de causar algum erro, então, podemos usar o método de tentativa - o try. Tudo que estiver dentro do bloco try será executado até que alguma exceção seja lançada, ou seja, até que algo dê errado. Quando uma exceção é lançada, ela sempre deve ser capturada. O trabalho de captura da exceção é executado pelo bloco catch. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 122 Um bloco try pode possuir vários blocos de catch, dependendo do número de exceções que podem ser lançadas por uma classe ou método. O bloco catch obtém o erro criando uma instância da exceção. Portanto, a sintaxe do bloco try catch é: try { // código a ser executado } catch (ClasseDeExceção instânciaDaExceção) { // tratamento da exceção } 25.2. Finally Finally é o trecho de código final. A função básica de finally é sempre executar seu bloco de dados mesmo que uma exceção seja lançada. É muito útil para liberar recursos do sistema quando utilizamos, por exemplo, conexões de banco de dados e abertura de buffer para leitura ou escrita de arquivos. Finally virá após os blocos de catch. try { // código a ser executado } catch (ClasseDeExceção instânciaDaExceção) { // tratamento da exceção } finally { // código a ser executado mesmo que uma exceção seja lançada } Abaixo está um exemplo de tratamento de erro ou exceção. Tentaremos atribuir uma string de letras a um objeto inteiro. Como não é possível atribuir uma string de letras a um objeto inteiro, uma exceção de formato de número é lançada. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 123 public class ExemploDeExcecao { public static void main(String[] args) { String var = "ABC"; try { Integer i = new Integer(var); System.out.println("A variável i vale " + i); } catch (NumberFormatException nfe) { System.out.println("Não é possível atribuir a string " + var + " a um Objeto Inteiro.\n" + "A seguinte mensagem foi retornada:\n\n" + nfe.getMessage()); } } } O código acima apresentará algo como: Não é possível atribuir a string ABC a um Objeto Inteiro. A seguinte mensagem foi retornada: For input string: "ABC" Perceba que a linha System.out.println("A variável i vale " + i) não foi executada, pois houve um erro na linha anterior. Portanto, apenas a mensagem de tratamento do erro NumberFormatException foi impressa na tela. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 124 26. Classes Numéricas Estamos seguindo para, em breve, entrarmos nos tutoriais de programação usando SWING e AWT, resumidamente, janelas. Mas antes, veremos classes que se tornarão de extrema importância para o uso da manipulação dos dados. Essas classes são as que tem por base a classe abstrata Numbers e a classe String. Em Java, além de podermos utilizar os tipos primitivos de dados, também podemos usufruir de classes completas para o tratamento desses tipos primitivos. Isso é uma grande vantagem quando métodos necessitam ou retornam objetos ao invés de tipos primitivos (o que é muito comum com os objetos do pacote SWING e AWT). Outra vantagem dessas classes é que o próprio compilador é capaz de extrair os dados do objeto implicitamente e manipular seus dados como sendo simples dados primitivos, num processo descrito como box e unbox (encaixotar e desencaixotar). Por exemplo, se quisermos somar dois inteiros que estão dentro de dois objetos inteiros, não precisaríamos fazer nada de especial, a não ser somá-los de fato, como se fossem dados primitivos. Veja: public class SomarIntegers { public static void main(String[] args) { Integer var1 = 25; Integer var2 = 75; int resultado = var1 + var2; // somando dois objetos System.out.println(resultado); } } A princípio, a classe abstrata Number nos proporciona um conjunto de métodos que, logicamente, são possíveis acessar de qualquer classe numérica. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 125 26.1. Obtendo Tipo Primitivo de um Objeto Numérico Podemos utilizar os métodos *Value para obter um tipo primitivo de qualquer objeto numérico. • byteValue(): Obtém um valor primitivo byte. • shortValue(): Obtém um valor primitivo short (inteiro curto). • intValue(): Obtém um valor primitivo int (inteiro). • longValue(): Obtém um valor primitivo long (inteiro longo). • floatValue(): Obtém um valor primitivo float. • doubleValue(): Obtém um valor primitivo double. Esses métodos são ótimos para passar de um tipo de dado para o outro sem nos preocuparmos com indução de tipo ou typecasting, pois a mudança é feita diretamente pelo objeto. public class ConverterNumeros { public static void main(String[] args) { Byte meuByte = 5; Integer meuInt = 12345; Double meuDouble = 1234567.89; byte doubleParaByte = meuDouble.byteValue(); int byteParaInteiro = meuByte.intValue(); double inteiroParaDouble = meuInt.doubleValue(); System.out.println("Byte: " + meuByte + " - para int: " + byteParaInteiro + "\nInteger: " + meuInt + " - para double: " + inteiroParaDouble + "\nDouble: " + meuDouble + " - para byte: " + doubleParaByte); } } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 126 26.2. Comparando Números Para comparação de números, há dois métodos: compareTo() e equals(). O método compareTo() compara o objeto com um outro objeto da mesma classe ou número de tipo primitivo do mesmo tipo. Ele retorna 0 se o número comparado for igual, -1 se o número for menor ou 1 se o número for maior. Equals() funciona de forma semelhante. Ele indica se o número comparado é igual ao argumento deste método, porém não diz se o argumento é maior ou menor que o valor do objeto. Outra diferença fica por conta de seu retorno que é um valor booleano (true ou false). 26.7. Classes Integer, Float, Short, Byte, Long e Double Agora que temos a base de todas as classes numéricas, iremos para a descrição dos métodos contidos nessas classes, que apesar de diferentes, mantem uma similaridade muito grande. 26.7.1. Análise de Dados A análise de dados consiste em tentar usar uma String que possa ser interpretada como tal objeto numérico usando o comando parse*. Caso a String não possa ser interpretada como um número, uma exceção (erro) é lançada. • Byte.parseByte(): analisa uma String para tenta atribuir um dado do tipo primitivo byte. • Short.parseShort(): analisa uma String para tenta atribuir um dado do tipo primitivo short. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 127 • Integer.parseInt(): analisa uma String para tenta atribuir um dado do tipo primitivo inteiro. • Long.parseLong(): analisa uma String para tenta atribuir um dado do tipo inteiro primitivo longo. • Float.parseFloat(): analisa uma String para tenta atribuir um dado do tipo primitivo float. • Double.parseDouble(): analisa uma String para tenta atribuir um dado do tipo primitivo double. Se quisermos que, ao invés de um tipo primitivo de número, seja retornado um objeto, podemos trocar qualquer parse* por valueOf(). Em tipos inteiros, além de valueOf(), também podemos trocar parseInt, parseByte, parseShort e parseLong por decode(). Importante: As classes que se baseiam em números inteiros (Byte, Short, Long e Integer) possuem um segundo argumento do tipo inteiro opcional nos métodos parse* que indica a base do número inteiro, fazendo com que dessa forma possa ser interpretado números Decimais (base 10), Binários (base 2), Octais (base 8) e Hexadecimais (base 16). Decode também pode fazer este tipo de interpretação, mas não é necessário um segundo argumento desde que a String respeite algumas convenções: • Não são aceitos espaços; • Não são aceitos números negativos; • Números octais devem começar com um 0 (ex.: "0377", "0400", "0401"); • Números hexadecimais devem começar com 0x, 0X ou # (ex.: "0xFF", "0X100", "#101"). public class ParseEDecode { public static void main(String[] args) { String numero = "256"; www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 128 // retorna um dado do tipo int (inteiro) int tipoInteiro = Integer.parseInt(numero); // retorna um objeto da classe Integer (inteiro) Integer objetoInteiro = Integer.decode(numero); System.out.println("tipoInteiro: " + tipoInteiro + "\nobjetoInteiro: " + objetoInteiro); } } 26.7.2. Conversão Para String Para converter qualquer objeto numérico para uma String podemos fazer uso de toString() como qualquer outra classe. 26.8. Classe Math Vimos anteriormente como tratar números de vários tipos. Veremos agora, como aplicar conceitos matemáticos mais complexos a nossos processamentos usando a classe Math do pacote Java.lang. A classe Math nos proporciona uma série de operações e constantes matemáticas que são facilmente acessadas estaticamente, ou seja, não precisamos instanciar um objeto para podermos usar seus métodos. Dentro desta classe encontramos vários métodos e categorizamos os mais utilizados da seguinte forma: www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 129 • Máximo e Mínimo; • Potências e Raízes; • Logaritmo; • Arredondamentos e Valores Absolutos; • Trigonometria; • Números Randômicos. 26.8.1. Constantes A classe Math possui duas constantes que são o Π (pi) e E (base de logaritmos naturais ou neperianos) cada uma com o valor de 3,141592653589793 2.718281828459045, respectivamente. Abaixo está um exemplo simples com o cálculo do comprimento do círculo: public class ComprimentoCirculo { public static void main(String[] args) { float raio = 2.4f; double comprimento = 2 * raio * Math.PI; System.out.println(comprimento); } } www.primebean.com.br www.primebean.com.br/joeydecurcio e Introdução á Linguagem de Programação JAVA 130 26.8.2. Máximo e Mínimo Como o título já sugere, a classe Math de Java possui dois métodos que retornam o maior e o menor valor de seus argumentos. Esses métodos são max() e min(). public class MenorMaior { public static void main(String[] args) { float precoProdutoA[] = { 11.2f, 15.12f }; float precoProdutoB[] = { 19.7f, 20 }; System.out.println("O maior preço do produto A é " + Math.max(precoProdutoA[0], precoProdutoA[1])); System.out.println("O menor preço do produto B é " + Math.min(precoProdutoB[0], precoProdutoB[1])); } } 26.8.3. Potências e raízes Podemos fazer cálculos de potência e raízes com facilidade usando os métodos disponíveis em Math. • pow (base, expoente) - calcula a potência da base elevada ao expoente. • sqrt (número) - calcula a raíz quadrada de um número • cbrt (número) - calcula a raiz cúbica de um número • exp (expoente) - calcula o valor da constante de Euler (E) elevado ao expoente public class PotenciasRaizes { public static void main(String[] args) { www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 131 System.out.println("1 MB tem " + Math.pow(2, 10) + " KB"); System.out.println("A raiz quadrada de 121 é " + Math.sqrt(121) + " e a raiz cúbica de 1331 também é " + Math.cbrt(1331)); } } 26.8.4. Logaritmo Na classe Math encontramos funções para cálculo de logaritmo natual, na base de 10 e a soma do número mais 1. Tais métodos são: • log (número) - logaritmo natural de um número. • log10 (número) - logaritmo natural de um número na base 10 • log1p (número) - logaritmo natual de um número somado a 1. Esse método retorna um resultado mais confiável se o número em questão for muito próximo a 0 ou um número fracionado. Ou seja, o resultado não é o mesmo entre os métodos log1p (0.1f) e log (1+0.1f). public class Exemplo { public static void main(String[] args) { float nr = 0.1f; System.out.println("Resultado 1: " + Math.log(nr+1)); System.out.println("Resultado 2: " + Math.log1p(nr)); } } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 132 26.8.5. Arredondamentos e Valores Absolutos Existem algumas formas de arredondar um número fracionado (float e double) transformando-o em um número inteiro e também como obter o valor absoluto de qualquer número. • abs (número) - retorna o valor absoluto do mesmo tipo do parâmetro (ex.: inteiro retorna int positivo, decimal retorna float positivo, etc) • ceil (decimal) - este método retorna o valor decimal do parâmetro sem a parte fracionada. Ex.: 2.1 será 2, 6.0 será 6, 10.8 será 10... • floor (decimal) - este método retorna o primeiro inteiro após o valor decimal. Ex.: 2.1 será 3, 6.0 será 6, 10.8 será 11... • rint (decimal) - retorna um valor double mais próximo do valor do parâmetro. • round (decimal) - retorna o arredondamento aritmético do número decimal passado como parâmetro public class Exemplo { public static void main(String[] args) { float nr = -5.75f; System.out.println("Absoluto: " + Math.abs(nr) + "\nInteiro mais baixo: " + Math.ceil(nr) + "\nInteiro mais alto: " + Math.floor(nr) + "\nDouble mais próximo: " + Math.rint(nr) + "\nArredondamento: " + Math.round(nr)); } } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 133 26.8.6. Trigonometria A maior parte dos métodos encontrados na classe Math são trigonométricas, o que ajuda muito em cálculos mais complexos que envolvem figuras. • sin (graus) - este método retorna o valor do seno de acordo com o número de graus passado como parâmetro. • cos (graus) - este método retorna o valor do coseno de acordo com o número de graus passado como parâmetro. • tan (graus) - este método retorna o valor da tangente de acordo com o número de graus passado como parâmetro. • asin (graus) - este método retorna o valor do arco seno de acordo com o número de graus passado como parâmetro. • acos (graus) - este método retorna o valor do arco coseno de acordo com o número de graus passado como parâmetro. • atan (graus) - este método retorna o valor do arco tangente de acordo com o número de graus passado como parâmetro. • sinh (graus) - este método retorna o valor hiperbólico do seno de acordo com o número de graus passado como parâmetro. • cosh (graus) - este método retorna o valor hiperbólico do coseno de acordo com o número de graus passado como parâmetro. • tanh (graus) - este método retorna o valor hiperbólico da tangente de acordo com o número de graus passado como parâmetro. • hypot (x , y) - retorna o valor da hipotenusa, ou, basicamente, a distância entre dois pontos fundamentada na fórmula √x2+y2 » [sqrt (pow(x, 2) + pow(y,2))]. • toRadians (graus) - retorna um valor aproximado de radianos de acordo com o www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 134 ângulomedido em graus. • toDegrees (raio) - retorna um valor aproximado de graus de acordo com o ângulo medido em raios. public class Hipotenusa { public static void main(String[] args) { double ponto1 = 30; double ponto2 = 40; System.out.println("A distancia entre o " + ponto1 + " e o " + ponto2 + " é " + Math.hypot(ponto1, ponto2)); } } 26.8.7. Números Randômicos Os números randômicos são obtidos usando o método random(). O método random() retorna um valor double em 0.0 e 1.0. Para conseguirmos um valor limite ou um alcance (comumente chamado de range) delimitado, devemos fazer pequenas operações matemáticas. Essas operações são simples e podem ser resumidas da seguinte maneira. • O limite inferior, ou valor inicial (start value) será sempre somado ao número randômico. • O limite superior, ou alcance (range) será sempre o limite superior subtraído o limite inferior e depois multiplicado ao número randômico. Por exemplo, se quisermos que um número randômico sempre fique entre 5 e 10, procederíamos da seguinte maneira: • O menor número possível é 5, portanto ele será nosso start value ou limite inferior. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 135 O maior número possível é 10, então 10 será nosso limite superior. • Como temos ambos os limites (inferior e superior) devemos criar um alcance (range). Para obtermos isso, subtrairemos o limite superior com o limite inferior (10-5=5). public class Exemplo { public static void main(String[] args) { int limiteInferior = 5; int limiteSuperior = 10; int alcance = limiteSuperior - limiteInferior; double nrRandomico = Math.random(); System.out.println("O número randômico escolhido entre 5 e 10 foi " + Math.round(limiteInferior + nrRandomico * alcance)); } } 27. String Strings são utilizadas frequentemente em várias linguagens de programação, não apenas Java. Embora Strings sejam uma sequência de caracteres em Java, e não um array de caracteres. Em Java, o importante é entender que string não é um tipo de dado, mas sim uma classe. E suas variáveis são, na verdade, objetos dessa classe. Em síntese, tanto um array de caracteres como uma string se apresentam da mesma forma. Então, qual a vantagem de se usar uma classe e não um array de tipo primitivo? A resposta se baseia exatamente no uso da orientação a objetos e no fato de que existem muitos métodos que podemos utilizar em um objeto instanciado da classe String, mesmo sendo os objetos desta classe imutáveis, ou seja, uma vez instanciados não podemos mudar o que está guardado dentro do objeto String. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 136 Dentre as possibilidades oferecidas pela classe String podemos destacar algumas como: • Concatenação; • Tamanho da String; • Converter para maiúsculas ou minúsculas; • Fazer comparações que incluem verificações no início e no fim; • Extrair um carácter específico da string; • Achar um índice da string, inclusive recursivamente (de trás para frente); • Substituir uma parte da string ou ela completamente; • Verificar se uma string contém outra; • Dividir uma string em array ou vetor; • Obter uma porção da string inteira, o que chamamos de substring. Objetos Strings podem ser instanciadas usando um array de caracteres ou bytes com o operador new. Ou por meio de uma string literal. String literal é qualquer sequência de caracteres que estiver entre aspas ("). public class ExemploCriarString { public static void main(String[] args) { char[] charArray = { 'T', 'I', ' ', 'E', 'x', 'p', 'e', 'r', 't'}; /* construindo uma string a partir de um array de char */ String string1 = new String(charArray); /* construindo uma string a partir de uma string literal */ String string2 = "www.primebean.com.br"; System.out.println(string1); System.out.println(string2); } } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 137 27.1. Concatenação de Strings Concatenação nada mais é do que juntar strings numa só. Isto pode ser feito de duas formas: A primeira utilizando o método concat() da classe String ou usando o sinal de adição (+) como operador de concatenação. O método concat() retorna uma nova string formada da junção da string principal com a string indicada como parâmetro. De uma forma mais simples, podemos usar o + para juntar várias strings ao mesmo tempo. 27.2. Tamanho da string - length() A classe String possui um método acessor que retorna o tamanho da String. Esse método é length(). public class TamanhoString { public static void main(String[] args) { String str = "primebean"; System.out.println(str + " possui " + str.length() + " caracteres."); } } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 138 24.3. Letras Maiúsculas e Minúsculas Podemos facilmente deixar todas as letras de uma sequência de caracteres maiúscula ou minúscula usando os métodos toUpperCase() e toLowerCase() respectivamente. public class StringMaiusculoMinusculo { public static void main(String[] args) { String email = "[email protected]"; String hexadecimal = "#aa33ff"; System.out.println(email.toLowerCase()); System.out.println(hexadecimal.toUpperCase()); } } 24.4. Comparação Há várias formas de se fazer comparações com uma string, mas vale sempre lembrar que Java é case sensitive - diferencia letras maiúscula de minúsculas e vice-versa. Embora haja métodos próprios para comparações em que não há importância em diferenciar letras maiúsculas e minúsculas. A comparação mais simples é usando o próprio operador de igualdade (==), mas por se tratar de um objeto é preferível que se use o método específico chamado equals(). O método equals() compara o objeto string com outro objeto, se ambos possuírem conteúdos iguais, então, é retornado verdadeiro (true), caso contrário falso (false). Isso quer dizer que se, por exemplo, tiver um objeto da classe Integer que vale 15 e uma string contendo os caracteres 1 e 5, a comparação de ambos resultará em verdadeiro. A função equals() é case sensitive, para fazer uma comparação ignorando esta www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 139 característica basta usar o método equalsIgnoreCase(). public class ComparacaoIgualdadeString { public static void main(String[] args) { String string1 = "PRIMEBEAN"; String string2 = "primebean"; System.out.println("São iguais? (case sensitive)"); System.out.println(string1.equals(string2) ? "sim" : "não"); System.out.println("São iguais? (sem case sensitive)"); System.out.println(string1.equalsIgnoreCase(string2) ? "sim" : "não"); } } Há também uma forma de comparar strings lexicograficamente. Dessa forma, podemos verificar se uma string é idêntica (quando retorna-se 0), ou se ela tem um valor menor (quando retorna-se um número abaixo de 0) ou se ela tem um valor maior (quando retorna-se um número acima de 0). O método para fazer tais comparações é o compareTo() (case sensitive) ou compareToIgnoreCase() (sem case sensitive). public class ComparacaoString { public static void main(String[] args) { String string1 = "PRIMEBEAN"; String string2 = "primebean"; int comparacao = string1.compareTo(string2); System.out.println("Comparação entre string1 e string2 (sensitive case)"); if (comparacao > 0) { System.out.println("string1 é lexicograficamente maior que string2"); } else if (comparacao < 0) { System.out.println("string1 é lexicograficamente menor que string2"); } else { System.out.println("string1 é lexicograficamente igual a string2"); } } } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 140 24.5. Início e fim Outra forma de fazer comparações é fazer testes no início e no fim de uma string. Podemos fazer tais comparações usando dois métodos: startsWith() e endsWith(). StartsWith() verifica se há uma string no começo de outra string. StartsWith() também possui um segundo parâmetro opcional que determina a compensação inicial, ou seja, caso necessite verificar a string não da posição 0, mas de uma posição mais adiante. EndsWith() verifica se há uma string no final de outra string. Diferentemente de startsWith(), o método endsWith() não possui compensação. public class InicioFim { public static void main(String[] args) { String string1 = "http://www.primebean.com.br"; System.out.println("A string " + string1 + " é:"); // verifica se há 'http:' no inicio da string if (string1.startsWith("http:")) { System.out.println("uma URL"); } /* * verifica se há 'www' no início da string, mas apenas a partir do * 8o. caracter, ou seja, após o prefixo 'http://', portanto deverá * ser compensado 7 caracteres */ if (string1.startsWith("www", 7)) { System.out.println("uma página da web"); } if (string1.endsWith(".br")) { System.out.println("um site registrado no Brasil"); } else { System.out.println("não é um site registrado no Brasil"); } } } www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 141 24.6. Caracter na posição Podemos também obter um caracter que se encontra em alguma posição dentro da string. Para isso, usaremos o método charAt(). CharAt() recebe um inteiro como argumento que indica a posição que queremos da string. Importante: Strings seguem o mesmo conceito de vetores e arrays, portanto, seu primeiro caracter não está na posição 1, mas na posição 0. public class ExtrairCaracter { public static void main(String[] args) { String string1 = "primebean"; char caracter = string1.charAt(3); System.out.println("O 4o. caracter desta string é " + caracter); } } 24.7. Índice da String A classe string possui uma forma de encontrar o índice da primeira ocorrência de uma string dentro de outra string. O método indexOf() retorna um número inteiro que indica exatamente em que posição ocorre uma string de busca, ou retorna um valor menor que 0 caso não encontre o valor requisitado. Assim como startsWith(), indexOf() também possui um segundo argumento que determina a compensação a ser feita caso a busca não possa ser feita desde a posição 0, mas de uma posição posterior. Além do método indexOf(), há também o método lastIndexOf() que faz a mesma coisa que indexOf(), porém de forma recursiva (de trás para frente ou do fim da string para o começo). www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 142 public class IndiceString { public static void main(String[] args) { String string1 = "www.primebean.com.br"; int posicao; posicao = string1.indexOf("primebean"); if (posicao >= 0) { System.out.println("A string primebean começa na posição " + posicao); } else { System.out.println("Não há primebean na string"); } posicao = string1.lastIndexOf(".com"); if (posicao >= 0) { System.out.println("A string .com começa na posição " + posicao); } else { System.out.println("Não há .com na string"); } } } 24.8. Substituir string ou parte dela Podemos substituir todas as ocorrências de uma string por uma nova string resultando em uma nova string de retorno. Para executarmos esta operação usamos o método replace() que tem dois parâmetros: o primeiro será o que desejamos procurar dentro da string e o segundo a string que colocaremos no lugar da antiga. Nota: replace também funciona com o tipo primitivo char. public class SubstituirString { public static void main(String[] args) { www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 143 String string1 = "http://primebean.com.br"; System.out.println(string1.replace("http://", "www.")); } } 24.9. Verificar conteúdo da string Um método muito útil para verificar o conteúdo de uma string é o contains(). Contains() retorna verdadeiro (true) se houver a sequência de caracteres especificada no parâmetro. public class VerificarConteudo { public static void main(String[] args) { String string1 = "http://www.primebean.com.br"; System.out.println("É uma página da web?"); System.out.println(string1.contains("www.") ? "sim" : "não"); } } 24.10. Dividindo em vários vetores ou arrays Também é possível dividir uma string em um vetor ou array de strings, o que possibilita trabalhar com pedaços menores e mais lógicos da string. Para dividir a string podemos usar o método split(). O método split usa uma expressão regular para fazer a divisão. Para simplificar o entendimento, podemos usar como parâmetro uma outra string como base. Mas vale atentar no fato de que a expressão utilizada para ser feita a quebra desaparece no fim do processo. Ex.: Se minha string for 15:30:00, se utilizarmos os dois pontos (:) para a www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 144 separação conseguiremos um array com 3 posições que seriam: [0]->15, [1]->30, [2]->00. public class Exemplo { public static void main(String[] args) { String string1 = "15:30:00"; String[] stringDividida = string1.split(":"); for (int i = 0; i < stringDividida.length; i++) { System.out.println("stringDividida[" + i + "]=" + stringDividida[i]); } } } 24.11. Substring Substring é uma porção ou parte da string principal da qual pode formar outra string, ou seja, uma substring é uma string formada a partir de uma string principal. Para obtermos uma substring usamos um método homônimo (de mesmo nome) com um ou dois parâmetros. O primeiro parâmetro, obrigatório, é a posição que a substring deve iniciar (lembrando-se que strings sempre começam da posição 0). O segundo parâmetro, opcional, é a posição final da substring, caso este parâmetro não seja indicado, a substring sempre irá até o último carácter encontrado. Nota: O carácter na posição inicial fará parte da substring, porém o carácter na posição final não faz parte da substring. Vejamos o exemplo: Se tivermos uma string de 9 caracteres, portanto, de 0 a 8 posições, se fizermos a substring da seguinte forma: stringOriginal.substring(5,8); www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 0 1 2 3 4 5 6 7 8 P R I M E B E A N 145 O resultado será BEA. Então, se quisermos que a 8a posição entre, devemos usar a posição seguinte 9, assim: stringOriginal.substring(3,9); public class ExemploSubstring { public static void main(String[] args) { String url = "www.primebean.com.br"; String dominio = url.substring(4); String site = url.substring(url.indexOf('.') + 1,url.lastIndexOf('.')); System.out.println("Análise da string:"); System.out.println("Domínio: " + dominio); System.out.println("Site: " + site); } } 25. Manipulando datas em Java Para quem está começando, trabalhar com datas em Java pode ser um pouco complicado, já que a classe Date não fornece todos os recursos necessários. Para completá-la é também utilizada a classe Calendar, que é uma classe abstrata que permite a manipulação de datas de forma mais fácil. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 146 25.1. Date(java.util.Date) A classe Date armazena uma data e hora, que internamente é armazenada com um inteiro long que é o numero de milissegundos que se passou desde 01/01/1970. Esta classe é bem simples de se trabalhar, mas muitos de seus métodos foram depreciados por não trabalhar muito bem com internacionalização e etc. Date d = new Date(); 25.2. Calendar(java.util.Calendar) A classe Calendar sendo uma classe abstrata não pode ser instanciada com o operador new, ela deve ser criada utilizando um operador estático sobrecarregado getInstance(). Na maioria das vezes você vai receber uma instância de Java.util.GregorianCalendar. Calendar c = Calendar.getIntance(); Com a instância de Calendar devemos configurar uma data e podemos fazer isso de duas formas: Métodos set c.set(ano,mes,dia); c.set(ano,mês,dia,hora,minuto); c.set(ano,mês,dia,hora,minuto,segundo); Método setTime c.setTime(new Date() ); www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 147 A classe Calendar também nos fornece várias constantes que utilizaremos para manipular uma data entre elas. Com a data devidamente configurada podemos realizar diversas operações com a data: Para adicionar ou subtrair um dia, hora, mês ou ano utilizamos o método add. O método add aceita dois parâmetros, sendo o primeiro um constante inteira que representa a unidade da data que queremos modificar(dia, mês , ano, etc…) e o segundo quantas vezes será adicionada/subtraída esta unidade. A unidade é informada utilizando constantes fornecidas pela classe Calendar que pode ser: Dia: Calendar.DAY_OF_MONTH Calendar.DAY_OF_WEEK Calendar.DAY_OF_YEAR Mês: Calendar.MONTH Ano: Calendar.YEAR Hora: Calendar.HOUR Calendar.HOUR_OF_DAY www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 148 Segundos: Calendar.SECOND Veja o Exemplo abaixo: Date d= new Date(); Calendar c = Calendar.getInstance(); c.add(Calendar.DAY_OF_YEAR,5 );//adicionamos 5 dias a data aual c.add(Calendar.MONTH,3 );//adicionamos 3 mêses a data atual c.add(Calendar.YEAR,1 );//adicionamos 1 ano a data atual 25.3. DateFormat(java.text.DateFormat) Bom agora sabemos como manipula datas, agora precisamos formatar a data para apresentação. A classe DateFormat nos fornece uma maneira simples de formatá-la e permite a internacionalização a partir da classe Locale. Date d = new Date(); Calendar c = Calendar.getInstance(); c.setTime(d); DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); System.out.println( df.format(c.getTime()) ); Para obtermos uma String da data utilizamos o método format que retorna uma String no formato especificado no método getDateInstance(). A saída do exemplo acima será algo como 03/04/14. A classe DateForma nos fornece vários tipos de formato para data como: www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 149 Dateformat.SHORT // 03/04/14 Dateformat.MEDIUM // 03/04/2014 Dateformat.LONG //3 de Abril de 2014 Dateformat.FULL //Quarta-feira, 3 de Abril de 2014 Embora para muitos casos estes formatos serão suficientes algumas vezes necessitamos de uma formato vem personalizado. Isso pode ser feio através de um subclasse de DateFormat a SimpleDateFormat.. Date hoje = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); System.out.println( sdf.format(hoje)); O construtor de SimpleDateFormat recebe uma String que representa o formato da data. Os símbolos utilizados para cada campo da data pode ser visto na tabela abaixo abaixo: Símbolo Significado Apresentação Exemplo G era designator (Text) AD Y Year (Number) 2014 M Month in year (Text & Number) April & 04 D Day in month (Number) 14 h Hour in am/pm (1 ~ 12) (Number) 12 H Hour in day (0 ~ 23 ) (Number) 0 m Minute in hour (Number) 30 s Second in minute (Number) 55 S milisecond (Number) 978 E Day in week (Text) Tuesday D Day in year (Number) 189 F Day in week in month (Number) 2(2nd Wed in July) w Week in year (Number) 27 W Week in month (Number) 2 www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 150 a Am/pm marker (Text) PM k Hour in day (1 ~ 24) (Number) 24 K Hour in am/pm (0 ~ 11) (Number) 0 z Time zone (Text) Pacif Standard Time Como vimos o dia da semana pode ser escrito por extenso, que língua ele será utilizada? Normalmente o inglês, mas se quisermos que seja na língua de um local diferente? Para isso utilizaremos a internacionalização com a classe Locate que recebe em seu construtor a língua e o país que queremos utilizar: Locale brasil = new Locale("pt","br");//portugues do brasil Locale japao = new Locale("ja");// japao O objeto locale de Locale pode ser utilizado tanto com a classe DateFormat quanto com a classe SimpleDateFormat. Date hoje = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("E dd ",new Locale("pt","br")); System.out.println( sdf.format(hoje)); DateFormat df = DateFormat.getDateInstance(DateFormat.FULL,new Locale("pt","br")); System.out.println( df.format(hoje)); Para finalizar como covertermos uma String em um objeto Date Date d = new Date(); SimpleDateFormat df = new SimpleDateFormat("DD/MM/yyyy"); try { d = df.parse("25/03/2010"); } catch (ParseException ex) { ex.printStackTrace(); www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 151 } System.out.println( df.format(d)); O métdo parse da classe DateFormat e recebe uma string e convertepara um objeto Date 26. Uma Introdução à API Swing Após apresentarmos os conceitos estruturais principais de linguagem, a idéia de orientação a objeto e as classes que mais utilizaremos como String e Numbers, passaremos agora a focar uma programação mais voltada a práticas possíveis, demonstrando classes com funções mais avançadas e importantes, além de abandonarmos um pouco o visual de console e partirmos para a programação visual de Java. 26.1. JoptionPane Para introduzir esta nova fase, iniciaremos descrevendo um pouco sobre JOptionPane do pacote visual Swing. A classe JOptionPane nos proporciona uma série de métodos estáticos que ao serem invocados criam caixas de diálogos simples e objetivas. Para usar JOptionPane javax.swing.JoptionPane primeiro. www.primebean.com.br www.primebean.com.br/joeydecurcio temos sempre que importar o pacote Introdução á Linguagem de Programação JAVA 152 26.2. Caixas de Diálogo Input Text As caixas de diálogo de entrada de texto ou Input Text Dialog servem para fazer uma requisição de algum dado ao usuário de forma bem simples e direta. O que é digitado pelo usuário é retornado pelo método em forma de string. Existem mais de 10 métodos sobrecarregados para invocar uma caixa de diálogo Input Text, mas, a princípio, usaremos a mais simples. O método showInputText recebe um argumento que é a string contendo a informação desejada, o que na maioria das vezes é uma pergunta ou pedido. O exemplo abaixo demonstra um programa pedindo para que digite seu nome. import javax.swing.JOptionPane; public class CaixasDeDialogo { public static void main(String[] args) { JOptionPane.showInputDialog("Qual é o seu nome?"); } } Será apresentada uma janela a seguir. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 153 26.3. Caixas de Diálogo Confirm Outra caixa de diálogo simples e objetiva do JOptionPane é a caixa de diálogo de confirmação ou Confirm Dialog. A Confirm Dialog (caixa de confirmação) consiste de uma caixa contendo uma mensagem, um ícone e três botões: sim, não e cancelar. Apesar deste ser o aspecto padrão, esta caixa, como qualquer outra de JOptionPane, pode ser facilmente configurada (assunto que será tratado com mais detalhes nas próximas páginas). No método padrão chamado showConfirmDialog usamos dois argumentos: 1. O primeiro é a dependência ou frame pai, ou seja, de qual janela esta confirmação está sendo gerada. Como nossos exemplos iniciais não possuem nenhuma dependência, então, sempre usaremos null neste argumento. 2. O segundo argumento é a mensagem que desejamos mostrar ao usuário. O método showConfirmDialog sempre retorna uma constante que é a resposta clicada pelo usuário, que são: Valor Nome da Constante Equivale 0 YES_OPTION ao clicar no botão Yes (sim) 1 NO_OPTION ao clicar no botão No (não) 2 CANCEL_OPTION ao clicar no botão Cancel (cancelar) Melhorando o exemplo anterior ficaria assim. import javax.swing.JOptionPane; public class CaixasDeDialogo { www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 154 public static void main(String[] args) { String nome = null; nome = JOptionPane.showInputDialog("Qual é o seu nome?"); JOptionPane.showConfirmDialog(null, "O seu nome é " + nome + "?"); } } A caixa de confirmação pareceria da seguinte forma: 26.4. Caixa de Diálogo de Mensagem A caixa de diálogo de mensagem é uma caixa que serve apenas para emitir uma mensagem. Esta caixa também é muito configurável e versátil, pois serve para muitas situações distintas como uma mensagem de erro, um alerta, ou simplesmente uma informação. O método showMessageDialog é responsável em trazer a caixa de mensagem, o qual pode ter muitos argumentos, porém, vamos nos ater ao mais simples. Assim como o método showConfirmDialog, usaremos null como valor de nosso primeiro argumento, pois, por enquanto, não há dependência de outras janelas em nosso programa. O segundo argumento é a mensagem que desejamos emitir. Para finalizar nosso exemplo, incluiremos as caixas de mensagem de acordo com as respostas. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 155 import javax.swing.JOptionPane; public class CaixasDeDialogo { public static void main(String[] args) { String nome = null; int resposta; nome = JOptionPane.showInputDialog("Qual é o seu nome?"); resposta = JOptionPane.showConfirmDialog(null, "O seu nome é " + nome + "?"); if (resposta == JOptionPane.YES_OPTION) { // verifica se o usuário clicou no botão YES JOptionPane.showMessageDialog(null, "Seu nome é " + nome); } else { JOptionPane.showMessageDialog(null, "Seu nome não é " + nome); } } } Abaixo está um exemplo de como irá ficar a caixa de mensagem caso clique no botão YES. www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 156 26.5. Input Dialogs Caixas de Entrada de Dados Como foi introduzido anteriormente, em Java, podemos usufruir de classes e objetos do pacote Swing, o qual facilita a criação de interface gráfica sem a necessidade de ficar horas programando. Neste artigo, nos aprofundaremos no uso de JOptionPane, começando a personalizar algumas caixas de diálogo mais simples. Caixas de diálogo de entrada de dados são importantes para obter informações ou requisitar algo do usuário. No objeto JOptionPane, há o método showInputDialog() que é responsável em criar uma caixa de diálogo requisitando uma entrada de dado. Este método é sobrecarregado de várias maneiras. A forma mais simples de seus argumentos é: 1. A mensagem que deve ser exibida para o usuário. Com apenas este argumento é possível criar uma caixa de diálogo com o título Input, um ícone de interrogação, uma caixa de texto, uma mensagem e dois botões. Igual a figura abaixo: Porém, há como alterarmos a aparência dessa completamente. Outra forma é utilizar dois argumentos, sendo: www.primebean.com.br www.primebean.com.br/joeydecurcio caixa, customizando-a Introdução á Linguagem de Programação JAVA 157 1. A mensagem que deve ser exibida ao usuário. 2. O valor inicial da caixa de texto. O valor inicial da caixa de texto é a string que deve aparecer dentro do campo onde digitamos nossa entrada. Assim que aparece a caixa, seu campo está preenchido com um valor inicial já selecionado. Ex.: O código JOptionPane.showInputDialog("Qual o seu nome?", "Digite seu nome aqui.") geraria a seguinte caixa: Uma das formas mais completas desse método inclui alterar, inclusive, o título da caixa. Assim, usa-se 4 argumentos: 1. De qual frame a caixa de diálogo é dependente, ou seja, qual a janela principal que chamou a caixa Input Dialog. Caso a caixa de diálogo não dependa de nenhum frame ou janela principal, basta utilizarmos o valor null para este argumento. 2. A mensagem que deve ser exibida ao usuário. 3. O título da caixa de texto. 4. Que tipo de mensagem é. O tipo de mensagem define qual o ícone será utilizado, podendo ser utilizados os números inteiros representados pelas constantes: www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 158 • PLAIN_MESSAGE (valor: -1): Mensagem limpa, sem nenhum ícone. • ERROR_MESSAGE (valor: 0): Mensagem de erro. • INFORMATION_MESSAGE (valor: 1): Mensagem informativa. • WARNING_MESSAGE (valor: 2): Mensagem de alerta. • QUESTION_MESSAGE (valor: 3): Mensagem de requisição ou pergunta. Esta é a opção padrão do método showInputDialog(). Ex.: O código JOptionPane.showInputDialog(null, "Qual o seu Nome?", "Pergunta", JOptionPane.PLAIN_MESSAGE) geraria a seguinte caixa: 26.5.1. Obter valor de showInputDialog O método showInputDialog pode retornar dois valores: ou uma string ou null. Se o botão OK for clicado a string contida na caixa de texto será retornada, se o botão Cancel for clicado o valor null será retornado. Sabendo disso, podemos usar uma variável string para obter o valor e tratarmos da forma que quisermos. Vejamos o exemplo abaixo: import javax.swing.JOptionPane; public class CaixasDeInput { www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 159 public static void main(String[] args) { String nome = null; while (nome == null || nome.equals("")) { nome = JOptionPane.showInputDialog("Qual o seu nome?"); if (nome == null || nome.equals("")) { JoptionPane.showMessageDialog(null, "Você não respondeu a pergunta."); } } JOptionPane.showMessageDialog(null, "Seu nome é " + nome); } } 26.5.2. Input Dialog com lista de opções Outra forma de caixa de diálogo de entrada de dados é a Input Dialog com lista de opções. É o mesmo método showInputDialog, mas com mais argumentos, sendo um deles uma lista de objetos. Esta lista de objetos fará com que a caixa de diálogo venha com um combo box ao invés de um campo de texto. Para criar um Input Dialog com um combo box devemos usar os seguintes argumentos na respectiva ordem: 1. De qual frame a caixa de diálogo é dependente, ou seja, qual a janela principal que chamou a caixa Input Dialog. Caso a caixa de diálogo não dependa de nenhum frame ou janela principal, basta utilizarmos o valor null para este argumento. 2. A mensagem que deve ser exibida ao usuário. 3. O título da caixa de texto. 4. Que tipo de mensagem é. O tipo de mensagem define qual o ícone será utilizado, podendo ser utilizados os números inteiros representados pelas constantes da www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 160 mesma forma como foi mostrada anteriormente. 5. O quinto argumento é representado pelo objeto Icon, que é um ícone que podemos criar a partir de um jpg, gif, png, etc. 6. O segredo do combo box está neste argumento. Aqui virá um array (vetor) de objetos que serão nossos valores pré-definidos. 7. O último argumento serve apenas para indicar qual elemento do array (vetor) deve vir selecionado no início. Caso não desejarmos que um ítem seja selecionado no início basta utilizarmos null. O array (vetor) de objetos deve ser genérico, portanto, utilizamos a classe Object para criar este array. O método showInputDialog com combo box se diferencia do showInputDialog com caixa de texto pelo seguinte fato: o que é retornado dessa vez não será uma string, mas um objeto. Isso faz sentido se percebermos que agora estamos escolhendo um item dentro de uma lista de objetos. Portanto, o que será retornado será um objeto dessa lista, não uma string como acontecia com o Input Dialog com caixa de texto. Então, se quisermos utilizar o objeto genérico como algum outro tipo de dado, devemos antes fazer uma indução de tipo ou typecasting. Vejamos o exemplo abaixo: import javax.swing.JOptionPane; public class CaixaComComboBox { public static void main(String[] args) { Object[] opcoes = { "sim", "não" }; Object resposta; do { resposta = JoptionPane.showInputDialog(null, "Deseja finalizar o programa?", www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 161 "Finalização", JoptionPane.PLAIN_MESSAGE, null, opcoes, "não"); } while (resposta == null || resposta.equals("não")); } } No exemplo acima, criamos uma lista com dois objetos: "sim" e "não". E já definimos "não" como opção pré-selecionada. Removemos qualquer ícone com as opções PLAIN_MESSAGE e ícone null. Criamos um laço (loop) com while que sempre irá repetir a mesma caixa enquanto o botão Cancel ou a opção "não" forem selecionados. Abaixo está um exemplo mais funcional, divertido e simples de fazer e entender. Trata-se de um jogo de adivinhar onde um número é escolhido e temos que adivinhar qual número foi sorteado. No exemplo, serão usados elementos já estudados no site como a classe Math e Integer. import javax.swing.JOptionPane; public class JogoDeAdivinhar { public static void main(String[] args) { // define um número qualquer entre 0 e 10 int rndNr = (int) Math.ceil(Math.random() * 10); // lista de opções para o combo box da caixa de diálogo Object[] opcoes = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9","10" }; // string onde será retornado o resultado String resposta; while (true) { // loop para evitar que o jogo feche depois da primeira resposta resposta = (String) JOptionPane.showInputDialog(null, "Em que número estou pensando?", "Jogo de Advinhar", JoptionPane.QUESTION_MESSAGE, null, opcoes, null); www.primebean.com.br www.primebean.com.br/joeydecurcio Introdução á Linguagem de Programação JAVA 162 if (resposta == null) { /* * se clicar no botão Cancel, mostrar uma mensagem de Game Over * e sair do loop para finalizar o programa */ JOptionPane.showMessageDialog(null, "Game Over!\nVocê desistiu do jogo!"); break; } if (Integer.valueOf(resposta) > rndNr) { /* * Interpreta string como inteiro e compara com o número sorteado * para ver se é maior */ JOptionPane.showMessageDialog(null, "Errado!\nO número que eu pensei é menor."); } else if (Integer.valueOf(resposta) < rndNr) { /* * Interpreta string como inteiro e compara com o número sorteado * para ver se é maior */ JOptionPane.showMessageDialog(null, "Errado!\nO número que eu pensei é maior."); } else { /* * se não for nem maior e nem menor, então é igual. * Finaliza o jogo saindo do loop */ JOptionPane.showMessageDialog(null, "Parabéns\nVocê adivinhou!\n" + "Eu realmente pensei no número " + rndNr); break; } } } } www.primebean.com.br www.primebean.com.br/joeydecurcio