SlideShare uma empresa Scribd logo
1 de 73
Baixar para ler offline
Programação Desktop 
Uma abordagem com Java 
ROSICLÉIA FRASSON DE SOUZA
Fundamentos da Linguagem Java Rosicléia Frasson 
1 
Fundamentos da linguagem Java 
Histórico da linguagem Java 
por Bruno Bitencourt Luiz 
Em 1991, atenta a grande tendência dos microprocessadores e dispositivos inteligentes, a Sun Microsystems dá início a um projeto de pesquisa com a ideia de desenvolver uma linguagem sólida para o mercado. O líder do projeto era James Gosling. O objetivo era que aplicações rodassem em qualquer aparelho de pouca memória como switchboxes de televisores. Para cumprir este objetivo a linguagem deveria ser pequena, porém potente. Infelizmente, o mercado para estes dispositivos não se desenvolveu como a Sun esperava. Porém, em 1993, a Web se populariza de uma forma repentina. A Sun vê então a possibilidade de usar esta linguagem para a Web. A ideia é que esta linguagem baseada em C++ tornasse as aplicações Web e suas animações mais dinâmicas. Oficialmente, o Java só é apresentado em 1995 durante uma conferência. 
Finalmente, no início de 1996 é lançado o Java 1.0. Versão que de imediato causou decepção na comunidade Java, pois pecava em vários requisitos como: segurança e interface visual. Mais adiante, foi lançada a versão 1.1, com várias melhorias de segurança e graficamente mais amigável, mas ainda não era satisfatória. Na conferência JavaOne em 1998 a versão 1.2 é lançada. Continha várias melhorias de segurança e substituía por completo a interface anterior. Esta versão foi um marco na história do Java, dias depois a versão 1.2 passou a se chamar Java 2 Standart Edition Software. Posteriormente foram sendo lançadas várias atualizações. A última versão que adicionou uma série de recursos significativos foi a versão 5, pois mais de 1000 classes e interfaces foram implementadas. Atualmente o Java está na versão 8 com mais de 3 mil classes e interfaces existentes. 
O Java é amplamente aceito por parte dos desenvolvedores. Isso se deve a características como: simplicidade, orientação a objetos, compatibilidade com redes, robustez, segurança, portabilidade, alto desempenho, capacidade de múltiplos threads. Além disso, deve-se destacar que sua licença é GPL, e que é multiplataforma, ou seja, para desenvolver em Java não é necessário adquirir qualquer tipo de licença e a compatibilidade com todos os principais sistemas operacionais é garantida. 
Durante o desenvolvimento deste trabalho, a versão Java mais recente é a 8.0. Esta é mais uma daquelas que causam uma revolução. Diversas melhorias como a expressão Lambda (λ) foram adicionadas. Este é um recurso novo no Java, porém já existia em outras linguagens. O foco desta nova versão é fazer mais, com menos código. 
Distribuições do Java 
Java pode ser encontrada em três distribuições principais, cada uma com sua finalidade específica: 
● Java StandartEdition (JSE): Usada em computadores pessoais, notebooks e arquiteturas com poder de processamento consideráveis. Várias APIs acompanham esta versão. 
● Java Enterprise Edition (JEE): É a tecnologia Java para aplicativos distribuídos em rede em larga escala e aplicativos baseados na web . Possui um grande número de APIs voltadas para a segurança da aplicação. Usada em servidores, contendo suporte para JSP, XML e servlets. 
● Java Micro Edition (JME): Usada em dispositivos com recursos limitados, como sistemas embarcados e dispositivos móveis. Possui APIs bem simples e leves para economizar memória e processamento.
Fundamentos da Linguagem Java Rosicléia Frasson 
2 
Além das três principais distribuições, também existe o Java Card, que é uma edição específica para cartões inteligentes, extremamente reduzida. Nesta tecnologia até a máquina virtual é dividida entre o sistema do cartão e o sistema operacional do terminal. 
Compilador e interpretador Java 
O processo de tradução da linguagem Java para a linguagem de máquina é um pouco diferente das demais linguagens de programação. Os programas Java são compilados e interpretados. 
Após a criação de um programa Java, um compilador transforma o programa em uma linguagem intermediária, chamada de bytecodes. Os bytecodes representam uma linguagem de máquina para uma máquina abstrata, executada pela máquina virtual nos dispositivos que suportam a linguagem de programação Java. Sendo assim, o bytecode é independente de plataforma. 
Todas as vezes que o programa é executado, a JVM (Java Virtual Machine) lê o arquivo com a extensão .class que está em bytecode e o interpreta para o processador. Vale mencionar que quando uma classe é carregada na JVM, a mesma é verificada para garantir que os bytecodes são bem formados e atendem aos critérios de segurança e confidencialidade. 
Com o uso da máquina virtual, o programa fica independente de sistema operacional e de plataforma. Uma máquina virtual é muito mais ampla do que um interpretador. Uma máquina virtual é uma espécie de computador de mentira, tem tudo o que um computador tem: gerenciamento de memória, thread, pilha de execução. 
Nas primeiras versões do Java, o processo de interpretação feito pela JVM era lento, o que tornava um problema para a linguagem. Na versão 1.2 surgiu o Compilador Just In Time ou Compilador JIT. O compilador JIT trabalha em conjunto com o interpretador Java. O interpretador verifica quais trechos de código são executados mais vezes e pede que o compilador JIT os compile, convertendo o bytecode na linguagem de máquina do processador que está executando o programa. O JIT também possui informações relativas ao ambiente em que está executando, como quantidade de usuários simultâneos e memória disponível. Com essas informações a JVM muda a estratégia de compilação em busca de um melhor desempenho. 
Java SE 
A Java Standart Edition é o segmento base da plataforma. Com o Java SE é possível criar
Fundamentos da Linguagem Java Rosicléia Frasson 
3 
aplicações Desktop e applets. A Java SE possui duas grandes divisões: 
● JRE: ambiente de execução Java para quem quer apenas executar programas em Java. É composta pela JVM e as APIs Java. Uma API é uma coleção de softwares prontos, que incluem desde estruturas para a manipulação de arquivos até a construção de aplicativos gráficos. 
● JDK: é o conjunto de ferramentas necessárias para o desenvolvimento de programas Java. É composto pela JRE, javac (compilador), jar (empacotador) e o javadoc (documentação). 
IDEs 
Programas em Java podem ser construídos usando apenas um bloco de notas e um prompt de comando. No entanto, com apenas essas duas ferramentas o processo fica bem dispendioso. Para deixar o processo de desenvolvimento mais produtivo, existem programas específicos, chamados de IDEs (Ambiente de Desenvolvimento Integrado). 
Uma IDE é um software que tem como objetivo maximizar a produtividade no processo de desenvolvimento. Alguns recursos que as IDEs possuem: 
● Editor de código: Escrita rápida de código, auto completar, gerenciamento de importações, dicas para correção e geração de código. 
● Depurador: Facilidade na busca por erros no código através da análise cuidadosa de cada passo executado pelo software. 
● Compilador: Geração de código de máquina a partir do código fonte automaticamente. 
● Deploy: Publicação da aplicação, geração de executáveis. 
● Código limpo e automatizado: Facilidade no entendimento do projeto por todos os envolvidos. 
● JVM: Processo de interpretação de bytecodes automático.
Fundamentos da Linguagem Java Rosicléia Frasson 
4 
Principais IDEs para o desenvolvimento Java 
Existem uma infinidade de IDEs para o desenvolvimento Java, abaixo segue uma listagem das líderes de mercado: 
● JDeveloper: O JDeveloper é uma ferramenta da Oracle que tem como principal característica a cobertura de todo o ciclo de desenvolvimento: análise, codificação, manutenção, otimização e implantação. Esta ferramenta é pouco flexível e seu uso é recomendado quando o software for produzido usando toda a arquitetura com produtos Oracle. 
● Eclipse: Poderosíssima IDE de desenvolvimento, leve, rápido, configurável e com inúmeros plug- ins. Deixa a desejar no desenvolvimento de telas para desktop. 
● Netbeans: Juntamente com o Eclipse, uma das IDEs mais utilizadas pela comunidade de desenvolvimento. Tem editor de GUI nativo.Gera muito código automático, não editável. 
Gerenciamento de memória JVM 
Quando a JVM é inicializada um bloco de memória é capturado do sistema operacional para o programa Java ser executado. Em Java, existem duas áreas de memória. Aquela que os objetos residem, chamado de heap e a pilha de execução, onde estão as variáveis locais e as chamadas de métodos a serem executados. 
Variáveis de instância são declaradas dentro de uma classe, mas não dentro de um método. Elas representam o atributo de um objeto. Sendo assim elas residem dentro do objeto a que pertencem, ou seja, no heap. 
A vida de uma variável local é limitada a existência do método em que a mesma está declarada na pilha de execução. Entende-se por variável local as variáveis declaradas dentro de um método, inclusive como parâmetros do método. Se uma variável local não for do tipo primitivo, um objeto correspondente a mesma deve existir no heap. No entanto, como uma variável não primitiva armazena apenas a referência a um objeto e não o próprio objeto, a variável que contém a referência estará armazenada na pilha de execução. 
Quando um programa chama um método, o método entra na pilha de execução de programas. 
Na pilha de chamadas o estado do método e os valores de todas as variáveis locais são armazenados. O método do topo da pilha é sempre o que está sendo executado no momento. Um método e suas variáveis locais permanecem na pilha até o fim da sua execução. 
GarbageCollector 
O Garbage Collector é um dos componentes da JVM e é responsável por liberar espaços da memória que não estão sendo mais utilizados. Diferente do gerenciamento manual, onde o desenvolvedor é responsável tanto pela alocação quanto pela liberação de memória, em Java, o desenvolvedor não define os pontos de coleta, apenas libera as referências dos objetos e em algum momento a coleta é efetuada. Vale ressaltar que um objeto não é excluído do heap no momento em que o mesmo deixa de ser referenciado. O Garbage Collector define o melhor momento de efetuar a coleta. 
O propósito da coleta de lixo é descartar os objetos que não estão sendo mais usados. Isso garante espaço de memória para que o software continue sua execução. Um objeto pode deixar de ser utilizado quando a variável que o está referenciando passa a ser null, quando a variável passa a referenciar outro objeto ou um método termina sua execução e as variáveis locais do mesmo deixam de existir. 
Basicamente o processo de coleta de lixo pode ser descrito em alguns passos. Embora os
Fundamentos da Linguagem Java Rosicléia Frasson 
5 
coletores de lixo sejam um pouco mais sofisticados e dependem do fabricante e versão da JVM, basicamente a coleta de lixo é dividida em duas partes: diferenciação de objetos vivos e mortos e remoção de objetos mortos. 
● Marcação: Nesta etapa o coletor de lixo identifica quais partes da memória estão em uso e quais não estão. 
● Remoçao normal: Objetos não referenciados são removidos, espaços livres ficam espalhados pela memória. 
● Remoção com compactação: Além da remoção dos objetos sem referência, os objetos restantes são realocados. 
A máquina virtual garante que qualquer objeto vai permanecer na memória enquanto existir a possibilidade de o mesmo ser alcançado pela pilha de execução, além de liberar espaço quando o objeto não é mais referenciado. O fato do desenvolvedor não se preocupar com a coleta de lixo é um dos pontos positivos do garbage collector. No entanto, pode se tornar um ponto crítico pela sua imprevisibidade.
Sintaxe da Linguagem Java Rosicléia Frasson 
6 
Sintaxe da linguagem Java 
Ponto e vírgula, blocos, espaços em branco e case-sensitive 
Java é uma linguagem de formato livre, ou seja, não existem regras especiais para o espaçamento vertical ou para a indentação horizontal. Porém, para uma melhor legibilidade do código, é interessante usar espaços, tabulações e novas linhas. Em Java, espaços em branco podem ser usados sem restrições. 
Um bloco é formado por uma ou mais instruções agrupadas entre chaves indicando que formam uma só unidade. O uso de chaves em Java indica a presença de um bloco, onde a abertura da chave indica o início do bloco e o fechamento da chave, o fim do bloco. Os blocos podem ser organizados em estruturas aninhadas infinitamente. 
Uma instrução é composta por uma ou mais linhas terminadas com um ponto-e-vírgula. No fim de cada instrução, indispensavelmente deve ser usado o sinal de pontuação ponto-e-vírgula. A quebra de linha não separa instruções. 
O Java é uma linguagem case-sensitive, ou seja, diferencia maiúsculas de minúsculas. Portanto, escrever letra e LETRA é diferente para o Java. 
Palavras reservadas 
O Java possui uma lista de palavras que possuem um significado especial para o compilador. Essas palavras não podem ser usadas na declaração de classes, métodos e variáveis. 
catch case byte break boolean assert abstract double do default continue const class char float finally final false extends enum else int instanceof import implements if goto for private package null new native long interface super strictpf static short return public protected try transient throws throw this synchronized switch 
while volatile void 
Tipos primitivos 
No Java existem apenas oito tipos primitivos de dados. Os tipos primitivos fazem parte da linguagem e não são instâncias de outras classes. 
Descricão Tipo Classificação O tipo boolean pode armazenar apenas dois valores: true ou false, que representam os valores verdadeiro e falso, respectivamente. O valor boolean lógico
Sintaxe da Linguagem Java Rosicléia Frasson 
7 
padrão do tipo boolean é false. Variáveis do tipo byte podem representar valores inteiros com 8 bits de precisão, ou seja, valores entre -128 a 127. byte inteiro Variáveis do tipo short podem representar valores inteiros com 16 bits de precisão, ou seja, valores entre -32768 a 32767. short Variáveis do tipo int podem representar valores inteiros com 32 bits de precisão, ou seja, valores entre -2147483648 a 2147483647. int Variáveis do tipo long podem armazenar valores inteiros com 64 bits de precisão, ou seja, valores entre -9223372036854775808 a 9223372036854775807. long Variáveis do tipo float podem armazenar valores em ponto flutuante com 32 bits de precisão, na faixa de - 1.40239846E-45 a 3.40282347E + 38 (9 dígitos significativos de precisão). float ponto flutuante Variáveis do tipo double podem armazenar valores em ponto flutuante com 64 bits de precisão, na faixa de - 4.94065645841246544E-324 a 1.79769313486231570E + 308 (18 dígitos significativos de precisão). double O tipo char representa um único caracter em Java. Caracteres em Java são representados usando o conjunto de caracteres Unicode, com dois bytes por caracter. Esta representação permite a representação em várias línguas respectivamente. char caracter 
` 
Ao escolher um tipo de dado para ser usado, o programador deve estar atento a faixa de valores que o campo pode vir a ocupar. A tentativa de armazenar um valor maior do que o esperado pelo tipo pode ocasionar erros no software. 
Para representar valores decimais em Java é utilizado o ponto ao invés da vírgula. 
Além dos caracteres normais, existem os caracteres de controle, que efetuam uma ação diferenciada quando utilizados. Segue uma lista dos mesmos: 
Descrição Caracter aspa dupla ” aspa simples ’ nova linha n tabulação t barra  enter r 
Conversão entre tipos primitivos 
Valores de tipos numéricos podem ser transformados em outros tipos numéricos de duas formas: 
● Implicitamente: A JVM transforma em tempo de execução, quando acha conveniente, tipos restritos em tipos com maior amplitude, ou seja, uma variável pode receber valores de variáveis de tipos com tamanho menor do que a mesma foi declarada. . Nenhuma informação é perdida. 
● Através de uma operação chamada casting ou conversão explícita. Para efetuar a conversão
Sintaxe da Linguagem Java Rosicléia Frasson 
8 
explícita, basta colocar o tipo de dado para o qual se deseja converter entre parênteses antes da expressão a ser convertida. Neste caso, o programador estará se responsabilizando por possíveis perdas de valores. 
Na tabela a seguir, estão relacionados todos os casts possíveis na linguagem Java. 
double float long int char short byte PARA: DE: implícito implícito implícito implícito (char) implícito ----- byte implícito implícito implícito implícito (char) ----- (byte) short implícito implícito implícito implícito ----- (short) (byte) char implícito implícito implícito ----- (char) (short) (byte) int implícito implícito ----- (int) (char) (short) (byte) long implícito ----- (long) (int) (char) (short) (byte) float ----- (float) (long) (int) (char) (short) (byte) double 
Declaração de variáveis 
Variáveis são espaços na memória onde podemos guardar informações. Cada valor é convertido para binário e então pode ser alocado na memória. Praticamente todos os programas usam variáveis. E como o próprio nome diz, elas podem ter o valor modificado durante a execução do programa. As variáveis possuem tipos diferentes, dependendo da informação a ser armazenada. 
No Java, para declarar uma variável é necessário especificar o tipo, dar um nome a ela e preferencialmente inicializá-la. Valores iniciais são estabelecidos por expressões de inicialização usando o operador = quando as variáveis são declaradas. 
Os nomes de variáveis ou identificadores possuem algumas regras para que o compilador identifique como válido: 
● Os nomes de variáveis em Java devem ser inicializados por uma letra, um cifrão ou por undescore; 
● Após o primeiro caracter, vale qualquer combinação de números, letras e caracteres; 
● Os identificadores não podem ter o nome igual ao de uma palavra reservada. 
Além das regras que são definidas pela linguagem, algumas convenções de nomes foram estabelecidas pela comunidade de programadores com o intuito de deixar o código mais legível. Segue uma lista das principais convenções: 
● O nome de uma variável deve ser escrito em letras minúsculas. Caso o nome da variável seja uma palavra composta, a primeira letra a partir da segunda palavra deve ser escrita com letra maiúscula; 
● O nome de uma variável deve ser significativo, indicando claramente o que a variável representa. Isso significa que se o nome de uma variável necessita de um comentário para explicar o porquê da sua existência, ele deve ser trocado. 
● É indicado utilizar nomes que refletem o domínio em que o software será utilizado. 
● As abreviações e siglas devem ser usadas com cautela. Decifrar uma abreviação adiciona um
Sintaxe da Linguagem Java Rosicléia Frasson 
9 
tempo extra na execução de uma tarefa. 
● Nomes semelhantes devem ser evitados, pois podem confundir o desenvolvedor, principalmente quando o recurso de autocompletar disponível nas IDEs de desenvolvimento é utilizado. 
● É considerada uma boa prática não utilizar como identificadores nomes confusos que podem levar quem lê o código a conclusões erradas. 
● Identificadores de variáveis devem ser escritos no singular, exceto quando a variável representar uma coleção de dados. 
● É indicado utilizar nomes pronunciáveis para facilitar a leitura e comunicação. 
● É preferível declarar uma variável por linha, ao invés de várias na mesma linha. 
Entrada e saída de dados 
A classe Scanner possui uma série de métodos convenientes para ler o fluxo de entrada. A mesma faz parte do pacote java.util e é necessário importá-lo para a utilização da classe. Para a leitura de dados do console, na criação do objeto é necessário passar como argumento Sistem.in. 
Para cada tipo primitivo existe um método da classe Scanner que retorna um valor do tipo que foi invocado. Sendo assim, existem os métodos nextInt(), nextDouble(), nextFloat(), nextBoolean(), entre outros. O método close() fecha o escaneamento de leitura. 
O objeto System.out permite exibir uma saída de texto no console. Dentro deste objeto existem os métodos println(), print() e printf(). O método println() gera uma saída de texto juntamente com uma quebra de linha, o método print gera uma saída de texto sem quebra de linha e o método printf() exibe dados formatados. 
package br.com.rosicleiafrasson.sintaxeBasica; 
import java.util.Scanner; 
public class EntradaSaidaDadosConsole { 
public static void main(String[] args) { 
Scanner entrada = new Scanner(System.in); 
int idade; 
String nome; 
double peso; 
System.out.println("Informe o seu nome: "); 
nome = entrada.nextLine(); 
System.out.println("Informe a sua idade: "); 
idade = entrada.nextInt(); 
System.out.println("Informe o seu peso: "); 
peso = entrada.nextDouble(); 
System.out.println(nome + ", você possui " + idade + " anos. "); 
System.out.print("Seu peso é "); 
System.out.printf("%.2f", peso); 
entrada.close(); 
} 
}
Sintaxe da Linguagem Java Rosicléia Frasson 
10 
Operadores básicos 
Referência a método, função ou atributo de um objeto. . Separador de identificadores. , Finalizador de declarações e comandos. ; Declarador de vetores e delimitador de índices. [ ] Separador de blocos. { } Lista de parâmetros. ( ) Operador de atribuição. = 
Operadores lógicos 
Maior > Maior ou igual >= Menor < Menor ou igual <= Igual == Diferente != E && OU || 
Operadores aritméticos 
Adição + Subtração - Multiplicação * Divisão / Módulo (resto da divisão) % 
É importante ressaltar que a divisão de números inteiros sempre resulta em um inteiro. Mesmo que a variável responsável por armazenar o resultado seja do tipo double ou float.
Sintaxe da Linguagem Java Rosicléia Frasson 
11 
Operadores de incremento e decremento 
Os operadores de incremento e decremento são operadores que atuam sobre uma única variável numérica, aumentando ou diminuindo ou seu valor. 
● incremento: adiciona o valor de uma unidade ao valor atual. O operador de incremento é o sinal de ++; 
● decremento: diminui uma unidade do valor atual. O operador de decremento é o --; 
Os operadores de incremento e decremento podem ser posicionados imediatamente antes ou imediatamente após o nome da variável. Vale ressaltar que esses operadores funcionam de forma diferente dependendo da posição em relação a variável. Se o operador for colocado antes, a variável é incrementada no momento da sua avaliação. Caso contrário, a variável é incrementada após a sua avaliação. Maiores detalhes podem ser vistos na tabela a seguir: 
Significado Exemplo Operador Incrementa a variável e depois usa. ++x ++ Usa a variável e depois incrementa. x++ Decrementa a variável e depois usa. --x -- Usa a variável e depois decrementa. x-- 
Operadores de atribuição 
Expressão equivalente Exemplo Operador x = x + y x += y += x = x - y x -= y -= x = x * y x *= y *= x = x / y x /= y /= x = x % y x%=y %= 
Operador condicional ternário ( ?:) 
O operador condicional ternário retorna um entre dois valores de acordo com o resultado de uma expressão booleana. O mesmo possui a seguinte estrutura: 
Onde: 
● o primeiro operador a esquerda do ? é a condição, normalmente representada por uma expressão booleana; 
● o segundo operando que fica entre ? e : representa o valor da expressão, caso a condição seja
Sintaxe da Linguagem Java Rosicléia Frasson 
12 
verdadeira; 
● o terceiro operando a direita do : representa o valor da expressão se a condição for falsa. 
Segue um trecho de código que deve mprimir na tela a mensagem aprovado, caso a nota do aluno seja um valor maior ou igual a 7. Caso contrário deve imprimir a mensagem reprovado. 
Scanner entrada = new Scanner(System.in); 
double nota; 
System.out.println("Informe a nota do aluno: "); 
nota = entrada.nextDouble(); 
System.out.println(nota >= 7 ? " Aluno aprovado " : " Aluno reprovado"); 
Diferença entre tipos primitivos e variáveis de referência 
As variáveis primitivas guardam o real conteúdo da variável. Uma variável de tipo primitivo pode armazenar exatamente um valor de seu tipo declarado por vez, quando outro valor for atribuído a essa variável, seu valor inicial será substituído. 
As variáveis de referência são as variáveis que apontam para um objeto, ou seja,guardam um endereço de memória para um objeto criado.Desta forma, quando um outro valor é atribuído para a variável, uma nova posição de memória aloca o novo valor e a referência aponta para a nova posição de memória. O tamanho alocado para uma variável de referência é sempre fixo, pois se trata de um endereço de memória que mostra como chegar ao objeto. 
String 
Em Java não existe um tipo primitivo para se trabalhar com textos. Para fazer uso dos mesmos é necessário utilizar o tipo String que é um objeto presente no Java desde a primeira versão. A classe String faz parte do pacote java.lang e por ser uma classe amplamente usada, ela não precisa ser instanciada. Sua atribuição é composta por uma sequência de caracteres delimitados por aspas duplas. 
Os objetos da classe String são imutáveis, ou seja, o conteúdo de uma String nunca pode ser alterado. Cada vez que é executada uma operação para modificar uma String, o que ocorre é a criação de um novo objeto, enquanto o objeto String original permanece inalterado. 
A JVM mantém uma área especial chamada de pool de Strings. Cada vez que é atribuído uma String a uma variável, é feita uma busca no pool a fim de encontrar uma String idêntica. Se existir, a referência a nova String é direcionada a String existente. Caso contrário, é criada uma nova String no pool. 
A classe String fornece diversos métodos utilitários. Seguem os mais utilizados: 
● equals: Retorna true se as duas Strings possuírem o mesmo tamanho e exatamente os mesmos caracteres. O método equalsIgoreCase não diferencia letras maiúsculas e minúsculas. 
● replace: Este método faz a substituição de um determinado conjunto de caracteres por outro, retornando uma nova String. O método é case sensitive. 
● trim: Retorna uma String sem os espaços em branco no começo e no final da mesma. 
● contains: Este método avalia se a String original possui a String passada por parâmetro. Retorna um valor booleano. 
● lenght: Retorna o tamanho da String.
Sintaxe da Linguagem Java Rosicléia Frasson 
13 
● toUpperCase: Retorna uma nova String com todos os caracteres em maiúsculo. 
● toLowerCase: Retorna uma nova String com todos os caracteres em minúsculo. 
● charAt: Retorna o caracter que se encontra na posição passada por parâmetro da String. 
● substring: Retorna um objeto String contendo os caracteres especificados entre o intervalo de valores passados como argumentos para o método. 
● valueOf: Retorna uma String a partir de uma dado numérico. É um método estático, sendo assim, não pertence a um objeto e sim a classe String. 
public class UtilitariosString { 
public static void main(String[] args) { 
String frase1 = "O rato roeu a roupa do rei de roma."; 
System.out.println(frase1.replace('r', 'p')); 
String frase2 = " É melhor prevenir do que remediar. "; 
System.out.println(frase2.trim()); 
String frase3 = "Um é pouco, dois é bom, três é demais"; 
System.out.println(frase3.contains("dois")); 
System.out.println(frase3.length()); 
System.out.println(frase3.toUpperCase()); 
System.out.println(frase3.toLowerCase()); 
System.out.println(frase3.substring(12,22)); 
System.out.println("dois".equals("dois")); 
System.out.println("dois".equalsIgnoreCase("DOIS")); 
System.out.println(frase3.charAt(8)); 
String numeroCasa = String.valueOf(45); 
} 
} 
Para transformar uma String em um tipo numérico, é necessário utilizar as classes de ajuda para os tipos primitivos correspondentes: 
● Integer.parseInt: Para conversões para o tipo inteiro; 
● Double.parseDouble: Para conversões para o tipo double. 
● Long.parseLong: Para conversões para o tipo long. 
● Float.parseFloat: Para conversões para o tipo float. 
● Short.parseShort: Para conversões para o tipo short. 
● Byte.parseByte: Para conversões para o tipo byte. 
int idade = Integer.parseInt(JOptionPane.showInputDialog("Informe sua idade: ")); 
double peso = Double.parseDouble(JOptionPane.showInputDialog("Informe o seu peso: ")); 
float altura = Float.parseFloat(JOptionPane.showInputDialog("Informe sua altura: ")); 
long matricula = Long.parseLong(JOptionPane.showInputDialog("Informe sua matrícula: "));
Sintaxe da Linguagem Java Rosicléia Frasson 
14 
Estruturas condicionais 
Comando if … else 
A estrutura if ... else permite expressar duas alternativas de execução, uma delas executa caso a condição seja verdadeira e a outra quando a condição não for satisfeita. A expressão contida dentro do comando if deve resultar em um valor booleano. A cláusula else é opcional. 
if (expressão){ bloco de comandos }else{ bloco de comandos } 
Quando houver apenas um comando dentro do bloco if ou do bloco else, não é necessário o uso das chaves. 
É possível construir uma série de testes através do encadeamento de um outro if na cláusula else. Quando houver comandos if aninhados, cada else está relacionado ao if que estiver dentro do mesmo bloco que ele. 
Segue um exemplo de utilização do comando if … else de um aplicativo que exibe uma mensagem conforme a situação do aluno: aprovado, em recuperação ou reprovado. 
import java.util.Scanner; 
public class CondicaoIfElse { 
public static void main(String[] args) { 
Scanner entrada = new Scanner(System.in); 
System.out.println("Informe a média do aluno: "); 
double media = entrada.nextDouble(); 
if (media >= 7){ 
System.out.println("Aluno aprovado!"); 
}else if (media >= 4){ 
System.out.println("Aluno em recuperação!"); 
}else{ 
System.out.println("Aluno reprovado!"); 
} 
entrada.close(); 
} 
} 
Comando switch 
O comando switch permite transferir o fluxo de controle para uma entrada rotulada em um bloco de comandos, baseado no valor de uma expressão. A expressão deve ser do tipo inteiro ou um valor enumerado. Em outras palavras, o comando switch faz o teste da expressão de seleção contra os valores das constantes indicados nas cláusulas case, até que um valor verdadeiro seja obtido.
Sintaxe da Linguagem Java Rosicléia Frasson 
15 
switch (expressão){ case constante1: bloco de comandos; break; case constante2: bloco de comandos; break; ••• default: bloco de comandos; } 
Se não for encontrado um rótulo case que combine com o valor da expressão switch, o fluxo de controle é transferido para o primeiro comando que segue o rótulo default. O rótulo default é opcional. 
Vale mencionar que um rótulo case ou default não força uma saída para fora do switch, nem implica no final da execução dos comandos. Para forçar a saída do switch, é necessário utilizar o comando break. 
Segue um trecho de código com a utilização do comando switch. 
import java.util.Scanner; 
public class CondicaoSwitch { 
public static void main(String args[]) { 
Scanner entrada = new Scanner(System.in); 
System.out.println("Informe um dia da semana"); 
int diaDaSemana = entrada.nextInt(); 
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"); 
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!"); 
}
Sintaxe da Linguagem Java Rosicléia Frasson 
16 
entrada.close(); 
} 
} 
Estruturas de repetição 
Comando for 
O comando for é usado quando é necessário repetir um bloco de comando sobre um intervalo de valores do ínicio ao fim. O laço for introduz uma nova mecanismo de definição de variáveis, a declaração no laço de inicialização. Sendo assim, o escopo da variável é reduzido a região exata em que a mesma é necessária, ou seja, a variável existe apenas enquanto o laço estiver sendo executado. 
for (inicialização; condição; incremento){ bloco de comandos; } 
O comando for permite expressar iterações combinando uma expressão de inicialização, um teste de condição e uma expressão de incremento. 
● inicialização: comando de atribuição que define o valor inicial da variável que controla o número de repetições. 
● condição: expressão relacional que define até quando as iterações serão executadas. 
● incremento: expressão que define como a variável de controle do laço deve variar ( pode aumentar ou diminuir). 
O teste da condição do controle é feito no início do laço, o que significa que se a expressão de condição for falsa os comandos dentro do laço não serão executados. 
Segue um exemplo de utilização do comando for. 
public class RepeticaoFor { 
public static void main(String[] args) { 
for (int num = 0; num <=10; num++){ 
System.out.println(num); 
} 
} 
} 
Comando while 
Como já mencionado no comando for, o comando while também é utilizado para repetir um trecho de código diversas vezes. No entanto este comando possui apenas a expressão de condição, a inicialização da variável de controle e o incremento não estão presentes na sintaxe do comando. 
while (condição){ bloco de comandos; }
Sintaxe da Linguagem Java Rosicléia Frasson 
17 
A expressão de condição pode ser qualquer expressão ou valor que resulte em um verdadeiro ou falso. O laço while é executado enquanto a condição for verdadeira e o teste da condição de controle é feito no ínicio do laço, o que significa que se a expressão resultar em um valor falso, os blocos de comando dentro do laço não serão executados. 
Segue um exemplo de utilização do comando while. 
public class RepeticaoWhile { 
public static void main(String[] args) { 
int num = 0; 
while (num <= 10 ){ 
System.out.println(num); 
num++; 
} 
} 
} 
Comando do … while 
Similar ao comando while, porém, o teste da condição de controle é feito no fim do laço, o que significa que os comandos dentro do laço são executados pelo menos uma vez. 
do{ bloco de comandos; }while (condição); 
Segue um exemplo de utilização do comando do … while. 
import java.util.Scanner; 
public class RepeticaoDoWhile { 
public static void main(String[] args) { 
Scanner entrada = new Scanner(System.in); 
int num; 
do{ 
System.out.println("Informe um número: "); 
num = entrada.nextInt(); 
}while(num > 0); 
entrada.close(); 
} 
}
Sintaxe da Linguagem Java Rosicléia Frasson 
18 
Instruções break e continue 
Os comandos break e continue são estruturas auxiliares dos fluxos de repetição. Ambos os comandos paralisam a execução antes do normal. 
O comando break pode ser utilizado com as instruções while, for, do … while e switch e ocasiona a saída imediata dessa instrução. A execução continua com o primeiro comando após a instrução de controle. 
public class ComandoBreak { 
public static void main (String args []){ 
for (int numero = 1; numero <= 1000; numero ++){ 
System.out.println("Número: "+ numero ); 
if (numero == 10) 
break; 
} 
} 
} 
O comando continue ignora as instruções restantes no corpo do loop e prossegue para a próxima iteração do laço. Pode ser utilizado nas estruturas de repetição for, while e do … while. 
Nos laços while e do … while o programa avalia o teste de condição do loop imediatamente após a execução da instrução continue. Nos laços for, a expressão de incremento é executada e então o teste de condição do loop é avaliado. 
public class ComandoContinue { 
public static void main(String[] args) { 
for (int num = 0; num <= 100; num ++){ 
if (num % 5 != 0){ 
continue; 
} 
System.out.println(num); 
} 
} 
} 
Comentários 
Comentário é a parte do código ignorada pelo compilador. É utilizado para deixar o código mais inteligível. Java possui três tipos diferentes de comentário: 
● Comentário de uma linha: O uso de barra dupla marca o início do comentário que se estende até o fim da linha. 
● Comentário de várias linhas: Os delimitadores /* e */ indicam início e fim de um comentário e podem conter várias linhas. 
● Comentário javadoc: É utilizado para gerar a documentação javadoc e é delimitado pelas sequências de símbolos /** e */. Para gerar o javadoc é necessário que o comentário esteja localizado imediatamente antes da classe, atributo ou método documentado.
Sintaxe da Linguagem Java Rosicléia Frasson 
19 
Arrays 
Uma variável em Java corresponde a uma posição de memória, cujo conteúdo pode ser alterado durante a execução do programa. Embora uma variável possa assumir diversos valores, ela só pode armazenar um valor a cada instante. Quando é necessário que mais de um valor do mesmo tipo seja armazenado, pode ser utilizada uma estrutura chamada vetor ou array. 
Como o array pode guardar vários valores, em sua definição é necessário definir o seu tamanho, ou seja, a quantidade máxima de valores que o mesmo pode armazenar. A quantidade de elementos de um vetor é definida na criação do mesmo e não pode ser alterada. 
String[] nome = new String[10]; 
Para declarar um vetor, é necessário colocar um par de colchetes antes ou depois do nome da variável. Também é necessário reservar um espaço na memória e definir o tamanho do vetor, ou seja, a quantidade total de elementos que podem ser armazenados no vetor. O operador new reserva espaço de memória para alocar os elementos. 
Implicitamente cada elemento no array é inicializado com um valor padrão, sendo 0 para numéricos primitivos, false para booleanos e null para objetos. Os objetos arrays possuem um campo length que indicam a quantidade de elementos do array. 
nome[0] = "Maria"; 
Ao armazenar uma informação em um vetor é necessário indicar a posição em que esta será alocada. Nos arrays em Java a primeira posição possui índice 0 e o mesmo aumenta gradativamente até o número de posições reservadas menos um. Uma tentativa ao acesso de uma posição fora dos limites do array lança uma exceção ArrayIndexOutOfBoundsException. 
Um array pode ser inicializado com valores entre chaves que seguem a sua declaração separados por vírgulas. 
String [] frutas = {"Abacaxi", "Acerola", "Morango", "Jaca", "Jabuticaba"}; 
Quando um array é inicializado dentro da sua declaração, não existe a necessidade da criação do vetor usando new. Neste caso, o tamanho do array é determinado pela quantidade de valores fornecidos na inicialização. 
import java.util.Scanner; 
public class Vetor { 
public static void main(String[] args) { 
Scanner entrada = new Scanner(System.in); 
String[] nome = new String[6]; 
for (int i = 0; i < 6; i++){ 
System.out.println("Informe o aluno " + i + " :");
Sintaxe da Linguagem Java Rosicléia Frasson 
20 
nome[i] = entrada.nextLine(); 
} 
System.out.println("nAlunos: "); 
for(int i = 0; i < nome.length; i++){ 
System.out.println(nome[i]); 
} 
entrada.close(); 
} 
} 
Estrutura de repetição for each 
O comando for each possui como objetivo facilitar o loop em um array ou em uma coleção e é indicado para percorrer todo o conjunto de dados, sem a necessidade de indicar o tamanho do mesmo. Os loops for each ficam mais legíveis e tendem a minimizar as oportunidades de erros pela ocultação do iterador, sem perda de desempenho. 
for ( declaração: expressão){ bloco de comandos; } 
Na declaração é necessário indicar o tipo de dado presente no array ou coleção e atribuir um identificador. Caso o tipo de dado indicado na declaração for diferente do tipo de dado dos elementos do array, o código não compila. A expressão consiste no array ou coleção que deve ser percorrida. 
Cada vez que o loop é executado, a variável do laço assume o próximo valor do conjunto e o bloco de comandos é executado. Normalmente a variável do laço é utilizada dentro do bloco de comandos. Esse processo continua até o término do conjunto de dados. 
É importante ressaltar que a instrução for-each pode ser usada apenas para obter elementos de um array, ela não pode ser utilizada para modificar os elementos. Em outras palavras, não é possível adicionar, remover ou alterar um valor do array utilizando o comando for aprimorado, nesses casos deve ser utilizada a estrutura for padrão. 
public class ComandoForAprimorado { 
public static void main(String[] args) { 
int somaNumeros = 0; 
int [] numeros = {87, 45, 65, 32, 44, 26, 7, 90}; 
for(int numero: numeros) 
somaNumeros += numero; 
System.out.println("Soma dos elementos do vetor: " + somaNumeros); 
} 
}
Sintaxe da Linguagem Java Rosicléia Frasson 
21 
Pacotes 
Os pacotes possuem como objetivo agrupar classes de funcionalidades semelhantes ou relacionadas. Um pacote é um diretório onde ficam armazenadas classes, interfaces, subpacotes e arquivos de recursos adicionais, como imagens, usados pelas classes do pacote. Os pacotes são correspondentes as bibliotecas em outras linguagens de programação. 
A utilização de pacotes promove a reutilização de código, auxilia na manutenção e promove os príncipios de encapsulamento e modularidade da orientação a objetos. O empacotamento é recomendado pelos padrões de programação Java a fim de diminuir a possibilidade de colisão de classes, ou seja, classes com o mesmo nome em um mesmo contexto. 
Com o intuito de evitar conflitos de nomes de pacotes e ao mesmo tempo possuir um nome significativo é utilizado um padrão para a nomeação de pacotes: 
● Nomes de pacotes devem ser compostos exclusivamente por letras minúsculas, não importando a quantidade de palavras que o mesmo contenha; 
● Os nomes de pacotes devem ser relativos a empresa que desenvolveu os mesmos. Geralmente é utilizada a nomeação reversa de domínios, onde o início do nome do pacote é dado pela ordem inversa do nome do domínio da instituição na internet. 
Em Java, as classes devem possuir como primeira instrução a indicação do pacote a que pertencem. A instrução começa com a palavra chave package, seguida pelo caminho do pacote delimitado por pontos. Classes que não possuem a instrução package pertencem ao pacote default que correspondem a raiz do projeto. 
package br.com.nomeempresa.sintaxeBasica; 
Classes declaradas sem o modificador de visibilidade public ficam invisíveis para outros pacotes. Classes que não possuem utilidade fora do pacote em que estão declaradas devem possuir o modificador de acesso default. 
A utilização de classes fora do pacote a que pertencem, necessita da indicação do caminho onde estão armazenadas. Isso pode ser feito de duas formas: através do nome plenamente qualificado do tipo ou através da importação do pacote. 
A utilização do nome plenamente qualificado é uma opção viável. No entanto, pode ser tedioso e causar confusão no código, se levando em consideração que os pacotes possuem nomes longos. 
javax.swing.JOptionPane.showMessageDialog(null, "Exemplo utilização de nome plenamente qualificado do tipo"); 
A outra maneira de utilizar classes de um pacote, é importar parte ou todo o pacote através da instrução import. A instrução import permite que código fonte de classes de outros pacotes sejam incluídas dentro de um código fonte em tempo de compilação. A instrução import inclui a palavra chave import seguida pelo caminho do pacote, delimitado com pontos e terminando com o nome de uma classe ou o coringa *. As instruções import ocorrem depois da instrução package e antes da definição de classe. 
import javax.swing.JOptionPane; 
public class Pacote { 
public static void main(String[] args) { 
JOptionPane.showMessageDialog(null, "Exemplo utilização de importação de
Sintaxe da Linguagem Java Rosicléia Frasson 
22 
pacote"); 
} 
} 
A API do JSE é composta por vários pacotes. Todos os pacotes iniciados por java ou javax fazem parte da API padrão. As funcionalidades dos mesmos são detalhadas na documentaçao do Java. Na tabela a seguir, estão os pacotes mais utilizados e uma descrição sucinta dos mesmos: 
Funcionalidade 
Pacote 
Fornece classes que são fundamentais para a concepção da linguagem Java. É importado automaticamente. 
java.lang 
Pacote utilitário. Fornece classes para trabalhar com coleções, entrada de dados (Scanner) e componentes de data e hora. 
java.util 
Fornece classes para definir interfaces gráficas com o usuário. 
java.awt 
Extensão do pacote java.awt. 
javax.swing 
Fornece classes para realizar operações de entrada e saída de dados através do sistema de fluxo de dados (streams) e serialização de objetos . 
java.io 
Classes para acesso a base de dados via JDBC. 
java.sql
Orientação a objetos Rosicléia Frasson 
23 
Programação Orientada a Objetos 
Programar consiste em desenvolver softwares que executam determinadas funcionalidades. Um software pode ser descrito como uma série de instruções organizadas que operam sobre um conjunto de dados. Operar sobre um conjunto pequeno de dados é uma tarefa que pode ser facilmente executada. No entanto, a medida que a complexidade do software aumenta, trabalhar com um extenso conjunto de dados inter relacionado deixa de ser uma tarefa trivial. 
A Programação Orientada a Objetos, também conhecida pelas iniciais POO, oferece uma forma para tratar a complexidade citada, auxiliando na construção de softwares mais confiáveis e de fácil manutenção. O uso do paradigma orientado a objetos melhora a organização e reduz a quantidade de código em um software, além disso, toda a lógica de negócio fica encapsulada, o que garante que as responsabilidades são concentradas nos pontos certos, aumentando a flexibilidade. 
Na POO, um software é conceituado como um conjunto de objetos que interagem e mantém seu próprio estado local, fornecendo ações baseadas nesse estado. Cada objeto constitui uma parte separada do programa e interage com outras partes. Essa interação deve ser feita de maneira controlada, de modo que a representação do estado de um objeto deve ser privativa, ou seja, o estado de um objeto só pode ser acessado pelo próprio objeto. 
As classes constituem a unidade fundamental de um projeto orientado a objetos. São as classes que definem os objetos de um sistema e suas interações. Durante a execução de um software orientado a objetos, objetos são criados dinamicamente a partir de definições de classes. 
Princípios da programação orientada a objetos 
Os pilares que sedimentam a POO são: abstração, encapsulamento, herança, composição e polimorfismo: 
● Abstração: Consiste em focar somente os aspectos importantes de determinado ponto de vista e desconsiderar os aspectos restantes. A abstração é um meio de reduzir a complexidade. Sendo assim, no modelo OO, a abstração significa concentrar-se no que é e no que faz um objeto e não em como o mesmo será implementado. 
● Encapsulamento: Consiste em ocultar detalhes da implementação de uma classe. Utilizando o encapsulamento, os métodos devem ser o único meio de acessar os dados de um objeto. Os dados não podem ser acessados diretamente, isso assegura que um dado não seja modificado acidentalmente por funções externas ao objeto. 
● Herança: Mecanismo da POO que permite a criação de classes derivadas de classes já existentes. As classes derivadas herdam atributos e métodos das classes bases. Sendo assim, existe uma significativa redução na quantidade de código das mesmas. 
● Composição: É o mecanismo que permite o uso de uma ou mais classes para compor uma outra classe. Na composição uma classe é usada como tipo de atributo em uma outra classe, para que seus atributos possam ser utilizados. 
● Polimorfismo: Mecanismo que garante que classes derivadas de uma mesma superclasse invoquem métodos com a mesma identificação, mas com comportamentos distintos. Em outras palavras, o polimorfismo é o mecanismo que permite escrever programas que processam objetos de uma mesma superclasse como se todos fossem do tipo da superclasse.
Orientação a objetos Rosicléia Frasson 
24 
Notação UML 
A UML (Unified Modeling Language) é uma linguagem gráfica para a modelagem de sistemas de software que ajuda na descrição e no projeto de sistemas, particularmente daqueles construídos utilizando o estilo orientado a objetos. Ela é composta por uma série de diagramas que estão divididos em diagramas estruturais e de comportamento. Dentre os diagramas estruturais, um deles, o diagrama de classes, possibilita modelar com clareza os principais conceitos da orientação a objetos. 
A criação de um modelo de classes resulta de um processo de abstração no qual são identificados os objetos relativos ao contexto que se pretende modelar. Além disso, este modelo descreve os membros das classes, como atributos e métodos, identificando com clareza a visibilidade de cada membro. O diagrama de classe também fornece as relações existentes entre as classes. 
Objetos 
Um objeto é a unidade central da POO. Em um sistema computacional pode ser definido como uma abstração de alguma coisa em um determinado domínio. Essa abstração deve permitir que o software mantenha informações sobre a mesma e interaja com ela. Sendo assim, um objeto em um software é algo que se visualiza, se utiliza e pode assumir um papel. 
Em uma definição mais informal, um objeto é qualquer entidade do mundo real que possui um estado e um conjunto definido de operações para funcionar nesse estado. O estado é composto por um conjunto de características do objeto. As operações fornecem serviços a outros objetos quando estes solicitam a realização de uma ação. 
Quando um programa é construído utilizando o paradigma orientado a objetos, é necessário descobrir os objetos que assumem um papel no domínio do problema. Após a descoberta, devem ser analisados os aspectos relevantes ao problema que o software deve resolver. O mesmo tipo de objeto pode requerer características e comportamentos distintos em domínios de negócios distintos, ou seja, um objeto carro em um software para uma montadora possui um enfoque diferente de um carro em um software de uma locadora de veículos. 
Como os objetos em um software são independentes, softwares desenvolvidos usando POO, são mais fáceis de manter. Mudanças na implementação de um objeto ou adição de novas funcionalidades não devem afetar outros objetos do sistema. Além disso, os objetos podem ser componentes reusáveis, visto que um projeto pode utilizar objetos criados em projetos anteriores. Isso reduz os custos do projeto, visto que na reutilização são aproveitados objetos já implementados e validados. 
Classes 
Uma classe é a especificação para a criação de um objeto, ou seja, uma classe fornece a estrutura necessária para que um objeto possa ser criado. Sendo assim, ela descreve as propriedades e funcionalidades de um objeto em forma de atributos e métodos. 
Além dos atributos e métodos, uma classe pode possuir classes aninhadas. Uma classe aninhada ou interna é uma classe declarada dentro de outra classe. 
Vale ressaltar que uma declaração de classe cria um tipo. Em Java a declaração de uma classe não cria um objeto. Os objetos devem ser explicitamente criados. Sendo assim, é correto afirmar que uma classe é o projeto de um objeto. Este projeto possui como objetivo orientar a JVM na criação de um objeto. Cada objeto criado possui valores próprios para os atributos da classe. 
Na notação UML, uma classe é representada como um retângulo vertical com três seções. O
Orientação a objetos Rosicléia Frasson 
25 
nome da classe do objeto está na seção superior, os atributos da classe estão na seção intermediária e as operações associadas a classe estão na seção inferior do retângulo. 
Em Java, uma classe é definida utilizando a palavra chave class. Após a palavra chave class, deve seguir o nome da classe, que deve ser um identificador válido. Os membros de uma classe - atributos, métodos e classes aninhadas - são listados entre as chaves após a declaração. 
Na declaração de uma classe também é informado o modificador de acesso. O modificador public indica que a classe é publicamente acessível, ou seja, outras classes podem declarar referências a objetos da classe e acessar seus membros public. 
Para nomear classes por convenção devem ser usados substantivos. A primeira letra deve ser maiúscula. Na concatenação de palavras a primeira letra de cada palavra deve ser maiúscula. Um outro cuidado é que o nome de uma classe deve descrever o que ela faz. 
Atributos 
Na definição de classes foi descrito que uma classe possui propriedades que determinam o estado de um objeto. Essas propriedades de uma classe são denominadas atributos ou variáveis de instância. Uma variável de instância possui valores distintos para cada objeto criado. 
Uma declaração de atributo é composta pelo tipo do atributo, que pode ser um tipo primitivo ou um objeto, seguido por um identificador e opcionalmente uma claúsula de inicialização que fornece ao atributo um valor inicial. Vale ressaltar que se o atributo não possuir um valor inicial explicitamente declarado, um valor inicial padrão é atribuído. Para tipos numéricos o valor padrão é 0, para booleanos o valor padrão é false e para objetos é null.
Orientação a objetos Rosicléia Frasson 
26 
Um ponto crucial para a criação de atributos significativos para o objeto é um estudo do escopo do problema que o software deve resolver. 
Métodos 
Dentro da POO, os métodos representam o mecanismo de comunicação entre os objetos. A troca de informações entre os objetos é feita através de parâmetros e valores de retorno dos métodos. Além disso, um método pode mudar o estado do objeto, ou seja, um método pode alterar o valor de um ou mais atributos que estão contidos no objeto. 
Uma declaração de um método é composta de duas partes: cabeçalho e corpo do método. No corpo do método fica o código executável que possui a função de manipular os dados armazenados nos objetos. Já o cabeçalho do método é composto por um conjunto opcional de modificadores, o tipo de retorno do método, a assinatura do método e uma claúsula throws opcional que relaciona as exceções lançadas pelo método. 
A assinatura de um método consiste no nome do método e na lista de parâmetros entre parênteses, que pode ser vazia. Obrigatoriamente todos os métodos devem possuir uma assinatura e um tipo de retorno. 
Os métodos que não possuem retorno usam a palavra chave void como tipo de retorno. Métodos void não retornam nenhuma informação para a classe que o chamou. Para os métodos com retorno, é utilizado o tipo de retorno que pode ser um tipo primitivo ou uma classe Java. Os métodos com retorno podem retornar apenas um único resultado, seja um valor primitivo ou a referência a um objeto. 
O fato de um método possuir retorno ou não, altera o encerramento da execução. Quando um método não possui valor de retorno, a execução é encerrada quando o bloco do corpo do método chega ao final. Já quando o método possui valor de retorno, a execução é encerrada através do comando return.
Orientação a objetos Rosicléia Frasson 
27 
Os métodos podem receber argumentos representados por uma lista de parâmetros separados por vírgula, onde para cada parâmetro é indicado o tipo e o nome. Todos os parâmetros de métodos são passados por valor, independente de serem tipos primitivos ou objetos. Parâmetros do tipo objeto passam a referência ao objeto e não o próprio objeto. Dessa forma, se o estado do objeto for alterado durante a execução do método, o objeto é alterado para cada parte do programa que possui uma referência para ele. 
Vale ressaltar que um parâmetro de um método é uma variável local. Isso significa que ao fim da execução do método ela deixa de existir. 
Para serem executados os métodos devem ser invocados. Métodos são invocados como operações sobre objetos através de referências. Os métodos com parâmetros quando invocados, obrigam o invocador a fornecer um argumento do tipo apropriado para cada um dos parâmetros declarados pelo método. 
referencia.método (argumentos); 
Quando um método é invocado, o fluxo de execução passa para o método invocado e os comandos deste são executados em sequência. Um método retorna ao invocador em uma das três condições: a execução de um comando return, o bloco de execução acaba nos casos dos métodos void ou uma exceção não capturada é lançada. 
Sobrecarga de métodos 
A sobrecarga de métodos ou overloading é o mecanismo que permite a criação de vários métodos com o mesmo nome, mas com possibilidades de entradas diferentes. Essas entradas que consistem nos parâmetros dos métodos devem ser tipos diferentes, quantidade de parâmetros distintas
Orientação a objetos Rosicléia Frasson 
28 
ou posições de tipos diferentes. 
A sobrecarga é comumente utilizada quando é necessário criar métodos que realizem as mesmas tarefas, porém com tipos de dados diferentes ou números distintos de argumentos. 
O compilador distingue os métodos sobrecarregados pela sua assinatura, sendo assim, não é possível declarar métodos com a mesma assinatura e tipos de retorno distintos, pois no momento da invocação do método, o compilador não seria capaz de determinar a versão do método a ser chamada porque o valor de retorno é ignorado. 
A API do Java contempla uma série de métodos sobrecarregados, um bom exemplo é o método max da classe Math, que possui quatro métodos sobrecarregados que possuem como objetivo retornar o maior valor de dois números. 
Métodos da classe Object 
Em Java todos os objetos derivam da classe Object. A classe Object possui uma série de métodos que podem ser utilizados pelas classes criadas. Dentre eles, os mais importantes são: 
● toString 
O método toString possui como objetivo retornar a representação String de um objeto, ou seja, retorna uma String que textualmente representa esse objeto. Este método é chamado automaticamente quando um objeto é passado para print ou para um operador de concatenação de Strings. O método toString de Object retorna a String com o package, o nome da classe, o caracter @ e um número de identidade em hexadecimal. 
br.com.rosicleiafrasson.oo.Produto@58c3d9ac
Orientação a objetos Rosicléia Frasson 
29 
Para retornar informações mais concisas sobre o objeto, o toString pode ser reescrito. 
public String toString() { 
return "Produto " 
+ "nCódigo: " + codigo 
+ "nNome: " + nome 
+ "nPreço: " + preco ; 
} 
● getClass 
O método getClass retorna informações do objeto como o package e o nome da classe. 
● equals 
O método equals faz a comparação entre dois objetos e retorna o valor true se ambos ocuparem o mesmo espaço de memória. O método equals pode ser reescrito para que outros critérios de comparação sejam utilizados. 
Métodos com um número variável de parâmetros 
A partir do Java 5, os métodos podem ser construídos com uma quantidade variável de parâmetros. Tais métodos são chamados de varargs. 
Na declaração de um método varargs, o último parâmetro é declarado como uma sequência de um dado tipo. Para indicar que um parâmetro é uma sequência são colocadas reticências (...) após o tipo do parâmetro. Os parâmetros de sequência permitem que a invocação do método tenha um número variável de argumentos, incluindo zero. 
Quando um parâmetro é declarado como uma sequência, o compilador constrói implicitamente um array e adiciona neste os elementos passados como argumento. Apenas um parâmetro de sequência é permitido por método. 
public double calculaValorVenda (double ... precosProdutos){ 
double valorTotal = 0; 
for (double preco : precosProdutos) { 
valorTotal += preco; 
} 
return valorTotal; 
} 
Quando um parâmetro é declarado como uma sequência, o compilador constrói um array do tipo especificado pelo parâmetro de sequência e armazena os argumentos passados nesse array. 
Instâncias de classes 
Uma classe é a especificação de um objeto. No entanto, para ser criado, um objeto precisa ser instanciado. Quando um objeto é criado, ele adquire espaço em memória para armazenar seu estado e um conjunto de operações podem ser aplicadas ao mesmo. Sendo assim, para atribuir valores a quaisquer atributos e invocar métodos é necessária a instanciação de um objeto da refererida classe. 
A maneira mais comum de instanciar um objeto é através da palavra chave new. Para a criação
Orientação a objetos Rosicléia Frasson 
30 
de um objeto através do comando new, é necessário especificar o tipo de objeto que deve ser criado e os argumentos da sua construção. 
O new aloca espaço para armazenar os campos do objeto e os inicializa. Quando a inicialização está completa, o sistema de execução retorna uma referência ao novo objeto. É importante ressaltar que no momento da alocação se o sistema não encontra espaço suficiente para criar o objeto, ele efetua uma coleta de lixo para tentar recuperar espaço. Após a coleta se não existir espaço livre, é lançada uma exceção: OutOfMemoryError. 
Construtores 
Quando a palavra chave new é utilizada, um objeto é construído. A palavra chave new executa o construtor da classe. Construtores são blocos de código que são usados para inicializar um objeto, antes que a referência seja retornada por new. 
Um construtor é um bloco declarado com o mesmo nome da classe seguido por uma lista de parâmetros entre parênteses. Os argumentos passados ao construtor podem inicializar informações. Sendo assim, os construtores podem obrigar a passagem de argumentos para o objeto durante o processo de criação do mesmo. Vale ressaltar que o construtor é invocado após os atributos terem sido configurados com seus valores iniciais default. Um construtor não possui valor de retorno.
Orientação a objetos Rosicléia Frasson 
31 
Em uma classe em que não existe um construtor declarado, a JVM cria implicitamente um construtor default. O construtor default não recebe nenhum argumento e seu corpo é vazio. A partir do momento em que um construtor é declarado, o construtor default deixa de ser fornecido. 
Uma classe pode ter mais de um construtor. Desde que a lista de argumentos seja diferente. Neste caso, no momento da instanciação do objeto é necessário escolher o construtor apropriado. Um construtor pode invocar outro construtor da mesma classe usando a invocação this() como seu primeiro comando executável. Se o construtor a ser invocado possui argumentos, os mesmos podem ser passados na invocação do construtor. O construtor invocado é determinado pela quantidade e tipo de argumentos usados. 
Palavra chave this 
A palavra chave this é usada para passar uma referência ao objeto atual. Comumente é usada quando o nome do campo a ser acessado é o mesmo nome de uma variável local ou parâmetro.
Orientação a objetos Rosicléia Frasson 
32 
O this permite uma diferenciação entre atributos e parâmetros de métodos. Dessa forma, é possível ter o mesmo identificador para uma variável de instância e um parâmetro de método. Essa prática tende a deixar o código mais legível e amigável. 
Atributos estáticos 
Os atributos estáticos consistem em campos pertencentes as classes, ou seja, não existe uma cópia do atributo para cada objeto. Sendo asssim, todos os objetos compartilham a mesma cópia da variável. Um campo estático deve ser declarado com o modificado static. 
Variáveis estáticas possuem escopo de classe. Sendo assim, elas podem ser acessadas por meio de uma referência a qualquer objeto da classe ou pelo nome da classe, seguido pelo atributo. 
As variáveis estáticas são inicializadas quando uma classe é carregada. Uma classe é carregada pela JVM quando uma instância da mesma é criada pela primeira vez ou quando uma variável ou método estático é utilizado. Vale mencionar que as variáveis estáticas são inicializadas antes que qualquer objeto da classe possa ser criado e antes de qualquer método estático da classe ser executado.
Orientação a objetos Rosicléia Frasson 
33 
Métodos estáticos 
Os métodos estáticos realizam procedimentos sem estarem vinculados a um objeto. Sendo assim, eles pertencem a uma classe e não a uma instância da mesma. Em outras palavras, um método estático pode ser executado sem a existência de uma instância da classe a que pertence. 
Os métodos estáticos só podem realizar operações sobre atributos estáticos, isto é, para a sua execução nenhuma instância específica da classe pode ser utilizada. Sendo assim, métodos estáticos também não podem utilizar métodos não estáticos. Métodos estáticos são adequados para métodos utilitários que não dependam do valor de uma variável de instância específica. 
Como exemplo de método estático da classe Java pode ser citado o método showMessageDialog da classe JOptionPane. É importante perceber que para utilizar o mesmo, não é necessária nenhuma instância da classe JOptionPane. 
Classe Math 
A classe Math é constituída por uma série de métodos estáticos para operações matemáticas,
Orientação a objetos Rosicléia Frasson 
34 
entre elas potências, raízes, logaritmos, arredondamentos e operações trigonométricas. Além disso possui duas constantes, o PI e E. 
Por pertencer ao pacote java.lang não precisa ser instanciada. Seguem alguns métodos disponíveis na classe: 
● Math.PI - Constante PI 
● Math.pow(a, b) - Potência na forma ab 
● Math.sqrt(a) - Raiz quadrada de a 
● Math.cbrt(a) - Raiz cúbica de a 
● Math.abs(a) - Retorna o valor absoluto de a 
● Math.min(a, b) - Retorna o menor valor 
● Math.max(a, b) - Retorna o maior valor 
● Math.ceil(a) - Arredonda para cima 
● Math.floor(a) - Arrenda para baixo 
Campo final 
Um campo final não pode ter seu valor alterado após ter sido inicializado. Sendo assim, ele é usado para definir uma propriedade imutável dentro de uma classe ou objeto. Na maioria dos casos os campos final são também campos estáticos. Isso significa que todos os objetos da classe compartilham um valor imutável. 
Por convenção os identificadores dos campos final devem possuir todas as letras maiúsculas. Nos casos de palavras compostas, as mesmas devem ser separadas pelo caractere underscore. 
Enum 
Em Java, um Enum é um tipo especial de classe que corresponde a um conjunto fixo de constantes. Os Enums deixam o código menos vulnerável a erros de programação e mais legível. 
A declaração de uma enumeração é similar a declaração de uma classe, exceto que ao invés da palavra chave class, é utilizada a palavra chave enum. Outra particularidade é que antes de declarar qualquer membro da classe, é necessário declarar todas as constantes de enumeração. Seguindo a convenção de constantes, o identificador é escrito com todas as letras em maiúsculas.
Orientação a objetos Rosicléia Frasson 
35 
Agregação e composição 
Em um sistema orientado a objetos, é necessário que existam relacionamentos entre as classes. Para a UML, existem diversos relacionamentos possíveis. Entre eles, agregação e composição. 
Agregação é uma especialização da associação e indica que uma classe é parte de um todo. Ainda, que a parte pode existir sem o todo. Como exemplo pode ser citado o relacionamento entre um cargo e um funcionário. Se o funcionário deixar de existir, o cargo pode ser usado por um outro funcionário. Na UML, a agregação é representada por uma linha sólida com um losango vazio na extremidade que representa o todo. 
A composição é similar a agregação. No entanto, na composição a parte existe somente enquanto o todo existir. Como exemplo pode ser citada a relação que existe entre um pedido e os itens que estão contidos nesse pedido. Se o pedido deixar de existir, os itens relacionados a ele não fazem mais sentido. Na UML, a composição é representada por uma linha sólida com um losango preenchido na extremidade que representa o todo. 
Tanto a composição quanto a agregação são relacionamentos do tipo TEM UM. Na definição de classes Java, os dois relacionamentos se comportam da mesma maneira. Uma classe possui como um tipo de atributo uma outra classe.
Orientação a objetos Rosicléia Frasson 
36 
Encapsulamento 
O encapsulamento consiste em ocultar dados e implementações da classe. Em outras palavras, membros de uma classe podem ser escondidos de forma a prever acessos indevidos. A orientação a objetos recomenda que o estado de um objeto deve ser mantido oculto. Os objetos devem ser manipulados apenas através de métodos públicos, dos quais apenas as assinaturas devem ser expostas. Vale ressaltar que apenas os métodos que são importantes para as classes externas devem ser visíveis. 
A utilização do encapsulamento protege as classes cliente contra os efeitos de uma alteração. Isso é possível porque o cliente conhece apenas a assinatura do método. Sendo assim, a implementação do mesmo pode ser alterada sem que nenhuma modificação na assinatura seja necessária. 
Outro ponto, é que o estado do objeto fica protegido contra modificações inválidas feitas pelas classes clientes. Visto que o estado só pode ser alterado através de métodos, é possível incluir validadores de dados nesses métodos ou lançar um erro ao cliente no caso de valores indevidos. 
Modificadores de acesso 
A restrição de acesso a classes e a membros da mesma é parte fundamental da orientação a objetos. Sendo assim, faz-se necessário um meio para restringir o acesso a classes e membros desta. 
Em Java, são utilizados os modificadores de acesso para controlar a visibilidade de classes, construtores, atributos e métodos. Existem quatro modificadores de acesso: private, default, protected e public.
Orientação a objetos Rosicléia Frasson 
37 
O modificador public indica que a classe ou o membro pode ser acessado em qualquer parte do programa. Este modificador deve ser utilizado para construtores e métodos que devem ser acessados por outras classes. Também pode ser usado em métodos e constantes estáticas. Construtores e métodos de uso restrito e campos de dados de objetos não devem utilizar public como modificador. 
O modificador protected deixa os membros acessíveis a subclasses e classes do mesmo pacote. 
A ausência de um modificado de acesso, constitui o chamado modificador default. Este modificador deixa o membro acessível a classes do mesmo pacote. Classes cosntruídas com a ausência de modificador só podem ser instanciadas no pacote a que pertencem. O mesmo vale para os demais membros. 
Por fim, o modificador private deixa os membros acessíveis somente dentro da própria classe. Este modificador deve ser utilizado em atributos de classes, construtores e métodos que não devem ser acessados por outras classes. 
Gets e sets 
A visibilidade dos atributos pode ser restrita se aplicados os modificadores de acesso aos mesmos. No caso de um atributo com modificador private, os atributos só são acessíveis na própria classe. Isso significa que o estado das propriedades só pode ser alterado através de métodos públicos. 
Existe uma convenção para a criação de métodos que possuem como objetivo alterar ou recuperar o valor de uma propriedade com visiblidade restrita. 
Os métodos que possuem como objetivo alterar o valor da propriedade são chamados de métodos sets. Os métodos sets não retornam nenhum valor, portanto são métodos void. No entanto,
Orientação a objetos Rosicléia Frasson 
38 
eles devem receber obrigatoriamente um argumento, que corresponde ao valor atribuído ao campo. 
Já os métodos que recuperam um valor são chamados de métodos gets. Os métodos gets obrigatoriamente possuem valor de retorno e não possuem argumentos. 
Herança 
O mecanismo de herança permite uma hierarquia entre classes. Sendo assim, novas classes podem ser criadas a partir de outras classes já existentes. As subclasses herdam as características e comportamentos das superclasses. Isto significa que a herança viabiliza o reúso de código. 
Normalmente, uma subclasse além de herdar membros da superclasse, também possui seus próprios atributos e métodos. Sendo assim, uma subclasse é mais específica que a sua superclasse, representando deste modo, um grupo mais especializado de objetos. 
As novas classes são chamadas de subclasses e as classes já existentes que deram origem as subclasses são chamadas de superclasses. Uma subclasse pode se tornar superclasse para outras subclasses. Ou seja, a herança pode ter vários níveis de hierarquia. 
Vale ressaltar que a herança é um relacionamento do tipo É UM. Sendo assim, um objeto de uma subclasse pode ser tratado como um objeto da superclasse.
Orientação a objetos Rosicléia Frasson 
39 
A nível de codificação, a herança é implementada utilizando a palavra chave extends, seguida do nome da superclasse. Quando a máquina virtual cria um novo objeto que faz uso de herança, são definidas todas as variáveis pertencentes a classe e também as variáveis que estão definidas na superclasse. Quanto aos métodos, o objeto criado possui todos os métodos de sua classe e superclasse. Sempre que um método é chamado, a JVM verifica a classe do objeto; se o método não for encontrado, a JVM procura na superclasse dessa classe e assim sucessivamente até que o método seja encontrado. 
A referência aos métodos da superclasse é feita através da palavra-chave super. Para a chamada de métodos da superclasse, é utilizada a palavra chave super seguida do nome do método. O comando super também é utilizado para invocar um construtor da superclasse. Neste caso, é utilizada apenas a palavra super(), com os aurgumentos relativos ao construtor que deve ser invocado. 
public class Fabricante extends PessoaJuridica{ 
public Fabricante() { 
super(); 
} 
}
Orientação a objetos Rosicléia Frasson 
40 
No Java a hierarquia de classes é iniciada com a classe Object, do pacote java.lang. Em outras palavras, implicitamente todas as classes extendem de Object e herdam os métodos desta superclasse. Por este motivo, todos os objetos criados possuem os métodos equals, toString, clone, getClass e hashCode. 
Diferente de outras linguagens, o Java não suporta herança múltipla. A herança múltipla permite que uma classe herde de mais de uma superclasse. 
Sobrescrita de métodos 
A sobrescrita de métodos ou overriding é o mecanismo que permite a alteração do comportamento de uma superclasse pelas suas subclasses, ou seja, a sobrescrita de um método é uma nova implementação para o mesmo. A sobrescrita de um método ocorre somente se a assinatura do mesmo permanece intacta, isto é, o tipo de retorno e os parâmetros devem ser os mesmos. 
A procura pelos métodos tem início no fim da hierarquia. Isso significa que quando um método é sobrescrito, a JVM executa o método definido na subclasse. Um exemplo clássico de overriding é a sobrescrita do método toString da classe Object por outras classes. 
Vale ressaltar que os métodos sobrepostos nunca devem ser mais restritivos do que os métodos originais. Isto significa que: 
● Se o método original for public, a sobrescrita deste método obrigatoriamente terá modificador de acesso public; 
● Se o método original for protected, a sobrescrita deste pode ser protected ou public; 
● Se o método original não possuir modificador de acesso, a sobrescrita pode não possuir modificador, ser protected ou public; 
● Se um método for private, ele não é visível pela subclasse, sendo assim, não pode ser sobrescrito. 
Modificador final 
O modificador final quando usado em uma declaração de classe impede que a mesma seja extendida. Muitas classes das API Java são final, como a classe String e a classe Math. Isso significa que é impossível extender as classes String e Math.
Orientação a objetos Rosicléia Frasson 
41 
Classes devem ser marcadas como final para garantir que subclasses não sejam criadas a partir da mesma. Sendo assim, o modificador final deve ser usado apenas quando a classe já possuir todos os métodos implementados e nunca será necessário implementar um comportamento específico. 
Um método também pode possuir o modificador final. Neste caso, o método não pode ser sobrescrito pelas subclasses. O modificador final garante segurança a métodos não podem ser sobrescritos. 
Polimorfismo 
A herança e o polimorfismo em Java estão intimamente ligados. O polimorfismo em Java é o mecanismo que garante que quando um método é invocado por meio de uma referência a superclasse, em tempo de execução, a versão correta do método da subclasse é executada. Sendo assim, o polimorfismo garante que objetos de múltiplos tipos sejam referenciados como se fossem do tipo de sua superclasse. 
Em outras palavras, o polimorfismo permite que hierarquias inteiras sejam referenciadas a partir do tipo da superclasse. Sendo assim, um método que recebe como parâmetro o tipo Object, pode receber como argumento qualquer tipo de objeto, visto que em Java todas as classes extendem de Object. 
Classe abstrata 
Uma classe abstrata constitui uma classe que não pode ser instanciada. Classes são marcadas como abstratas ficam no topo ou nos níveis próximos ao topo da hierarquia e servem como modelo para as classes concretas. Sendo assim, as classes abstratas para serem utilizadas precisam herdadas por classes concretas. 
Uma classe abstrata pode conter métodos com sua implementação definida, os métodos concretos; e métodos que contenham apenas a assinatura, que são chamados de métodos abstratos.
Orientação a objetos Rosicléia Frasson 
42 
Quando uma subclasse herda uma classe abstrata, obrigatoriamente todos os métodos abstratos devem ser sobrescritos, pois os mesmos não possuem implementação na superclasse. Uma classe abstrata pode ser extendida por outra classe abstrata. Dessa forma, a implementação dos métodos abstratos podem ser postergados para os níveis mais baixos da hierarquia. 
Na notação UML, o nome de uma classe abstrata é escrito em itálico. A mesma formatação também é aplicada para os métodos abstratos.
Orientação a objetos Rosicléia Frasson 
43 
Interface 
Uma interface, assim como uma classe abstrata, possui como propósito forçar uma subclasse a reescrever todos os métodos abstratos, definindo um comportamento para eles. No entanto, as interfaces não possuem métodos concretos, apenas abstratos. Uma interface também não possui atributos, apenas constantes e variáveis estáticas. Uma interface não possui construtores. 
Os métodos declarados em uma interface devem ser implementados em todas as classes que implementam a interface. A implementação de uma interface por uma classe indica um relacionamento do tipo É UM com a interface. Uma classe pode implementar mais de uma interface. 
Uma interface pode estender outra interface. Se uma interface estendida por outra, for implementada por uma subclasse, esta última deverá implementar todos os métodos abstratos definidos nas duas interfaces.
Orientação a objetos Rosicléia Frasson 
44 
Classes Wrappers 
As classes Wrappers fornecem um mecanismo para empacotar valores primitivos em um tipo objeto, para que estes sejam inclusos em atividades reservadas a objetos. Além disso, estas classes fornecem um conjunto de funções utilitárias para os tipos primitivos, como a conversão de um tipo primitivo em String e vice-versa. 
Com exceção da classe Character, as classes wrappers possuem dois construtores: um que recebe o tipo primitivo como argumento e outro que recebe uma String como argumento. 
Double d1 = new Double(1.0); 
Double d2 = new Double("1.0"); 
Integer i1 = new Integer(3); 
Integer i2 = new Integer("6"); 
As classes Wrappers fornecem métodos para conversão de uma String em um tipo primitivo correspondente. 
● Boolean.parseBoolean; 
● Byte.parseByte; 
● Short.parseShort; 
● Integer.parseInt; 
● Long.parseLong; 
● Float.parseFloat; 
● Double.parseDouble; 
As classes wrappers também fornecem um método que retorna o tipo primitivo por ela encapsulado. Para efetuar essa conversão existem os métodos intValue, doubleValue, floatValue, booleanValue, byteValue, shortValue e longValue. Embora a partir do Java 5, existe o recurso de autoboxing que efetua o desencaixotamento de forma automática. 
Integer a = new Integer(12); 
int b = a.intValue(); 
Exceções 
Na linguagem de programação Java e na grande maioria das linguagens de programação, os métodos invocados são empilhados em uma estrutura de dados. Isso significa que quando um método termina a sua execução, o fluxo do programa volta para o método que o invocou, ou seja, o próximo
Orientação a objetos Rosicléia Frasson 
45 
elemento da pilha. Caso aconteça alguma situação inesperada durante a execução do método, a JVM verifica se existe algum tratamento para o erro e em caso negativo, faz uma varredura nos métodos da pilha em busca de um tratamento para o problema. A inexistência de um tratamento para o erro gerado faz com que o programa seja encerrado. 
O mecanismo da linguagem Java relativo a exceções é baseado no conceito que as exceções são lançadas e capturadas. Quando uma exceção ocorre um objeto do tipo Exception é criado e lançado dentro do método. Se o método não capturar a exceção a mesma é passada para o invocador. Isso acontece sucessivamente até que a exceção seja capturada ou chegue na JVM, onde é capturada automaticamente. O trabalho com exceções se resume a decidir onde as exceções serão capturadas e como será o tratamento da mesma.
Orientação a objetos Rosicléia Frasson 
46 
Todas as exceções herdam direta ou indiretamente da classe Throwable, formando uma hierarquia de herança. 
Como todas as exceções descendem de Throwable, todas herdam os métodos desta superclasse. Seguem os mais utilizados: Método Descrição 
getMessage 
Retorna uma descrição para a exceção. 
printStackTrace 
Exibe o rastreamento da pilha. 
toString 
Retorna um objeto String contendo uma descrição completa da exceção. 
Na hierarquia de exceções exibida anteriormente, pode ser observado que a classe Throwable possui as subclasses Error e Exception. As classes derivadas de Error representam situações graves durante a execução do programa e que não podem ser tratados pelo programador, como por exemplo, a JVM ficar sem espaço na memória. Geralmente os programas não conseguem se recuperar de um Error, sendo assim, não é necessário codificar um tratamento para o mesmo. 
A classe Exception e suas subclasses representam situações excepcionais que podem ser capturadas pelo aplicativo. Consequentemente podem ser tratadas. Dentro das exceptions ainda existem as exceções checadas e não checadas. 
As exceções que são instâncias ou subclasses da classe RuntimeException refletem erros na lógica do programa e não são verificadas pelo compilador. Isso significa que pode haver um tratamento para o erro, no entanto, não existe a obrigatoriedade desse tratamento. As exceções não checadas mais comuns são: 
● ArithmeticException: Indica situações de erro em processamentos aritméticos. 
● NumberFormatException: Exceção lançada na tentativa de converter uma String em um valor numérico, onde o conteúdo da mesma não representa um número adequado para o formato. 
● ArrayIndexOutOfBoundsException: Indica a tentativa de acesso a um elemento de um array fora dos limites válidos. 
● NullPointerException: Indica a tentativa de acessar a referência a um objeto que não foi criado. 
Já as exceções verificadas compreendem as classes derivadas de Exception e que não derivam de RuntimeException. Essas exceções necessariamente precisam ser tratadas e normalmente são
Orientação a objetos Rosicléia Frasson 
47 
causadas por condições que não estão no controle do programa, como uma falha de conexão de rede ou uma resposta de um outro aplicativo. 
As exceções verificadas precisam ser tratadas. O tratamento de uma exceção através do bloco try catch. Dentro do bloco try são colocados os comandos que podem gerar uma exceção. O bloco try deve ser seguido por um ou mais blocos catch e/ou um bloco finally. Vale ressaltar que um método pode lançar várias exceções. Neste caso, todas as exceções que eventualmente possam ser lançadas devem ser tratadas. 
Nos blocos catch são capturadas as exceções. Cada bloco catch define o tipo de exceção que pode tratar. Vários blocos catch podem ser definidos para um mesmo bloco try. No entanto, apenas um será executado. O tipo de exceção deve coincidir com o tipo especificado em uma instrução catch. Se não coincidir a exceção não será capturada. 
A captura de uma exceção impede que o programa seja encerrado anormalmente. Quando uma exceção é lançada ela deve ser capturada e tratada em alguma parte do código fonte. Quando um programa não captura a exceção, a mesma é tratada pela JVM. O tratador de exceções padrão da JVM apenas encerra a execução e exibe uma mensagem de erro seguida por uma lista das chamadas de métodos que levaram a exceção. 
O bloco finally contém instruções que sempre serão executadas, independente de uma exceção ser lançada pelo try . Geralmente esse bloco possui instruções que liberam recursos utilizados durante o processamento do bloco try precisam ser liberados, independente da execução ter encerrado com
Orientação a objetos Rosicléia Frasson 
48 
sucesso ou ter sido interrompida por uma exceção. O bloco finally será executado mesmo que exista um comando return no bloco try. Normalmente esse bloco é indicado para o fechamento de arquivos e operações de limpeza. 
A cláusula throws é utilizada para propagar a exceção para um nível acima na pilha de execução. Na cláusula throws são especificadas as exceções que o método pode lançar, porém não serão tratadas dentro do mesmo. Essa cláusula aparece após a lista de parâmetros e antes do corpo do método. Ela contém a lista de exceções que o método pode lançar caso algum problema ocorra em tempo de execução. 
Em Java, é possível que uma aplicação defina seu próprio tipo de exceção. Para criar um novo tipo de exceção é necessário que a classe extenda de uma das classes da hierarquia de exceções. O comando throw lança uma exceção manualmente.
Collections Rosicléia Frasson 
49 
Collections 
Uma coleção é um objeto onde vários elementos podem ser agrupados. Em java, existe uma arquitetura para representar e armazenar as coleções. 
Essa arquitetura e composta por interfaces e classes concretas com uma série de métodos que realizam operações como inserção, remoção, pesquisa e ordenação dos elementos de uma coleção. 
List 
A interface List é responsável por armazenar elementos em forma de lista. Uma lista permite elementos duplicados e mantém os mesmos na ordem em que foram inseridos. A interface List resolve alguns problemas do array como tamanho infinito e métodos para inserção e pesquisa. 
A interface List possui as implementações ArrayList, LinkedList e Vector. 
ArrayList<String> arrayList = new ArrayList(); 
LinkedList<String> linkedList = new LinkedList(); 
Vector<String> vector = new Vector(); 
A interface List possui uma série de métodos. Seguem os mais utilizados:
Collections Rosicléia Frasson 
50 
● add: O método add adiciona no fim da lista um elemento. 
● size: O método size retorna a quantidade de elementos que a lista possui. 
● remove: O método remove retira um elemento da lista. 
● contains: O método constains verifica se um elemento está na lista. 
● sort: O método sort recebe um List como argumento e ordena em ordem crescente. Para efetuar a ordenação um objeto precisa implementar a interface Comparable que define o método compareTo. 
● min: Retorna o menor elemento da coleção. 
● reverse: O método reverse inverte a lista. 
Set 
Um conjunto Set não permite elementos duplicados. Os elementos possuem uma forma especial de ordenação. A interface Set deve ser utilizada quando a ordem dos elementos não é importante, visto que performance é muito superior a List. 
Collection<Integer> colecao = new HashSet<Integer>(); 
long tempoInicial = System.currentTimeMillis(); 
for (int i = 0; i < 10000000; i++) { 
colecao.add(i); 
} 
for (int i = 0; i < 10000000; i++) {
Collections Rosicléia Frasson 
51 
colecao.contains(i); 
} 
long tempoFinal = System.currentTimeMillis(); 
System.out.printf("Tempo em milisegundos: ", (tempoFinal - tempoInicial));
Conexão com a base de dados JDBC Rosicléia Frasson 
52 
Conexão com a base de dados 
As bases de dados estão presentes em nossa sociedade há muito tempo e correspondem a um conjunto de dados inter relacionados referentes a um determinado domínio. Antes dos advento dos computadores, as empresas armazenavam seus dados em arquivos físicos. Com a popularização da informática, esses dados passaram a ser armazenados em softwares específicos para este fim. A estes softwares damos o nome de SGBD. Um Sistema Gerenciador de Banco de Dados possui um ambiente adequado e eficiente para armazenamento e recuperação de dados. 
Modelo Entidade-Relacionamento 
O modelo entidade-relacionamento é composto por atributos, entidades compostas pelos atributos e o relacionamento entre as entidades. 
Entidades : São objetos do mundo real dentro do domínio da aplicação, que possuem informações necessárias para armazenamento na base de dados. A entidade é representada por um retângulo que contém o nome da entidade. 
Atributos: São as propriedades que descrevem as entidades. Poderiam ser atributos da entidade livro, por exemplo, o título, autor, edição, ano de publicação e a editora. 
Chaves: São atributos ou conjuntos de atributos que permitem identificar sem ambiguidade cada instância de uma entidade, ou seja, garante a distinção entre as ocorrências das entidades. 
Relacionamentos: São associações entre duas entidades ou entre uma entidade e ela mesma. O relacionamento é representado por um losango. Esse losango é ligado por linhas aos retângulos que representam as entidades participantes do relacionamento.
Conexão com a base de dados JDBC Rosicléia Frasson 
53 
Tipos de relacionamento: Existem três tipos de relacionamento entre as entidades. 
● um para um: é usado quando uma entidade A, se relaciona com uma entidade B e vice-versa. Este relacionamento é representado pelo sinal 1:1. 
● um para muitos: é usado quando uma entidade A pode se relacionar com uma ou mais entidades B. Este relacionamento é representado pelo sinal 1:N. 
● muitos para muitos: é usado quando várias entidades A se relacionam com várias entidades B. Este relacionamento é representado pelo sinal N:M ou N:N. 
Modelo Relacional 
O modelo relacional representa os dados em uma base de dados como uma coleção de tabelas (relações). Todas as tabelas possuem um nome e um conjunto de atributos com seus respectivos nome e domínios. 
Tabela: É onde as informações ficam armazenadas. 
Atributos: São todas as informações que existem em uma tabela. Essas informações também são chamadas de campos. 
Domínio: Representa todos os valores possíveis que um atributo pode receber. 
Tuplas: Representam as informações armazenadas em uma tabela. Informalmente as tuplas são chamadas de registros. 
Chave primária: É uma coluna ou um conjunto de colunas cujos valores distinguem uma linha
Conexão com a base de dados JDBC Rosicléia Frasson 
54 
das demais dentro da tabela. 
Chave estrangeira: É uma coluna ou uma combinação de colunas, cujos valores aparecem necessariamente na chave primária de uma tabela. A chave estrangeira permite a implementação dos relacionamentos em um banco de dados. 
Exemplo Supermercado 
Linguagem SQL 
A linguagem SQL - Structured Query Language - é a linguagem padrão utilizada para gerenciar a base de dados. O SQL é uma linguagem padrão para a grande maioria das bases de dados, embora existam algumas variações entre fabricantes diferentes de SGBDs. A linguagem SQL está subdividida em duas linguagens: DML e DDL. 
Os comandos contidos neste documento são baseados no SGBD da Oracle. 
DDL 
A linguagem DDL - Data Definition Language - é composta por comandos usados para alterar a estrutura da base de dados. Em outras palavras, comandos para inserir, atualizar e apagar a estrutura da base de dados. Seguem os comandos mais utilizados: 
CREATE TABLE 
É o comando utilizado para criar uma tabela na base de dados. As tabelas são organizadas por linhas e colunas. As tabelas e as colunas da mesma devem possuir um identificador. 
CREATE TABLE nome_tabela ( 
nome_coluna1 tipo_dado (tamanho), 
nome_coluna2 tipo_dado (tamanho), 
nome_coluna3 tipo_dado (tamanho), 
.... 
);
Conexão com a base de dados JDBC Rosicléia Frasson 
55 
ALTER TABLE 
Comando utilizado para adicionar, remover ou alterar uma coluna de uma tabela. 
● Para adicionar uma coluna: 
ALTER TABLE nome_tabela ADD nome_coluna tipo_dado; 
● Para remover uma coluna: 
ALTER TABLE nome_tabela DROP COLUMN nome_coluna; 
● Para editar uma coluna: 
ALTER TABLE nome_tabela MODIFY COLUMN nome_coluna tipo_dado; 
DROP TABLE 
Comando que elimina todos os dados e a estrutura da tabela. 
DROP TABLE nome_tabela; 
RENAME 
Comando utilizado para renomear uma tabela ou sequência. 
DROP TABLE nome_tabela; 
NOT NULL 
Garante a não existência de valores nulos para a coluna. Deve ser definido para cada coluna. 
UNIQUE 
A restrição unique bloqueia a possibilidade de registros repetidos para uma coluna, ou seja, garante que todos os valores de uma coluna sejam diferentes.
Conexão com a base de dados JDBC Rosicléia Frasson 
56 
PRIMARY KEY 
Uma primary key é utilizada para identificar de forma única cada linha em uma tabela. A coluna referente a chave primária não pode conter valores nulos e/ou repetidos. 
As chaves primárias podem ser especificadas quando a tabela é criada ou com a alteração de estrutura com o comando alter table. 
FOREING KEY 
Uma chave estrangeira define o relacionamento entre duas tabelas. Uma chave estrangeira consiste de um campo que aponta para a chave primária de outra tabela ou da mesma tabela nos autorelacionamentos. A chave estrangeira garante a integridade dos dados, pois somente valores existentes na tabela relacionada podem preencher o campo referente a chave estrangeira. 
Onde: 
● foreign key define a coluna da tabela filha; 
● references indentifica a coluna e a tabela pai. 
SEQUENCE 
Uma sequence gera números sequenciais de acordo com regras predefinidas no momento de sua criação. Normalmente, as seqüências são usadas para criar um valor de chave primária que deve ser exclusivo para cada linha de uma tabela.
Conexão com a base de dados JDBC Rosicléia Frasson 
57 
CREATE SEQUENCE nome_da_seqüência 
[increment by n] 
[start with n] 
[maxvalue n] or [minvalue n] 
[cycle | nocycle] 
[cache n | nocache]; 
Onde: 
● increment by n: define o número a ser incrementado cada vez que a coluna nextval for referenciada. 
● start with n: define o primeiro valor a ser gerado na sequência. 
● minvalue n: define o valor mínimo a ser produzido na sequência. 
● maxvalue n: define o valor máximo a ser produzido na sequência. 
● cycle: especifica se a seqüência continuará a gerar valores após alcançar seu valor máximo ou mínimo 
● cache n: especifica quantos valores o servidor Oracle alocará previamente na memória. Se o cache não for especificado explicitamente, o Oracle irá assumir o padrão, que é de gerar um cache de 20 valores. 
O comando nextval retorna o próximo número da sequência. 
Tipos de dados 
A tabela a seguir lista os tipos de dados mais utilizados no banco Oracle. 
Descrição Tipo de dado 
Armazena dados do tipo caracter de comprimento variável. 
VARCHAR2(comprimento) 
Armazena dados do tipo caracter de comprimento fixo. 
CHAR(comprimento) 
Armazena números flutuantes, porém aceita números inteiros. 
NUMBER(precisão, escala) 
Armazena datas e horas. 
DATE 
Armazena valores inteiros. 
INTEGER 
Vale ressaltar que a única diferença entre o CHAR e o VARCHAR é que o CHAR armazena caracteres alfanuméricos de tamanho fixo. Isso significa que se a string leite que corresponde ao nome de um produto for armazenada em uma coluna CHAR(50), a coluna conterá a string LEITE + 45 espaços em branco que são adicionados automaticamente para preencher o tamanho total da coluna.. 
DML
Conexão com a base de dados JDBC Rosicléia Frasson 
58 
A linguagem DML - Data Manipulation Language - é composta por comandos usados para manipular as informações contidas na base de dados. Dentre os comandos mais utilizados estão: 
INSERT 
Comando utilizado para inserir um registro na base de dados. 
INSERT INTO nome_tabela 
(coluna1,coluna2,coluna3,...) 
VALUES 
(valor1,valor2,valor3,...); 
UPDATE 
Instrução utilizada para atualizar os registros existentes em uma tabela. 
UPDATE nome_tabela SET 
coluna1=valor1, 
coluna2=valor2, 
... 
WHERE alguma_coluna = algum_valor; 
DELETE 
Comando utilizado para remover registros existentes em uma tabela. 
DELETE FROM nome_tabela 
WHERE alguma_coluna = algum_valor; 
SELECT 
Comando utilizado para recuperar dados de uma ou mais tabelas. O * seleciona todas as colunas de uma tabela. 
SELECT nome_coluna, nome_coluna FROM nome_tabela; 
SELECT * FROM nome_tabela; 
LIKE
Programação Desktop: Uma abordagem com Java
Programação Desktop: Uma abordagem com Java
Programação Desktop: Uma abordagem com Java
Programação Desktop: Uma abordagem com Java
Programação Desktop: Uma abordagem com Java
Programação Desktop: Uma abordagem com Java
Programação Desktop: Uma abordagem com Java
Programação Desktop: Uma abordagem com Java
Programação Desktop: Uma abordagem com Java
Programação Desktop: Uma abordagem com Java
Programação Desktop: Uma abordagem com Java
Programação Desktop: Uma abordagem com Java
Programação Desktop: Uma abordagem com Java
Programação Desktop: Uma abordagem com Java

Mais conteúdo relacionado

Mais procurados

Processo Unificado(RUP)
Processo Unificado(RUP)Processo Unificado(RUP)
Processo Unificado(RUP)elliando dias
 
Curso Java Básico Aula 01: Introdução e Dicas para quem está Começando
Curso Java Básico Aula 01: Introdução e Dicas para quem está ComeçandoCurso Java Básico Aula 01: Introdução e Dicas para quem está Começando
Curso Java Básico Aula 01: Introdução e Dicas para quem está ComeçandoLoiane Groner
 
Aula 02 - Principios da Orientação a Objetos (POO)
Aula 02 - Principios da Orientação a Objetos (POO)Aula 02 - Principios da Orientação a Objetos (POO)
Aula 02 - Principios da Orientação a Objetos (POO)Daniel Brandão
 
Estimativa de software usando pontos de função
Estimativa de software usando pontos de funçãoEstimativa de software usando pontos de função
Estimativa de software usando pontos de funçãoClaudio Martins
 
Introdução à Engenharia de Software
Introdução à Engenharia de SoftwareIntrodução à Engenharia de Software
Introdução à Engenharia de SoftwareNécio de Lima Veras
 
Aula - Introdução a Engenharia de Software
Aula - Introdução a Engenharia de SoftwareAula - Introdução a Engenharia de Software
Aula - Introdução a Engenharia de SoftwareCloves da Rocha
 
Diagrama de Atividades - UML
Diagrama de Atividades - UMLDiagrama de Atividades - UML
Diagrama de Atividades - UMLVinícius Barros
 
Java vetores e matrizes
Java   vetores e matrizesJava   vetores e matrizes
Java vetores e matrizesArmando Daniel
 
Analise de Requisitos
Analise de RequisitosAnalise de Requisitos
Analise de Requisitoselliando dias
 
Estrutura de Dados - Procedimentos e Funções
Estrutura de Dados - Procedimentos e FunçõesEstrutura de Dados - Procedimentos e Funções
Estrutura de Dados - Procedimentos e FunçõesAdriano Teixeira de Souza
 
Aula 16 - Modularização - parte 3 - exercícios
Aula 16 - Modularização - parte 3 - exercíciosAula 16 - Modularização - parte 3 - exercícios
Aula 16 - Modularização - parte 3 - exercíciosPacc UAB
 
Análise e Modelagem de Software
Análise e Modelagem de SoftwareAnálise e Modelagem de Software
Análise e Modelagem de SoftwareMarcelo Yamaguti
 
Apresentando a Linguagem de Programação Python
Apresentando a Linguagem de Programação PythonApresentando a Linguagem de Programação Python
Apresentando a Linguagem de Programação PythonPriscila Mayumi
 
Aula 1 - Introdução a Engenharia de Software
Aula 1 -  Introdução a Engenharia de SoftwareAula 1 -  Introdução a Engenharia de Software
Aula 1 - Introdução a Engenharia de SoftwareLeinylson Fontinele
 

Mais procurados (20)

Processo Unificado(RUP)
Processo Unificado(RUP)Processo Unificado(RUP)
Processo Unificado(RUP)
 
Aula diagrama de classes
Aula diagrama de classesAula diagrama de classes
Aula diagrama de classes
 
Itil v3 estratégia de serviço
Itil v3 estratégia de serviçoItil v3 estratégia de serviço
Itil v3 estratégia de serviço
 
Curso Java Básico Aula 01: Introdução e Dicas para quem está Começando
Curso Java Básico Aula 01: Introdução e Dicas para quem está ComeçandoCurso Java Básico Aula 01: Introdução e Dicas para quem está Começando
Curso Java Básico Aula 01: Introdução e Dicas para quem está Começando
 
Aula 02 - Principios da Orientação a Objetos (POO)
Aula 02 - Principios da Orientação a Objetos (POO)Aula 02 - Principios da Orientação a Objetos (POO)
Aula 02 - Principios da Orientação a Objetos (POO)
 
Estimativa de software usando pontos de função
Estimativa de software usando pontos de funçãoEstimativa de software usando pontos de função
Estimativa de software usando pontos de função
 
Introdução à Engenharia de Software
Introdução à Engenharia de SoftwareIntrodução à Engenharia de Software
Introdução à Engenharia de Software
 
Aula 05 - Java Script Básico
Aula 05 -  Java Script BásicoAula 05 -  Java Script Básico
Aula 05 - Java Script Básico
 
Aula - Introdução a Engenharia de Software
Aula - Introdução a Engenharia de SoftwareAula - Introdução a Engenharia de Software
Aula - Introdução a Engenharia de Software
 
Diagrama de Atividades - UML
Diagrama de Atividades - UMLDiagrama de Atividades - UML
Diagrama de Atividades - UML
 
Introducao swebok
Introducao swebokIntroducao swebok
Introducao swebok
 
Java vetores e matrizes
Java   vetores e matrizesJava   vetores e matrizes
Java vetores e matrizes
 
Analise de Requisitos
Analise de RequisitosAnalise de Requisitos
Analise de Requisitos
 
Estrutura de Dados - Procedimentos e Funções
Estrutura de Dados - Procedimentos e FunçõesEstrutura de Dados - Procedimentos e Funções
Estrutura de Dados - Procedimentos e Funções
 
Aula 16 - Modularização - parte 3 - exercícios
Aula 16 - Modularização - parte 3 - exercíciosAula 16 - Modularização - parte 3 - exercícios
Aula 16 - Modularização - parte 3 - exercícios
 
Análise e Modelagem de Software
Análise e Modelagem de SoftwareAnálise e Modelagem de Software
Análise e Modelagem de Software
 
Java Web, o Tutorial
Java Web, o TutorialJava Web, o Tutorial
Java Web, o Tutorial
 
Apresentando a Linguagem de Programação Python
Apresentando a Linguagem de Programação PythonApresentando a Linguagem de Programação Python
Apresentando a Linguagem de Programação Python
 
Aula 1 - Introdução a Engenharia de Software
Aula 1 -  Introdução a Engenharia de SoftwareAula 1 -  Introdução a Engenharia de Software
Aula 1 - Introdução a Engenharia de Software
 
Algoritmo recursivo
Algoritmo recursivoAlgoritmo recursivo
Algoritmo recursivo
 

Semelhante a Programação Desktop: Uma abordagem com Java

Java basico modulo_01
Java basico modulo_01Java basico modulo_01
Java basico modulo_01Daniel Alves
 
Java basico modulo_01
Java basico modulo_01Java basico modulo_01
Java basico modulo_01rollbackpt
 
Java 01 Java Visao Geral Detalhado
Java 01 Java Visao Geral DetalhadoJava 01 Java Visao Geral Detalhado
Java 01 Java Visao Geral DetalhadoRegis Magalhães
 
Java Fundamentos
Java FundamentosJava Fundamentos
Java FundamentosWilson Lima
 
Programação Orientada a Objetos com Java
Programação Orientada a Objetos com JavaProgramação Orientada a Objetos com Java
Programação Orientada a Objetos com JavaÁlvaro Farias Pinheiro
 
Aula 2 - POO: Fundamentos da linguagem Java
Aula 2 - POO: Fundamentos da linguagem JavaAula 2 - POO: Fundamentos da linguagem Java
Aula 2 - POO: Fundamentos da linguagem JavaDaniel Brandão
 
Apostila de Fundamentos Java
Apostila de Fundamentos JavaApostila de Fundamentos Java
Apostila de Fundamentos JavaMarcio Marinho
 
Aula 01 O que é java
Aula 01   O que é javaAula 01   O que é java
Aula 01 O que é javaSergio Silva
 
Introdução a Linguagem Java
Introdução a Linguagem JavaIntrodução a Linguagem Java
Introdução a Linguagem JavaUFPA
 
Java: Muito mais que uma linguagem!
Java: Muito mais que uma linguagem!Java: Muito mais que uma linguagem!
Java: Muito mais que uma linguagem!Aécio Costa
 
Java programação orientada a objetos
Java   programação orientada a objetosJava   programação orientada a objetos
Java programação orientada a objetosPaulo Carvalho
 
Poo1 aula 1 - java - história e introdução
Poo1   aula 1 - java -  história e introduçãoPoo1   aula 1 - java -  história e introdução
Poo1 aula 1 - java - história e introduçãoDenis Sobrenome
 
Poo1 aula 1 - java - história e introdução
Poo1   aula 1 - java -  história e introduçãoPoo1   aula 1 - java -  história e introdução
Poo1 aula 1 - java - história e introduçãoDenis Sobrenome
 
[DESATUALIZADO] Apostila Desenvolvimento Android Básico
[DESATUALIZADO] Apostila Desenvolvimento Android Básico[DESATUALIZADO] Apostila Desenvolvimento Android Básico
[DESATUALIZADO] Apostila Desenvolvimento Android BásicoMau Salamon
 
Capacitacao java aula-01-01-conceitos
Capacitacao java aula-01-01-conceitosCapacitacao java aula-01-01-conceitos
Capacitacao java aula-01-01-conceitosEliete Regina Souza
 

Semelhante a Programação Desktop: Uma abordagem com Java (20)

Java basico modulo_01
Java basico modulo_01Java basico modulo_01
Java basico modulo_01
 
Java basico modulo_01
Java basico modulo_01Java basico modulo_01
Java basico modulo_01
 
Java basico modulo_01
Java basico modulo_01Java basico modulo_01
Java basico modulo_01
 
Java basico modulo_01
Java basico modulo_01Java basico modulo_01
Java basico modulo_01
 
Java 01 Java Visao Geral
Java 01 Java Visao GeralJava 01 Java Visao Geral
Java 01 Java Visao Geral
 
Java 01 Java Visao Geral Detalhado
Java 01 Java Visao Geral DetalhadoJava 01 Java Visao Geral Detalhado
Java 01 Java Visao Geral Detalhado
 
Java Fundamentos
Java FundamentosJava Fundamentos
Java Fundamentos
 
Programação Orientada a Objetos com Java
Programação Orientada a Objetos com JavaProgramação Orientada a Objetos com Java
Programação Orientada a Objetos com Java
 
Aula 2 - POO: Fundamentos da linguagem Java
Aula 2 - POO: Fundamentos da linguagem JavaAula 2 - POO: Fundamentos da linguagem Java
Aula 2 - POO: Fundamentos da linguagem Java
 
Java -aula_01
Java  -aula_01Java  -aula_01
Java -aula_01
 
Apostila de Fundamentos Java
Apostila de Fundamentos JavaApostila de Fundamentos Java
Apostila de Fundamentos Java
 
Aula 01 O que é java
Aula 01   O que é javaAula 01   O que é java
Aula 01 O que é java
 
Introdução a Linguagem Java
Introdução a Linguagem JavaIntrodução a Linguagem Java
Introdução a Linguagem Java
 
Java: Muito mais que uma linguagem!
Java: Muito mais que uma linguagem!Java: Muito mais que uma linguagem!
Java: Muito mais que uma linguagem!
 
Aula 01 o que é java
Aula 01  o que é javaAula 01  o que é java
Aula 01 o que é java
 
Java programação orientada a objetos
Java   programação orientada a objetosJava   programação orientada a objetos
Java programação orientada a objetos
 
Poo1 aula 1 - java - história e introdução
Poo1   aula 1 - java -  história e introduçãoPoo1   aula 1 - java -  história e introdução
Poo1 aula 1 - java - história e introdução
 
Poo1 aula 1 - java - história e introdução
Poo1   aula 1 - java -  história e introduçãoPoo1   aula 1 - java -  história e introdução
Poo1 aula 1 - java - história e introdução
 
[DESATUALIZADO] Apostila Desenvolvimento Android Básico
[DESATUALIZADO] Apostila Desenvolvimento Android Básico[DESATUALIZADO] Apostila Desenvolvimento Android Básico
[DESATUALIZADO] Apostila Desenvolvimento Android Básico
 
Capacitacao java aula-01-01-conceitos
Capacitacao java aula-01-01-conceitosCapacitacao java aula-01-01-conceitos
Capacitacao java aula-01-01-conceitos
 

Programação Desktop: Uma abordagem com Java

  • 1. Programação Desktop Uma abordagem com Java ROSICLÉIA FRASSON DE SOUZA
  • 2. Fundamentos da Linguagem Java Rosicléia Frasson 1 Fundamentos da linguagem Java Histórico da linguagem Java por Bruno Bitencourt Luiz Em 1991, atenta a grande tendência dos microprocessadores e dispositivos inteligentes, a Sun Microsystems dá início a um projeto de pesquisa com a ideia de desenvolver uma linguagem sólida para o mercado. O líder do projeto era James Gosling. O objetivo era que aplicações rodassem em qualquer aparelho de pouca memória como switchboxes de televisores. Para cumprir este objetivo a linguagem deveria ser pequena, porém potente. Infelizmente, o mercado para estes dispositivos não se desenvolveu como a Sun esperava. Porém, em 1993, a Web se populariza de uma forma repentina. A Sun vê então a possibilidade de usar esta linguagem para a Web. A ideia é que esta linguagem baseada em C++ tornasse as aplicações Web e suas animações mais dinâmicas. Oficialmente, o Java só é apresentado em 1995 durante uma conferência. Finalmente, no início de 1996 é lançado o Java 1.0. Versão que de imediato causou decepção na comunidade Java, pois pecava em vários requisitos como: segurança e interface visual. Mais adiante, foi lançada a versão 1.1, com várias melhorias de segurança e graficamente mais amigável, mas ainda não era satisfatória. Na conferência JavaOne em 1998 a versão 1.2 é lançada. Continha várias melhorias de segurança e substituía por completo a interface anterior. Esta versão foi um marco na história do Java, dias depois a versão 1.2 passou a se chamar Java 2 Standart Edition Software. Posteriormente foram sendo lançadas várias atualizações. A última versão que adicionou uma série de recursos significativos foi a versão 5, pois mais de 1000 classes e interfaces foram implementadas. Atualmente o Java está na versão 8 com mais de 3 mil classes e interfaces existentes. O Java é amplamente aceito por parte dos desenvolvedores. Isso se deve a características como: simplicidade, orientação a objetos, compatibilidade com redes, robustez, segurança, portabilidade, alto desempenho, capacidade de múltiplos threads. Além disso, deve-se destacar que sua licença é GPL, e que é multiplataforma, ou seja, para desenvolver em Java não é necessário adquirir qualquer tipo de licença e a compatibilidade com todos os principais sistemas operacionais é garantida. Durante o desenvolvimento deste trabalho, a versão Java mais recente é a 8.0. Esta é mais uma daquelas que causam uma revolução. Diversas melhorias como a expressão Lambda (λ) foram adicionadas. Este é um recurso novo no Java, porém já existia em outras linguagens. O foco desta nova versão é fazer mais, com menos código. Distribuições do Java Java pode ser encontrada em três distribuições principais, cada uma com sua finalidade específica: ● Java StandartEdition (JSE): Usada em computadores pessoais, notebooks e arquiteturas com poder de processamento consideráveis. Várias APIs acompanham esta versão. ● Java Enterprise Edition (JEE): É a tecnologia Java para aplicativos distribuídos em rede em larga escala e aplicativos baseados na web . Possui um grande número de APIs voltadas para a segurança da aplicação. Usada em servidores, contendo suporte para JSP, XML e servlets. ● Java Micro Edition (JME): Usada em dispositivos com recursos limitados, como sistemas embarcados e dispositivos móveis. Possui APIs bem simples e leves para economizar memória e processamento.
  • 3. Fundamentos da Linguagem Java Rosicléia Frasson 2 Além das três principais distribuições, também existe o Java Card, que é uma edição específica para cartões inteligentes, extremamente reduzida. Nesta tecnologia até a máquina virtual é dividida entre o sistema do cartão e o sistema operacional do terminal. Compilador e interpretador Java O processo de tradução da linguagem Java para a linguagem de máquina é um pouco diferente das demais linguagens de programação. Os programas Java são compilados e interpretados. Após a criação de um programa Java, um compilador transforma o programa em uma linguagem intermediária, chamada de bytecodes. Os bytecodes representam uma linguagem de máquina para uma máquina abstrata, executada pela máquina virtual nos dispositivos que suportam a linguagem de programação Java. Sendo assim, o bytecode é independente de plataforma. Todas as vezes que o programa é executado, a JVM (Java Virtual Machine) lê o arquivo com a extensão .class que está em bytecode e o interpreta para o processador. Vale mencionar que quando uma classe é carregada na JVM, a mesma é verificada para garantir que os bytecodes são bem formados e atendem aos critérios de segurança e confidencialidade. Com o uso da máquina virtual, o programa fica independente de sistema operacional e de plataforma. Uma máquina virtual é muito mais ampla do que um interpretador. Uma máquina virtual é uma espécie de computador de mentira, tem tudo o que um computador tem: gerenciamento de memória, thread, pilha de execução. Nas primeiras versões do Java, o processo de interpretação feito pela JVM era lento, o que tornava um problema para a linguagem. Na versão 1.2 surgiu o Compilador Just In Time ou Compilador JIT. O compilador JIT trabalha em conjunto com o interpretador Java. O interpretador verifica quais trechos de código são executados mais vezes e pede que o compilador JIT os compile, convertendo o bytecode na linguagem de máquina do processador que está executando o programa. O JIT também possui informações relativas ao ambiente em que está executando, como quantidade de usuários simultâneos e memória disponível. Com essas informações a JVM muda a estratégia de compilação em busca de um melhor desempenho. Java SE A Java Standart Edition é o segmento base da plataforma. Com o Java SE é possível criar
  • 4. Fundamentos da Linguagem Java Rosicléia Frasson 3 aplicações Desktop e applets. A Java SE possui duas grandes divisões: ● JRE: ambiente de execução Java para quem quer apenas executar programas em Java. É composta pela JVM e as APIs Java. Uma API é uma coleção de softwares prontos, que incluem desde estruturas para a manipulação de arquivos até a construção de aplicativos gráficos. ● JDK: é o conjunto de ferramentas necessárias para o desenvolvimento de programas Java. É composto pela JRE, javac (compilador), jar (empacotador) e o javadoc (documentação). IDEs Programas em Java podem ser construídos usando apenas um bloco de notas e um prompt de comando. No entanto, com apenas essas duas ferramentas o processo fica bem dispendioso. Para deixar o processo de desenvolvimento mais produtivo, existem programas específicos, chamados de IDEs (Ambiente de Desenvolvimento Integrado). Uma IDE é um software que tem como objetivo maximizar a produtividade no processo de desenvolvimento. Alguns recursos que as IDEs possuem: ● Editor de código: Escrita rápida de código, auto completar, gerenciamento de importações, dicas para correção e geração de código. ● Depurador: Facilidade na busca por erros no código através da análise cuidadosa de cada passo executado pelo software. ● Compilador: Geração de código de máquina a partir do código fonte automaticamente. ● Deploy: Publicação da aplicação, geração de executáveis. ● Código limpo e automatizado: Facilidade no entendimento do projeto por todos os envolvidos. ● JVM: Processo de interpretação de bytecodes automático.
  • 5. Fundamentos da Linguagem Java Rosicléia Frasson 4 Principais IDEs para o desenvolvimento Java Existem uma infinidade de IDEs para o desenvolvimento Java, abaixo segue uma listagem das líderes de mercado: ● JDeveloper: O JDeveloper é uma ferramenta da Oracle que tem como principal característica a cobertura de todo o ciclo de desenvolvimento: análise, codificação, manutenção, otimização e implantação. Esta ferramenta é pouco flexível e seu uso é recomendado quando o software for produzido usando toda a arquitetura com produtos Oracle. ● Eclipse: Poderosíssima IDE de desenvolvimento, leve, rápido, configurável e com inúmeros plug- ins. Deixa a desejar no desenvolvimento de telas para desktop. ● Netbeans: Juntamente com o Eclipse, uma das IDEs mais utilizadas pela comunidade de desenvolvimento. Tem editor de GUI nativo.Gera muito código automático, não editável. Gerenciamento de memória JVM Quando a JVM é inicializada um bloco de memória é capturado do sistema operacional para o programa Java ser executado. Em Java, existem duas áreas de memória. Aquela que os objetos residem, chamado de heap e a pilha de execução, onde estão as variáveis locais e as chamadas de métodos a serem executados. Variáveis de instância são declaradas dentro de uma classe, mas não dentro de um método. Elas representam o atributo de um objeto. Sendo assim elas residem dentro do objeto a que pertencem, ou seja, no heap. A vida de uma variável local é limitada a existência do método em que a mesma está declarada na pilha de execução. Entende-se por variável local as variáveis declaradas dentro de um método, inclusive como parâmetros do método. Se uma variável local não for do tipo primitivo, um objeto correspondente a mesma deve existir no heap. No entanto, como uma variável não primitiva armazena apenas a referência a um objeto e não o próprio objeto, a variável que contém a referência estará armazenada na pilha de execução. Quando um programa chama um método, o método entra na pilha de execução de programas. Na pilha de chamadas o estado do método e os valores de todas as variáveis locais são armazenados. O método do topo da pilha é sempre o que está sendo executado no momento. Um método e suas variáveis locais permanecem na pilha até o fim da sua execução. GarbageCollector O Garbage Collector é um dos componentes da JVM e é responsável por liberar espaços da memória que não estão sendo mais utilizados. Diferente do gerenciamento manual, onde o desenvolvedor é responsável tanto pela alocação quanto pela liberação de memória, em Java, o desenvolvedor não define os pontos de coleta, apenas libera as referências dos objetos e em algum momento a coleta é efetuada. Vale ressaltar que um objeto não é excluído do heap no momento em que o mesmo deixa de ser referenciado. O Garbage Collector define o melhor momento de efetuar a coleta. O propósito da coleta de lixo é descartar os objetos que não estão sendo mais usados. Isso garante espaço de memória para que o software continue sua execução. Um objeto pode deixar de ser utilizado quando a variável que o está referenciando passa a ser null, quando a variável passa a referenciar outro objeto ou um método termina sua execução e as variáveis locais do mesmo deixam de existir. Basicamente o processo de coleta de lixo pode ser descrito em alguns passos. Embora os
  • 6. Fundamentos da Linguagem Java Rosicléia Frasson 5 coletores de lixo sejam um pouco mais sofisticados e dependem do fabricante e versão da JVM, basicamente a coleta de lixo é dividida em duas partes: diferenciação de objetos vivos e mortos e remoção de objetos mortos. ● Marcação: Nesta etapa o coletor de lixo identifica quais partes da memória estão em uso e quais não estão. ● Remoçao normal: Objetos não referenciados são removidos, espaços livres ficam espalhados pela memória. ● Remoção com compactação: Além da remoção dos objetos sem referência, os objetos restantes são realocados. A máquina virtual garante que qualquer objeto vai permanecer na memória enquanto existir a possibilidade de o mesmo ser alcançado pela pilha de execução, além de liberar espaço quando o objeto não é mais referenciado. O fato do desenvolvedor não se preocupar com a coleta de lixo é um dos pontos positivos do garbage collector. No entanto, pode se tornar um ponto crítico pela sua imprevisibidade.
  • 7. Sintaxe da Linguagem Java Rosicléia Frasson 6 Sintaxe da linguagem Java Ponto e vírgula, blocos, espaços em branco e case-sensitive Java é uma linguagem de formato livre, ou seja, não existem regras especiais para o espaçamento vertical ou para a indentação horizontal. Porém, para uma melhor legibilidade do código, é interessante usar espaços, tabulações e novas linhas. Em Java, espaços em branco podem ser usados sem restrições. Um bloco é formado por uma ou mais instruções agrupadas entre chaves indicando que formam uma só unidade. O uso de chaves em Java indica a presença de um bloco, onde a abertura da chave indica o início do bloco e o fechamento da chave, o fim do bloco. Os blocos podem ser organizados em estruturas aninhadas infinitamente. Uma instrução é composta por uma ou mais linhas terminadas com um ponto-e-vírgula. No fim de cada instrução, indispensavelmente deve ser usado o sinal de pontuação ponto-e-vírgula. A quebra de linha não separa instruções. O Java é uma linguagem case-sensitive, ou seja, diferencia maiúsculas de minúsculas. Portanto, escrever letra e LETRA é diferente para o Java. Palavras reservadas O Java possui uma lista de palavras que possuem um significado especial para o compilador. Essas palavras não podem ser usadas na declaração de classes, métodos e variáveis. catch case byte break boolean assert abstract double do default continue const class char float finally final false extends enum else int instanceof import implements if goto for private package null new native long interface super strictpf static short return public protected try transient throws throw this synchronized switch while volatile void Tipos primitivos No Java existem apenas oito tipos primitivos de dados. Os tipos primitivos fazem parte da linguagem e não são instâncias de outras classes. Descricão Tipo Classificação O tipo boolean pode armazenar apenas dois valores: true ou false, que representam os valores verdadeiro e falso, respectivamente. O valor boolean lógico
  • 8. Sintaxe da Linguagem Java Rosicléia Frasson 7 padrão do tipo boolean é false. Variáveis do tipo byte podem representar valores inteiros com 8 bits de precisão, ou seja, valores entre -128 a 127. byte inteiro Variáveis do tipo short podem representar valores inteiros com 16 bits de precisão, ou seja, valores entre -32768 a 32767. short Variáveis do tipo int podem representar valores inteiros com 32 bits de precisão, ou seja, valores entre -2147483648 a 2147483647. int Variáveis do tipo long podem armazenar valores inteiros com 64 bits de precisão, ou seja, valores entre -9223372036854775808 a 9223372036854775807. long Variáveis do tipo float podem armazenar valores em ponto flutuante com 32 bits de precisão, na faixa de - 1.40239846E-45 a 3.40282347E + 38 (9 dígitos significativos de precisão). float ponto flutuante Variáveis do tipo double podem armazenar valores em ponto flutuante com 64 bits de precisão, na faixa de - 4.94065645841246544E-324 a 1.79769313486231570E + 308 (18 dígitos significativos de precisão). double O tipo char representa um único caracter em Java. Caracteres em Java são representados usando o conjunto de caracteres Unicode, com dois bytes por caracter. Esta representação permite a representação em várias línguas respectivamente. char caracter ` Ao escolher um tipo de dado para ser usado, o programador deve estar atento a faixa de valores que o campo pode vir a ocupar. A tentativa de armazenar um valor maior do que o esperado pelo tipo pode ocasionar erros no software. Para representar valores decimais em Java é utilizado o ponto ao invés da vírgula. Além dos caracteres normais, existem os caracteres de controle, que efetuam uma ação diferenciada quando utilizados. Segue uma lista dos mesmos: Descrição Caracter aspa dupla ” aspa simples ’ nova linha n tabulação t barra enter r Conversão entre tipos primitivos Valores de tipos numéricos podem ser transformados em outros tipos numéricos de duas formas: ● Implicitamente: A JVM transforma em tempo de execução, quando acha conveniente, tipos restritos em tipos com maior amplitude, ou seja, uma variável pode receber valores de variáveis de tipos com tamanho menor do que a mesma foi declarada. . Nenhuma informação é perdida. ● Através de uma operação chamada casting ou conversão explícita. Para efetuar a conversão
  • 9. Sintaxe da Linguagem Java Rosicléia Frasson 8 explícita, basta colocar o tipo de dado para o qual se deseja converter entre parênteses antes da expressão a ser convertida. Neste caso, o programador estará se responsabilizando por possíveis perdas de valores. Na tabela a seguir, estão relacionados todos os casts possíveis na linguagem Java. double float long int char short byte PARA: DE: implícito implícito implícito implícito (char) implícito ----- byte implícito implícito implícito implícito (char) ----- (byte) short implícito implícito implícito implícito ----- (short) (byte) char implícito implícito implícito ----- (char) (short) (byte) int implícito implícito ----- (int) (char) (short) (byte) long implícito ----- (long) (int) (char) (short) (byte) float ----- (float) (long) (int) (char) (short) (byte) double Declaração de variáveis Variáveis são espaços na memória onde podemos guardar informações. Cada valor é convertido para binário e então pode ser alocado na memória. Praticamente todos os programas usam variáveis. E como o próprio nome diz, elas podem ter o valor modificado durante a execução do programa. As variáveis possuem tipos diferentes, dependendo da informação a ser armazenada. No Java, para declarar uma variável é necessário especificar o tipo, dar um nome a ela e preferencialmente inicializá-la. Valores iniciais são estabelecidos por expressões de inicialização usando o operador = quando as variáveis são declaradas. Os nomes de variáveis ou identificadores possuem algumas regras para que o compilador identifique como válido: ● Os nomes de variáveis em Java devem ser inicializados por uma letra, um cifrão ou por undescore; ● Após o primeiro caracter, vale qualquer combinação de números, letras e caracteres; ● Os identificadores não podem ter o nome igual ao de uma palavra reservada. Além das regras que são definidas pela linguagem, algumas convenções de nomes foram estabelecidas pela comunidade de programadores com o intuito de deixar o código mais legível. Segue uma lista das principais convenções: ● O nome de uma variável deve ser escrito em letras minúsculas. Caso o nome da variável seja uma palavra composta, a primeira letra a partir da segunda palavra deve ser escrita com letra maiúscula; ● O nome de uma variável deve ser significativo, indicando claramente o que a variável representa. Isso significa que se o nome de uma variável necessita de um comentário para explicar o porquê da sua existência, ele deve ser trocado. ● É indicado utilizar nomes que refletem o domínio em que o software será utilizado. ● As abreviações e siglas devem ser usadas com cautela. Decifrar uma abreviação adiciona um
  • 10. Sintaxe da Linguagem Java Rosicléia Frasson 9 tempo extra na execução de uma tarefa. ● Nomes semelhantes devem ser evitados, pois podem confundir o desenvolvedor, principalmente quando o recurso de autocompletar disponível nas IDEs de desenvolvimento é utilizado. ● É considerada uma boa prática não utilizar como identificadores nomes confusos que podem levar quem lê o código a conclusões erradas. ● Identificadores de variáveis devem ser escritos no singular, exceto quando a variável representar uma coleção de dados. ● É indicado utilizar nomes pronunciáveis para facilitar a leitura e comunicação. ● É preferível declarar uma variável por linha, ao invés de várias na mesma linha. Entrada e saída de dados A classe Scanner possui uma série de métodos convenientes para ler o fluxo de entrada. A mesma faz parte do pacote java.util e é necessário importá-lo para a utilização da classe. Para a leitura de dados do console, na criação do objeto é necessário passar como argumento Sistem.in. Para cada tipo primitivo existe um método da classe Scanner que retorna um valor do tipo que foi invocado. Sendo assim, existem os métodos nextInt(), nextDouble(), nextFloat(), nextBoolean(), entre outros. O método close() fecha o escaneamento de leitura. O objeto System.out permite exibir uma saída de texto no console. Dentro deste objeto existem os métodos println(), print() e printf(). O método println() gera uma saída de texto juntamente com uma quebra de linha, o método print gera uma saída de texto sem quebra de linha e o método printf() exibe dados formatados. package br.com.rosicleiafrasson.sintaxeBasica; import java.util.Scanner; public class EntradaSaidaDadosConsole { public static void main(String[] args) { Scanner entrada = new Scanner(System.in); int idade; String nome; double peso; System.out.println("Informe o seu nome: "); nome = entrada.nextLine(); System.out.println("Informe a sua idade: "); idade = entrada.nextInt(); System.out.println("Informe o seu peso: "); peso = entrada.nextDouble(); System.out.println(nome + ", você possui " + idade + " anos. "); System.out.print("Seu peso é "); System.out.printf("%.2f", peso); entrada.close(); } }
  • 11. Sintaxe da Linguagem Java Rosicléia Frasson 10 Operadores básicos Referência a método, função ou atributo de um objeto. . Separador de identificadores. , Finalizador de declarações e comandos. ; Declarador de vetores e delimitador de índices. [ ] Separador de blocos. { } Lista de parâmetros. ( ) Operador de atribuição. = Operadores lógicos Maior > Maior ou igual >= Menor < Menor ou igual <= Igual == Diferente != E && OU || Operadores aritméticos Adição + Subtração - Multiplicação * Divisão / Módulo (resto da divisão) % É importante ressaltar que a divisão de números inteiros sempre resulta em um inteiro. Mesmo que a variável responsável por armazenar o resultado seja do tipo double ou float.
  • 12. Sintaxe da Linguagem Java Rosicléia Frasson 11 Operadores de incremento e decremento Os operadores de incremento e decremento são operadores que atuam sobre uma única variável numérica, aumentando ou diminuindo ou seu valor. ● incremento: adiciona o valor de uma unidade ao valor atual. O operador de incremento é o sinal de ++; ● decremento: diminui uma unidade do valor atual. O operador de decremento é o --; Os operadores de incremento e decremento podem ser posicionados imediatamente antes ou imediatamente após o nome da variável. Vale ressaltar que esses operadores funcionam de forma diferente dependendo da posição em relação a variável. Se o operador for colocado antes, a variável é incrementada no momento da sua avaliação. Caso contrário, a variável é incrementada após a sua avaliação. Maiores detalhes podem ser vistos na tabela a seguir: Significado Exemplo Operador Incrementa a variável e depois usa. ++x ++ Usa a variável e depois incrementa. x++ Decrementa a variável e depois usa. --x -- Usa a variável e depois decrementa. x-- Operadores de atribuição Expressão equivalente Exemplo Operador x = x + y x += y += x = x - y x -= y -= x = x * y x *= y *= x = x / y x /= y /= x = x % y x%=y %= Operador condicional ternário ( ?:) O operador condicional ternário retorna um entre dois valores de acordo com o resultado de uma expressão booleana. O mesmo possui a seguinte estrutura: Onde: ● o primeiro operador a esquerda do ? é a condição, normalmente representada por uma expressão booleana; ● o segundo operando que fica entre ? e : representa o valor da expressão, caso a condição seja
  • 13. Sintaxe da Linguagem Java Rosicléia Frasson 12 verdadeira; ● o terceiro operando a direita do : representa o valor da expressão se a condição for falsa. Segue um trecho de código que deve mprimir na tela a mensagem aprovado, caso a nota do aluno seja um valor maior ou igual a 7. Caso contrário deve imprimir a mensagem reprovado. Scanner entrada = new Scanner(System.in); double nota; System.out.println("Informe a nota do aluno: "); nota = entrada.nextDouble(); System.out.println(nota >= 7 ? " Aluno aprovado " : " Aluno reprovado"); Diferença entre tipos primitivos e variáveis de referência As variáveis primitivas guardam o real conteúdo da variável. Uma variável de tipo primitivo pode armazenar exatamente um valor de seu tipo declarado por vez, quando outro valor for atribuído a essa variável, seu valor inicial será substituído. As variáveis de referência são as variáveis que apontam para um objeto, ou seja,guardam um endereço de memória para um objeto criado.Desta forma, quando um outro valor é atribuído para a variável, uma nova posição de memória aloca o novo valor e a referência aponta para a nova posição de memória. O tamanho alocado para uma variável de referência é sempre fixo, pois se trata de um endereço de memória que mostra como chegar ao objeto. String Em Java não existe um tipo primitivo para se trabalhar com textos. Para fazer uso dos mesmos é necessário utilizar o tipo String que é um objeto presente no Java desde a primeira versão. A classe String faz parte do pacote java.lang e por ser uma classe amplamente usada, ela não precisa ser instanciada. Sua atribuição é composta por uma sequência de caracteres delimitados por aspas duplas. Os objetos da classe String são imutáveis, ou seja, o conteúdo de uma String nunca pode ser alterado. Cada vez que é executada uma operação para modificar uma String, o que ocorre é a criação de um novo objeto, enquanto o objeto String original permanece inalterado. A JVM mantém uma área especial chamada de pool de Strings. Cada vez que é atribuído uma String a uma variável, é feita uma busca no pool a fim de encontrar uma String idêntica. Se existir, a referência a nova String é direcionada a String existente. Caso contrário, é criada uma nova String no pool. A classe String fornece diversos métodos utilitários. Seguem os mais utilizados: ● equals: Retorna true se as duas Strings possuírem o mesmo tamanho e exatamente os mesmos caracteres. O método equalsIgoreCase não diferencia letras maiúsculas e minúsculas. ● replace: Este método faz a substituição de um determinado conjunto de caracteres por outro, retornando uma nova String. O método é case sensitive. ● trim: Retorna uma String sem os espaços em branco no começo e no final da mesma. ● contains: Este método avalia se a String original possui a String passada por parâmetro. Retorna um valor booleano. ● lenght: Retorna o tamanho da String.
  • 14. Sintaxe da Linguagem Java Rosicléia Frasson 13 ● toUpperCase: Retorna uma nova String com todos os caracteres em maiúsculo. ● toLowerCase: Retorna uma nova String com todos os caracteres em minúsculo. ● charAt: Retorna o caracter que se encontra na posição passada por parâmetro da String. ● substring: Retorna um objeto String contendo os caracteres especificados entre o intervalo de valores passados como argumentos para o método. ● valueOf: Retorna uma String a partir de uma dado numérico. É um método estático, sendo assim, não pertence a um objeto e sim a classe String. public class UtilitariosString { public static void main(String[] args) { String frase1 = "O rato roeu a roupa do rei de roma."; System.out.println(frase1.replace('r', 'p')); String frase2 = " É melhor prevenir do que remediar. "; System.out.println(frase2.trim()); String frase3 = "Um é pouco, dois é bom, três é demais"; System.out.println(frase3.contains("dois")); System.out.println(frase3.length()); System.out.println(frase3.toUpperCase()); System.out.println(frase3.toLowerCase()); System.out.println(frase3.substring(12,22)); System.out.println("dois".equals("dois")); System.out.println("dois".equalsIgnoreCase("DOIS")); System.out.println(frase3.charAt(8)); String numeroCasa = String.valueOf(45); } } Para transformar uma String em um tipo numérico, é necessário utilizar as classes de ajuda para os tipos primitivos correspondentes: ● Integer.parseInt: Para conversões para o tipo inteiro; ● Double.parseDouble: Para conversões para o tipo double. ● Long.parseLong: Para conversões para o tipo long. ● Float.parseFloat: Para conversões para o tipo float. ● Short.parseShort: Para conversões para o tipo short. ● Byte.parseByte: Para conversões para o tipo byte. int idade = Integer.parseInt(JOptionPane.showInputDialog("Informe sua idade: ")); double peso = Double.parseDouble(JOptionPane.showInputDialog("Informe o seu peso: ")); float altura = Float.parseFloat(JOptionPane.showInputDialog("Informe sua altura: ")); long matricula = Long.parseLong(JOptionPane.showInputDialog("Informe sua matrícula: "));
  • 15. Sintaxe da Linguagem Java Rosicléia Frasson 14 Estruturas condicionais Comando if … else A estrutura if ... else permite expressar duas alternativas de execução, uma delas executa caso a condição seja verdadeira e a outra quando a condição não for satisfeita. A expressão contida dentro do comando if deve resultar em um valor booleano. A cláusula else é opcional. if (expressão){ bloco de comandos }else{ bloco de comandos } Quando houver apenas um comando dentro do bloco if ou do bloco else, não é necessário o uso das chaves. É possível construir uma série de testes através do encadeamento de um outro if na cláusula else. Quando houver comandos if aninhados, cada else está relacionado ao if que estiver dentro do mesmo bloco que ele. Segue um exemplo de utilização do comando if … else de um aplicativo que exibe uma mensagem conforme a situação do aluno: aprovado, em recuperação ou reprovado. import java.util.Scanner; public class CondicaoIfElse { public static void main(String[] args) { Scanner entrada = new Scanner(System.in); System.out.println("Informe a média do aluno: "); double media = entrada.nextDouble(); if (media >= 7){ System.out.println("Aluno aprovado!"); }else if (media >= 4){ System.out.println("Aluno em recuperação!"); }else{ System.out.println("Aluno reprovado!"); } entrada.close(); } } Comando switch O comando switch permite transferir o fluxo de controle para uma entrada rotulada em um bloco de comandos, baseado no valor de uma expressão. A expressão deve ser do tipo inteiro ou um valor enumerado. Em outras palavras, o comando switch faz o teste da expressão de seleção contra os valores das constantes indicados nas cláusulas case, até que um valor verdadeiro seja obtido.
  • 16. Sintaxe da Linguagem Java Rosicléia Frasson 15 switch (expressão){ case constante1: bloco de comandos; break; case constante2: bloco de comandos; break; ••• default: bloco de comandos; } Se não for encontrado um rótulo case que combine com o valor da expressão switch, o fluxo de controle é transferido para o primeiro comando que segue o rótulo default. O rótulo default é opcional. Vale mencionar que um rótulo case ou default não força uma saída para fora do switch, nem implica no final da execução dos comandos. Para forçar a saída do switch, é necessário utilizar o comando break. Segue um trecho de código com a utilização do comando switch. import java.util.Scanner; public class CondicaoSwitch { public static void main(String args[]) { Scanner entrada = new Scanner(System.in); System.out.println("Informe um dia da semana"); int diaDaSemana = entrada.nextInt(); 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"); 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!"); }
  • 17. Sintaxe da Linguagem Java Rosicléia Frasson 16 entrada.close(); } } Estruturas de repetição Comando for O comando for é usado quando é necessário repetir um bloco de comando sobre um intervalo de valores do ínicio ao fim. O laço for introduz uma nova mecanismo de definição de variáveis, a declaração no laço de inicialização. Sendo assim, o escopo da variável é reduzido a região exata em que a mesma é necessária, ou seja, a variável existe apenas enquanto o laço estiver sendo executado. for (inicialização; condição; incremento){ bloco de comandos; } O comando for permite expressar iterações combinando uma expressão de inicialização, um teste de condição e uma expressão de incremento. ● inicialização: comando de atribuição que define o valor inicial da variável que controla o número de repetições. ● condição: expressão relacional que define até quando as iterações serão executadas. ● incremento: expressão que define como a variável de controle do laço deve variar ( pode aumentar ou diminuir). O teste da condição do controle é feito no início do laço, o que significa que se a expressão de condição for falsa os comandos dentro do laço não serão executados. Segue um exemplo de utilização do comando for. public class RepeticaoFor { public static void main(String[] args) { for (int num = 0; num <=10; num++){ System.out.println(num); } } } Comando while Como já mencionado no comando for, o comando while também é utilizado para repetir um trecho de código diversas vezes. No entanto este comando possui apenas a expressão de condição, a inicialização da variável de controle e o incremento não estão presentes na sintaxe do comando. while (condição){ bloco de comandos; }
  • 18. Sintaxe da Linguagem Java Rosicléia Frasson 17 A expressão de condição pode ser qualquer expressão ou valor que resulte em um verdadeiro ou falso. O laço while é executado enquanto a condição for verdadeira e o teste da condição de controle é feito no ínicio do laço, o que significa que se a expressão resultar em um valor falso, os blocos de comando dentro do laço não serão executados. Segue um exemplo de utilização do comando while. public class RepeticaoWhile { public static void main(String[] args) { int num = 0; while (num <= 10 ){ System.out.println(num); num++; } } } Comando do … while Similar ao comando while, porém, o teste da condição de controle é feito no fim do laço, o que significa que os comandos dentro do laço são executados pelo menos uma vez. do{ bloco de comandos; }while (condição); Segue um exemplo de utilização do comando do … while. import java.util.Scanner; public class RepeticaoDoWhile { public static void main(String[] args) { Scanner entrada = new Scanner(System.in); int num; do{ System.out.println("Informe um número: "); num = entrada.nextInt(); }while(num > 0); entrada.close(); } }
  • 19. Sintaxe da Linguagem Java Rosicléia Frasson 18 Instruções break e continue Os comandos break e continue são estruturas auxiliares dos fluxos de repetição. Ambos os comandos paralisam a execução antes do normal. O comando break pode ser utilizado com as instruções while, for, do … while e switch e ocasiona a saída imediata dessa instrução. A execução continua com o primeiro comando após a instrução de controle. public class ComandoBreak { public static void main (String args []){ for (int numero = 1; numero <= 1000; numero ++){ System.out.println("Número: "+ numero ); if (numero == 10) break; } } } O comando continue ignora as instruções restantes no corpo do loop e prossegue para a próxima iteração do laço. Pode ser utilizado nas estruturas de repetição for, while e do … while. Nos laços while e do … while o programa avalia o teste de condição do loop imediatamente após a execução da instrução continue. Nos laços for, a expressão de incremento é executada e então o teste de condição do loop é avaliado. public class ComandoContinue { public static void main(String[] args) { for (int num = 0; num <= 100; num ++){ if (num % 5 != 0){ continue; } System.out.println(num); } } } Comentários Comentário é a parte do código ignorada pelo compilador. É utilizado para deixar o código mais inteligível. Java possui três tipos diferentes de comentário: ● Comentário de uma linha: O uso de barra dupla marca o início do comentário que se estende até o fim da linha. ● Comentário de várias linhas: Os delimitadores /* e */ indicam início e fim de um comentário e podem conter várias linhas. ● Comentário javadoc: É utilizado para gerar a documentação javadoc e é delimitado pelas sequências de símbolos /** e */. Para gerar o javadoc é necessário que o comentário esteja localizado imediatamente antes da classe, atributo ou método documentado.
  • 20. Sintaxe da Linguagem Java Rosicléia Frasson 19 Arrays Uma variável em Java corresponde a uma posição de memória, cujo conteúdo pode ser alterado durante a execução do programa. Embora uma variável possa assumir diversos valores, ela só pode armazenar um valor a cada instante. Quando é necessário que mais de um valor do mesmo tipo seja armazenado, pode ser utilizada uma estrutura chamada vetor ou array. Como o array pode guardar vários valores, em sua definição é necessário definir o seu tamanho, ou seja, a quantidade máxima de valores que o mesmo pode armazenar. A quantidade de elementos de um vetor é definida na criação do mesmo e não pode ser alterada. String[] nome = new String[10]; Para declarar um vetor, é necessário colocar um par de colchetes antes ou depois do nome da variável. Também é necessário reservar um espaço na memória e definir o tamanho do vetor, ou seja, a quantidade total de elementos que podem ser armazenados no vetor. O operador new reserva espaço de memória para alocar os elementos. Implicitamente cada elemento no array é inicializado com um valor padrão, sendo 0 para numéricos primitivos, false para booleanos e null para objetos. Os objetos arrays possuem um campo length que indicam a quantidade de elementos do array. nome[0] = "Maria"; Ao armazenar uma informação em um vetor é necessário indicar a posição em que esta será alocada. Nos arrays em Java a primeira posição possui índice 0 e o mesmo aumenta gradativamente até o número de posições reservadas menos um. Uma tentativa ao acesso de uma posição fora dos limites do array lança uma exceção ArrayIndexOutOfBoundsException. Um array pode ser inicializado com valores entre chaves que seguem a sua declaração separados por vírgulas. String [] frutas = {"Abacaxi", "Acerola", "Morango", "Jaca", "Jabuticaba"}; Quando um array é inicializado dentro da sua declaração, não existe a necessidade da criação do vetor usando new. Neste caso, o tamanho do array é determinado pela quantidade de valores fornecidos na inicialização. import java.util.Scanner; public class Vetor { public static void main(String[] args) { Scanner entrada = new Scanner(System.in); String[] nome = new String[6]; for (int i = 0; i < 6; i++){ System.out.println("Informe o aluno " + i + " :");
  • 21. Sintaxe da Linguagem Java Rosicléia Frasson 20 nome[i] = entrada.nextLine(); } System.out.println("nAlunos: "); for(int i = 0; i < nome.length; i++){ System.out.println(nome[i]); } entrada.close(); } } Estrutura de repetição for each O comando for each possui como objetivo facilitar o loop em um array ou em uma coleção e é indicado para percorrer todo o conjunto de dados, sem a necessidade de indicar o tamanho do mesmo. Os loops for each ficam mais legíveis e tendem a minimizar as oportunidades de erros pela ocultação do iterador, sem perda de desempenho. for ( declaração: expressão){ bloco de comandos; } Na declaração é necessário indicar o tipo de dado presente no array ou coleção e atribuir um identificador. Caso o tipo de dado indicado na declaração for diferente do tipo de dado dos elementos do array, o código não compila. A expressão consiste no array ou coleção que deve ser percorrida. Cada vez que o loop é executado, a variável do laço assume o próximo valor do conjunto e o bloco de comandos é executado. Normalmente a variável do laço é utilizada dentro do bloco de comandos. Esse processo continua até o término do conjunto de dados. É importante ressaltar que a instrução for-each pode ser usada apenas para obter elementos de um array, ela não pode ser utilizada para modificar os elementos. Em outras palavras, não é possível adicionar, remover ou alterar um valor do array utilizando o comando for aprimorado, nesses casos deve ser utilizada a estrutura for padrão. public class ComandoForAprimorado { public static void main(String[] args) { int somaNumeros = 0; int [] numeros = {87, 45, 65, 32, 44, 26, 7, 90}; for(int numero: numeros) somaNumeros += numero; System.out.println("Soma dos elementos do vetor: " + somaNumeros); } }
  • 22. Sintaxe da Linguagem Java Rosicléia Frasson 21 Pacotes Os pacotes possuem como objetivo agrupar classes de funcionalidades semelhantes ou relacionadas. Um pacote é um diretório onde ficam armazenadas classes, interfaces, subpacotes e arquivos de recursos adicionais, como imagens, usados pelas classes do pacote. Os pacotes são correspondentes as bibliotecas em outras linguagens de programação. A utilização de pacotes promove a reutilização de código, auxilia na manutenção e promove os príncipios de encapsulamento e modularidade da orientação a objetos. O empacotamento é recomendado pelos padrões de programação Java a fim de diminuir a possibilidade de colisão de classes, ou seja, classes com o mesmo nome em um mesmo contexto. Com o intuito de evitar conflitos de nomes de pacotes e ao mesmo tempo possuir um nome significativo é utilizado um padrão para a nomeação de pacotes: ● Nomes de pacotes devem ser compostos exclusivamente por letras minúsculas, não importando a quantidade de palavras que o mesmo contenha; ● Os nomes de pacotes devem ser relativos a empresa que desenvolveu os mesmos. Geralmente é utilizada a nomeação reversa de domínios, onde o início do nome do pacote é dado pela ordem inversa do nome do domínio da instituição na internet. Em Java, as classes devem possuir como primeira instrução a indicação do pacote a que pertencem. A instrução começa com a palavra chave package, seguida pelo caminho do pacote delimitado por pontos. Classes que não possuem a instrução package pertencem ao pacote default que correspondem a raiz do projeto. package br.com.nomeempresa.sintaxeBasica; Classes declaradas sem o modificador de visibilidade public ficam invisíveis para outros pacotes. Classes que não possuem utilidade fora do pacote em que estão declaradas devem possuir o modificador de acesso default. A utilização de classes fora do pacote a que pertencem, necessita da indicação do caminho onde estão armazenadas. Isso pode ser feito de duas formas: através do nome plenamente qualificado do tipo ou através da importação do pacote. A utilização do nome plenamente qualificado é uma opção viável. No entanto, pode ser tedioso e causar confusão no código, se levando em consideração que os pacotes possuem nomes longos. javax.swing.JOptionPane.showMessageDialog(null, "Exemplo utilização de nome plenamente qualificado do tipo"); A outra maneira de utilizar classes de um pacote, é importar parte ou todo o pacote através da instrução import. A instrução import permite que código fonte de classes de outros pacotes sejam incluídas dentro de um código fonte em tempo de compilação. A instrução import inclui a palavra chave import seguida pelo caminho do pacote, delimitado com pontos e terminando com o nome de uma classe ou o coringa *. As instruções import ocorrem depois da instrução package e antes da definição de classe. import javax.swing.JOptionPane; public class Pacote { public static void main(String[] args) { JOptionPane.showMessageDialog(null, "Exemplo utilização de importação de
  • 23. Sintaxe da Linguagem Java Rosicléia Frasson 22 pacote"); } } A API do JSE é composta por vários pacotes. Todos os pacotes iniciados por java ou javax fazem parte da API padrão. As funcionalidades dos mesmos são detalhadas na documentaçao do Java. Na tabela a seguir, estão os pacotes mais utilizados e uma descrição sucinta dos mesmos: Funcionalidade Pacote Fornece classes que são fundamentais para a concepção da linguagem Java. É importado automaticamente. java.lang Pacote utilitário. Fornece classes para trabalhar com coleções, entrada de dados (Scanner) e componentes de data e hora. java.util Fornece classes para definir interfaces gráficas com o usuário. java.awt Extensão do pacote java.awt. javax.swing Fornece classes para realizar operações de entrada e saída de dados através do sistema de fluxo de dados (streams) e serialização de objetos . java.io Classes para acesso a base de dados via JDBC. java.sql
  • 24. Orientação a objetos Rosicléia Frasson 23 Programação Orientada a Objetos Programar consiste em desenvolver softwares que executam determinadas funcionalidades. Um software pode ser descrito como uma série de instruções organizadas que operam sobre um conjunto de dados. Operar sobre um conjunto pequeno de dados é uma tarefa que pode ser facilmente executada. No entanto, a medida que a complexidade do software aumenta, trabalhar com um extenso conjunto de dados inter relacionado deixa de ser uma tarefa trivial. A Programação Orientada a Objetos, também conhecida pelas iniciais POO, oferece uma forma para tratar a complexidade citada, auxiliando na construção de softwares mais confiáveis e de fácil manutenção. O uso do paradigma orientado a objetos melhora a organização e reduz a quantidade de código em um software, além disso, toda a lógica de negócio fica encapsulada, o que garante que as responsabilidades são concentradas nos pontos certos, aumentando a flexibilidade. Na POO, um software é conceituado como um conjunto de objetos que interagem e mantém seu próprio estado local, fornecendo ações baseadas nesse estado. Cada objeto constitui uma parte separada do programa e interage com outras partes. Essa interação deve ser feita de maneira controlada, de modo que a representação do estado de um objeto deve ser privativa, ou seja, o estado de um objeto só pode ser acessado pelo próprio objeto. As classes constituem a unidade fundamental de um projeto orientado a objetos. São as classes que definem os objetos de um sistema e suas interações. Durante a execução de um software orientado a objetos, objetos são criados dinamicamente a partir de definições de classes. Princípios da programação orientada a objetos Os pilares que sedimentam a POO são: abstração, encapsulamento, herança, composição e polimorfismo: ● Abstração: Consiste em focar somente os aspectos importantes de determinado ponto de vista e desconsiderar os aspectos restantes. A abstração é um meio de reduzir a complexidade. Sendo assim, no modelo OO, a abstração significa concentrar-se no que é e no que faz um objeto e não em como o mesmo será implementado. ● Encapsulamento: Consiste em ocultar detalhes da implementação de uma classe. Utilizando o encapsulamento, os métodos devem ser o único meio de acessar os dados de um objeto. Os dados não podem ser acessados diretamente, isso assegura que um dado não seja modificado acidentalmente por funções externas ao objeto. ● Herança: Mecanismo da POO que permite a criação de classes derivadas de classes já existentes. As classes derivadas herdam atributos e métodos das classes bases. Sendo assim, existe uma significativa redução na quantidade de código das mesmas. ● Composição: É o mecanismo que permite o uso de uma ou mais classes para compor uma outra classe. Na composição uma classe é usada como tipo de atributo em uma outra classe, para que seus atributos possam ser utilizados. ● Polimorfismo: Mecanismo que garante que classes derivadas de uma mesma superclasse invoquem métodos com a mesma identificação, mas com comportamentos distintos. Em outras palavras, o polimorfismo é o mecanismo que permite escrever programas que processam objetos de uma mesma superclasse como se todos fossem do tipo da superclasse.
  • 25. Orientação a objetos Rosicléia Frasson 24 Notação UML A UML (Unified Modeling Language) é uma linguagem gráfica para a modelagem de sistemas de software que ajuda na descrição e no projeto de sistemas, particularmente daqueles construídos utilizando o estilo orientado a objetos. Ela é composta por uma série de diagramas que estão divididos em diagramas estruturais e de comportamento. Dentre os diagramas estruturais, um deles, o diagrama de classes, possibilita modelar com clareza os principais conceitos da orientação a objetos. A criação de um modelo de classes resulta de um processo de abstração no qual são identificados os objetos relativos ao contexto que se pretende modelar. Além disso, este modelo descreve os membros das classes, como atributos e métodos, identificando com clareza a visibilidade de cada membro. O diagrama de classe também fornece as relações existentes entre as classes. Objetos Um objeto é a unidade central da POO. Em um sistema computacional pode ser definido como uma abstração de alguma coisa em um determinado domínio. Essa abstração deve permitir que o software mantenha informações sobre a mesma e interaja com ela. Sendo assim, um objeto em um software é algo que se visualiza, se utiliza e pode assumir um papel. Em uma definição mais informal, um objeto é qualquer entidade do mundo real que possui um estado e um conjunto definido de operações para funcionar nesse estado. O estado é composto por um conjunto de características do objeto. As operações fornecem serviços a outros objetos quando estes solicitam a realização de uma ação. Quando um programa é construído utilizando o paradigma orientado a objetos, é necessário descobrir os objetos que assumem um papel no domínio do problema. Após a descoberta, devem ser analisados os aspectos relevantes ao problema que o software deve resolver. O mesmo tipo de objeto pode requerer características e comportamentos distintos em domínios de negócios distintos, ou seja, um objeto carro em um software para uma montadora possui um enfoque diferente de um carro em um software de uma locadora de veículos. Como os objetos em um software são independentes, softwares desenvolvidos usando POO, são mais fáceis de manter. Mudanças na implementação de um objeto ou adição de novas funcionalidades não devem afetar outros objetos do sistema. Além disso, os objetos podem ser componentes reusáveis, visto que um projeto pode utilizar objetos criados em projetos anteriores. Isso reduz os custos do projeto, visto que na reutilização são aproveitados objetos já implementados e validados. Classes Uma classe é a especificação para a criação de um objeto, ou seja, uma classe fornece a estrutura necessária para que um objeto possa ser criado. Sendo assim, ela descreve as propriedades e funcionalidades de um objeto em forma de atributos e métodos. Além dos atributos e métodos, uma classe pode possuir classes aninhadas. Uma classe aninhada ou interna é uma classe declarada dentro de outra classe. Vale ressaltar que uma declaração de classe cria um tipo. Em Java a declaração de uma classe não cria um objeto. Os objetos devem ser explicitamente criados. Sendo assim, é correto afirmar que uma classe é o projeto de um objeto. Este projeto possui como objetivo orientar a JVM na criação de um objeto. Cada objeto criado possui valores próprios para os atributos da classe. Na notação UML, uma classe é representada como um retângulo vertical com três seções. O
  • 26. Orientação a objetos Rosicléia Frasson 25 nome da classe do objeto está na seção superior, os atributos da classe estão na seção intermediária e as operações associadas a classe estão na seção inferior do retângulo. Em Java, uma classe é definida utilizando a palavra chave class. Após a palavra chave class, deve seguir o nome da classe, que deve ser um identificador válido. Os membros de uma classe - atributos, métodos e classes aninhadas - são listados entre as chaves após a declaração. Na declaração de uma classe também é informado o modificador de acesso. O modificador public indica que a classe é publicamente acessível, ou seja, outras classes podem declarar referências a objetos da classe e acessar seus membros public. Para nomear classes por convenção devem ser usados substantivos. A primeira letra deve ser maiúscula. Na concatenação de palavras a primeira letra de cada palavra deve ser maiúscula. Um outro cuidado é que o nome de uma classe deve descrever o que ela faz. Atributos Na definição de classes foi descrito que uma classe possui propriedades que determinam o estado de um objeto. Essas propriedades de uma classe são denominadas atributos ou variáveis de instância. Uma variável de instância possui valores distintos para cada objeto criado. Uma declaração de atributo é composta pelo tipo do atributo, que pode ser um tipo primitivo ou um objeto, seguido por um identificador e opcionalmente uma claúsula de inicialização que fornece ao atributo um valor inicial. Vale ressaltar que se o atributo não possuir um valor inicial explicitamente declarado, um valor inicial padrão é atribuído. Para tipos numéricos o valor padrão é 0, para booleanos o valor padrão é false e para objetos é null.
  • 27. Orientação a objetos Rosicléia Frasson 26 Um ponto crucial para a criação de atributos significativos para o objeto é um estudo do escopo do problema que o software deve resolver. Métodos Dentro da POO, os métodos representam o mecanismo de comunicação entre os objetos. A troca de informações entre os objetos é feita através de parâmetros e valores de retorno dos métodos. Além disso, um método pode mudar o estado do objeto, ou seja, um método pode alterar o valor de um ou mais atributos que estão contidos no objeto. Uma declaração de um método é composta de duas partes: cabeçalho e corpo do método. No corpo do método fica o código executável que possui a função de manipular os dados armazenados nos objetos. Já o cabeçalho do método é composto por um conjunto opcional de modificadores, o tipo de retorno do método, a assinatura do método e uma claúsula throws opcional que relaciona as exceções lançadas pelo método. A assinatura de um método consiste no nome do método e na lista de parâmetros entre parênteses, que pode ser vazia. Obrigatoriamente todos os métodos devem possuir uma assinatura e um tipo de retorno. Os métodos que não possuem retorno usam a palavra chave void como tipo de retorno. Métodos void não retornam nenhuma informação para a classe que o chamou. Para os métodos com retorno, é utilizado o tipo de retorno que pode ser um tipo primitivo ou uma classe Java. Os métodos com retorno podem retornar apenas um único resultado, seja um valor primitivo ou a referência a um objeto. O fato de um método possuir retorno ou não, altera o encerramento da execução. Quando um método não possui valor de retorno, a execução é encerrada quando o bloco do corpo do método chega ao final. Já quando o método possui valor de retorno, a execução é encerrada através do comando return.
  • 28. Orientação a objetos Rosicléia Frasson 27 Os métodos podem receber argumentos representados por uma lista de parâmetros separados por vírgula, onde para cada parâmetro é indicado o tipo e o nome. Todos os parâmetros de métodos são passados por valor, independente de serem tipos primitivos ou objetos. Parâmetros do tipo objeto passam a referência ao objeto e não o próprio objeto. Dessa forma, se o estado do objeto for alterado durante a execução do método, o objeto é alterado para cada parte do programa que possui uma referência para ele. Vale ressaltar que um parâmetro de um método é uma variável local. Isso significa que ao fim da execução do método ela deixa de existir. Para serem executados os métodos devem ser invocados. Métodos são invocados como operações sobre objetos através de referências. Os métodos com parâmetros quando invocados, obrigam o invocador a fornecer um argumento do tipo apropriado para cada um dos parâmetros declarados pelo método. referencia.método (argumentos); Quando um método é invocado, o fluxo de execução passa para o método invocado e os comandos deste são executados em sequência. Um método retorna ao invocador em uma das três condições: a execução de um comando return, o bloco de execução acaba nos casos dos métodos void ou uma exceção não capturada é lançada. Sobrecarga de métodos A sobrecarga de métodos ou overloading é o mecanismo que permite a criação de vários métodos com o mesmo nome, mas com possibilidades de entradas diferentes. Essas entradas que consistem nos parâmetros dos métodos devem ser tipos diferentes, quantidade de parâmetros distintas
  • 29. Orientação a objetos Rosicléia Frasson 28 ou posições de tipos diferentes. A sobrecarga é comumente utilizada quando é necessário criar métodos que realizem as mesmas tarefas, porém com tipos de dados diferentes ou números distintos de argumentos. O compilador distingue os métodos sobrecarregados pela sua assinatura, sendo assim, não é possível declarar métodos com a mesma assinatura e tipos de retorno distintos, pois no momento da invocação do método, o compilador não seria capaz de determinar a versão do método a ser chamada porque o valor de retorno é ignorado. A API do Java contempla uma série de métodos sobrecarregados, um bom exemplo é o método max da classe Math, que possui quatro métodos sobrecarregados que possuem como objetivo retornar o maior valor de dois números. Métodos da classe Object Em Java todos os objetos derivam da classe Object. A classe Object possui uma série de métodos que podem ser utilizados pelas classes criadas. Dentre eles, os mais importantes são: ● toString O método toString possui como objetivo retornar a representação String de um objeto, ou seja, retorna uma String que textualmente representa esse objeto. Este método é chamado automaticamente quando um objeto é passado para print ou para um operador de concatenação de Strings. O método toString de Object retorna a String com o package, o nome da classe, o caracter @ e um número de identidade em hexadecimal. br.com.rosicleiafrasson.oo.Produto@58c3d9ac
  • 30. Orientação a objetos Rosicléia Frasson 29 Para retornar informações mais concisas sobre o objeto, o toString pode ser reescrito. public String toString() { return "Produto " + "nCódigo: " + codigo + "nNome: " + nome + "nPreço: " + preco ; } ● getClass O método getClass retorna informações do objeto como o package e o nome da classe. ● equals O método equals faz a comparação entre dois objetos e retorna o valor true se ambos ocuparem o mesmo espaço de memória. O método equals pode ser reescrito para que outros critérios de comparação sejam utilizados. Métodos com um número variável de parâmetros A partir do Java 5, os métodos podem ser construídos com uma quantidade variável de parâmetros. Tais métodos são chamados de varargs. Na declaração de um método varargs, o último parâmetro é declarado como uma sequência de um dado tipo. Para indicar que um parâmetro é uma sequência são colocadas reticências (...) após o tipo do parâmetro. Os parâmetros de sequência permitem que a invocação do método tenha um número variável de argumentos, incluindo zero. Quando um parâmetro é declarado como uma sequência, o compilador constrói implicitamente um array e adiciona neste os elementos passados como argumento. Apenas um parâmetro de sequência é permitido por método. public double calculaValorVenda (double ... precosProdutos){ double valorTotal = 0; for (double preco : precosProdutos) { valorTotal += preco; } return valorTotal; } Quando um parâmetro é declarado como uma sequência, o compilador constrói um array do tipo especificado pelo parâmetro de sequência e armazena os argumentos passados nesse array. Instâncias de classes Uma classe é a especificação de um objeto. No entanto, para ser criado, um objeto precisa ser instanciado. Quando um objeto é criado, ele adquire espaço em memória para armazenar seu estado e um conjunto de operações podem ser aplicadas ao mesmo. Sendo assim, para atribuir valores a quaisquer atributos e invocar métodos é necessária a instanciação de um objeto da refererida classe. A maneira mais comum de instanciar um objeto é através da palavra chave new. Para a criação
  • 31. Orientação a objetos Rosicléia Frasson 30 de um objeto através do comando new, é necessário especificar o tipo de objeto que deve ser criado e os argumentos da sua construção. O new aloca espaço para armazenar os campos do objeto e os inicializa. Quando a inicialização está completa, o sistema de execução retorna uma referência ao novo objeto. É importante ressaltar que no momento da alocação se o sistema não encontra espaço suficiente para criar o objeto, ele efetua uma coleta de lixo para tentar recuperar espaço. Após a coleta se não existir espaço livre, é lançada uma exceção: OutOfMemoryError. Construtores Quando a palavra chave new é utilizada, um objeto é construído. A palavra chave new executa o construtor da classe. Construtores são blocos de código que são usados para inicializar um objeto, antes que a referência seja retornada por new. Um construtor é um bloco declarado com o mesmo nome da classe seguido por uma lista de parâmetros entre parênteses. Os argumentos passados ao construtor podem inicializar informações. Sendo assim, os construtores podem obrigar a passagem de argumentos para o objeto durante o processo de criação do mesmo. Vale ressaltar que o construtor é invocado após os atributos terem sido configurados com seus valores iniciais default. Um construtor não possui valor de retorno.
  • 32. Orientação a objetos Rosicléia Frasson 31 Em uma classe em que não existe um construtor declarado, a JVM cria implicitamente um construtor default. O construtor default não recebe nenhum argumento e seu corpo é vazio. A partir do momento em que um construtor é declarado, o construtor default deixa de ser fornecido. Uma classe pode ter mais de um construtor. Desde que a lista de argumentos seja diferente. Neste caso, no momento da instanciação do objeto é necessário escolher o construtor apropriado. Um construtor pode invocar outro construtor da mesma classe usando a invocação this() como seu primeiro comando executável. Se o construtor a ser invocado possui argumentos, os mesmos podem ser passados na invocação do construtor. O construtor invocado é determinado pela quantidade e tipo de argumentos usados. Palavra chave this A palavra chave this é usada para passar uma referência ao objeto atual. Comumente é usada quando o nome do campo a ser acessado é o mesmo nome de uma variável local ou parâmetro.
  • 33. Orientação a objetos Rosicléia Frasson 32 O this permite uma diferenciação entre atributos e parâmetros de métodos. Dessa forma, é possível ter o mesmo identificador para uma variável de instância e um parâmetro de método. Essa prática tende a deixar o código mais legível e amigável. Atributos estáticos Os atributos estáticos consistem em campos pertencentes as classes, ou seja, não existe uma cópia do atributo para cada objeto. Sendo asssim, todos os objetos compartilham a mesma cópia da variável. Um campo estático deve ser declarado com o modificado static. Variáveis estáticas possuem escopo de classe. Sendo assim, elas podem ser acessadas por meio de uma referência a qualquer objeto da classe ou pelo nome da classe, seguido pelo atributo. As variáveis estáticas são inicializadas quando uma classe é carregada. Uma classe é carregada pela JVM quando uma instância da mesma é criada pela primeira vez ou quando uma variável ou método estático é utilizado. Vale mencionar que as variáveis estáticas são inicializadas antes que qualquer objeto da classe possa ser criado e antes de qualquer método estático da classe ser executado.
  • 34. Orientação a objetos Rosicléia Frasson 33 Métodos estáticos Os métodos estáticos realizam procedimentos sem estarem vinculados a um objeto. Sendo assim, eles pertencem a uma classe e não a uma instância da mesma. Em outras palavras, um método estático pode ser executado sem a existência de uma instância da classe a que pertence. Os métodos estáticos só podem realizar operações sobre atributos estáticos, isto é, para a sua execução nenhuma instância específica da classe pode ser utilizada. Sendo assim, métodos estáticos também não podem utilizar métodos não estáticos. Métodos estáticos são adequados para métodos utilitários que não dependam do valor de uma variável de instância específica. Como exemplo de método estático da classe Java pode ser citado o método showMessageDialog da classe JOptionPane. É importante perceber que para utilizar o mesmo, não é necessária nenhuma instância da classe JOptionPane. Classe Math A classe Math é constituída por uma série de métodos estáticos para operações matemáticas,
  • 35. Orientação a objetos Rosicléia Frasson 34 entre elas potências, raízes, logaritmos, arredondamentos e operações trigonométricas. Além disso possui duas constantes, o PI e E. Por pertencer ao pacote java.lang não precisa ser instanciada. Seguem alguns métodos disponíveis na classe: ● Math.PI - Constante PI ● Math.pow(a, b) - Potência na forma ab ● Math.sqrt(a) - Raiz quadrada de a ● Math.cbrt(a) - Raiz cúbica de a ● Math.abs(a) - Retorna o valor absoluto de a ● Math.min(a, b) - Retorna o menor valor ● Math.max(a, b) - Retorna o maior valor ● Math.ceil(a) - Arredonda para cima ● Math.floor(a) - Arrenda para baixo Campo final Um campo final não pode ter seu valor alterado após ter sido inicializado. Sendo assim, ele é usado para definir uma propriedade imutável dentro de uma classe ou objeto. Na maioria dos casos os campos final são também campos estáticos. Isso significa que todos os objetos da classe compartilham um valor imutável. Por convenção os identificadores dos campos final devem possuir todas as letras maiúsculas. Nos casos de palavras compostas, as mesmas devem ser separadas pelo caractere underscore. Enum Em Java, um Enum é um tipo especial de classe que corresponde a um conjunto fixo de constantes. Os Enums deixam o código menos vulnerável a erros de programação e mais legível. A declaração de uma enumeração é similar a declaração de uma classe, exceto que ao invés da palavra chave class, é utilizada a palavra chave enum. Outra particularidade é que antes de declarar qualquer membro da classe, é necessário declarar todas as constantes de enumeração. Seguindo a convenção de constantes, o identificador é escrito com todas as letras em maiúsculas.
  • 36. Orientação a objetos Rosicléia Frasson 35 Agregação e composição Em um sistema orientado a objetos, é necessário que existam relacionamentos entre as classes. Para a UML, existem diversos relacionamentos possíveis. Entre eles, agregação e composição. Agregação é uma especialização da associação e indica que uma classe é parte de um todo. Ainda, que a parte pode existir sem o todo. Como exemplo pode ser citado o relacionamento entre um cargo e um funcionário. Se o funcionário deixar de existir, o cargo pode ser usado por um outro funcionário. Na UML, a agregação é representada por uma linha sólida com um losango vazio na extremidade que representa o todo. A composição é similar a agregação. No entanto, na composição a parte existe somente enquanto o todo existir. Como exemplo pode ser citada a relação que existe entre um pedido e os itens que estão contidos nesse pedido. Se o pedido deixar de existir, os itens relacionados a ele não fazem mais sentido. Na UML, a composição é representada por uma linha sólida com um losango preenchido na extremidade que representa o todo. Tanto a composição quanto a agregação são relacionamentos do tipo TEM UM. Na definição de classes Java, os dois relacionamentos se comportam da mesma maneira. Uma classe possui como um tipo de atributo uma outra classe.
  • 37. Orientação a objetos Rosicléia Frasson 36 Encapsulamento O encapsulamento consiste em ocultar dados e implementações da classe. Em outras palavras, membros de uma classe podem ser escondidos de forma a prever acessos indevidos. A orientação a objetos recomenda que o estado de um objeto deve ser mantido oculto. Os objetos devem ser manipulados apenas através de métodos públicos, dos quais apenas as assinaturas devem ser expostas. Vale ressaltar que apenas os métodos que são importantes para as classes externas devem ser visíveis. A utilização do encapsulamento protege as classes cliente contra os efeitos de uma alteração. Isso é possível porque o cliente conhece apenas a assinatura do método. Sendo assim, a implementação do mesmo pode ser alterada sem que nenhuma modificação na assinatura seja necessária. Outro ponto, é que o estado do objeto fica protegido contra modificações inválidas feitas pelas classes clientes. Visto que o estado só pode ser alterado através de métodos, é possível incluir validadores de dados nesses métodos ou lançar um erro ao cliente no caso de valores indevidos. Modificadores de acesso A restrição de acesso a classes e a membros da mesma é parte fundamental da orientação a objetos. Sendo assim, faz-se necessário um meio para restringir o acesso a classes e membros desta. Em Java, são utilizados os modificadores de acesso para controlar a visibilidade de classes, construtores, atributos e métodos. Existem quatro modificadores de acesso: private, default, protected e public.
  • 38. Orientação a objetos Rosicléia Frasson 37 O modificador public indica que a classe ou o membro pode ser acessado em qualquer parte do programa. Este modificador deve ser utilizado para construtores e métodos que devem ser acessados por outras classes. Também pode ser usado em métodos e constantes estáticas. Construtores e métodos de uso restrito e campos de dados de objetos não devem utilizar public como modificador. O modificador protected deixa os membros acessíveis a subclasses e classes do mesmo pacote. A ausência de um modificado de acesso, constitui o chamado modificador default. Este modificador deixa o membro acessível a classes do mesmo pacote. Classes cosntruídas com a ausência de modificador só podem ser instanciadas no pacote a que pertencem. O mesmo vale para os demais membros. Por fim, o modificador private deixa os membros acessíveis somente dentro da própria classe. Este modificador deve ser utilizado em atributos de classes, construtores e métodos que não devem ser acessados por outras classes. Gets e sets A visibilidade dos atributos pode ser restrita se aplicados os modificadores de acesso aos mesmos. No caso de um atributo com modificador private, os atributos só são acessíveis na própria classe. Isso significa que o estado das propriedades só pode ser alterado através de métodos públicos. Existe uma convenção para a criação de métodos que possuem como objetivo alterar ou recuperar o valor de uma propriedade com visiblidade restrita. Os métodos que possuem como objetivo alterar o valor da propriedade são chamados de métodos sets. Os métodos sets não retornam nenhum valor, portanto são métodos void. No entanto,
  • 39. Orientação a objetos Rosicléia Frasson 38 eles devem receber obrigatoriamente um argumento, que corresponde ao valor atribuído ao campo. Já os métodos que recuperam um valor são chamados de métodos gets. Os métodos gets obrigatoriamente possuem valor de retorno e não possuem argumentos. Herança O mecanismo de herança permite uma hierarquia entre classes. Sendo assim, novas classes podem ser criadas a partir de outras classes já existentes. As subclasses herdam as características e comportamentos das superclasses. Isto significa que a herança viabiliza o reúso de código. Normalmente, uma subclasse além de herdar membros da superclasse, também possui seus próprios atributos e métodos. Sendo assim, uma subclasse é mais específica que a sua superclasse, representando deste modo, um grupo mais especializado de objetos. As novas classes são chamadas de subclasses e as classes já existentes que deram origem as subclasses são chamadas de superclasses. Uma subclasse pode se tornar superclasse para outras subclasses. Ou seja, a herança pode ter vários níveis de hierarquia. Vale ressaltar que a herança é um relacionamento do tipo É UM. Sendo assim, um objeto de uma subclasse pode ser tratado como um objeto da superclasse.
  • 40. Orientação a objetos Rosicléia Frasson 39 A nível de codificação, a herança é implementada utilizando a palavra chave extends, seguida do nome da superclasse. Quando a máquina virtual cria um novo objeto que faz uso de herança, são definidas todas as variáveis pertencentes a classe e também as variáveis que estão definidas na superclasse. Quanto aos métodos, o objeto criado possui todos os métodos de sua classe e superclasse. Sempre que um método é chamado, a JVM verifica a classe do objeto; se o método não for encontrado, a JVM procura na superclasse dessa classe e assim sucessivamente até que o método seja encontrado. A referência aos métodos da superclasse é feita através da palavra-chave super. Para a chamada de métodos da superclasse, é utilizada a palavra chave super seguida do nome do método. O comando super também é utilizado para invocar um construtor da superclasse. Neste caso, é utilizada apenas a palavra super(), com os aurgumentos relativos ao construtor que deve ser invocado. public class Fabricante extends PessoaJuridica{ public Fabricante() { super(); } }
  • 41. Orientação a objetos Rosicléia Frasson 40 No Java a hierarquia de classes é iniciada com a classe Object, do pacote java.lang. Em outras palavras, implicitamente todas as classes extendem de Object e herdam os métodos desta superclasse. Por este motivo, todos os objetos criados possuem os métodos equals, toString, clone, getClass e hashCode. Diferente de outras linguagens, o Java não suporta herança múltipla. A herança múltipla permite que uma classe herde de mais de uma superclasse. Sobrescrita de métodos A sobrescrita de métodos ou overriding é o mecanismo que permite a alteração do comportamento de uma superclasse pelas suas subclasses, ou seja, a sobrescrita de um método é uma nova implementação para o mesmo. A sobrescrita de um método ocorre somente se a assinatura do mesmo permanece intacta, isto é, o tipo de retorno e os parâmetros devem ser os mesmos. A procura pelos métodos tem início no fim da hierarquia. Isso significa que quando um método é sobrescrito, a JVM executa o método definido na subclasse. Um exemplo clássico de overriding é a sobrescrita do método toString da classe Object por outras classes. Vale ressaltar que os métodos sobrepostos nunca devem ser mais restritivos do que os métodos originais. Isto significa que: ● Se o método original for public, a sobrescrita deste método obrigatoriamente terá modificador de acesso public; ● Se o método original for protected, a sobrescrita deste pode ser protected ou public; ● Se o método original não possuir modificador de acesso, a sobrescrita pode não possuir modificador, ser protected ou public; ● Se um método for private, ele não é visível pela subclasse, sendo assim, não pode ser sobrescrito. Modificador final O modificador final quando usado em uma declaração de classe impede que a mesma seja extendida. Muitas classes das API Java são final, como a classe String e a classe Math. Isso significa que é impossível extender as classes String e Math.
  • 42. Orientação a objetos Rosicléia Frasson 41 Classes devem ser marcadas como final para garantir que subclasses não sejam criadas a partir da mesma. Sendo assim, o modificador final deve ser usado apenas quando a classe já possuir todos os métodos implementados e nunca será necessário implementar um comportamento específico. Um método também pode possuir o modificador final. Neste caso, o método não pode ser sobrescrito pelas subclasses. O modificador final garante segurança a métodos não podem ser sobrescritos. Polimorfismo A herança e o polimorfismo em Java estão intimamente ligados. O polimorfismo em Java é o mecanismo que garante que quando um método é invocado por meio de uma referência a superclasse, em tempo de execução, a versão correta do método da subclasse é executada. Sendo assim, o polimorfismo garante que objetos de múltiplos tipos sejam referenciados como se fossem do tipo de sua superclasse. Em outras palavras, o polimorfismo permite que hierarquias inteiras sejam referenciadas a partir do tipo da superclasse. Sendo assim, um método que recebe como parâmetro o tipo Object, pode receber como argumento qualquer tipo de objeto, visto que em Java todas as classes extendem de Object. Classe abstrata Uma classe abstrata constitui uma classe que não pode ser instanciada. Classes são marcadas como abstratas ficam no topo ou nos níveis próximos ao topo da hierarquia e servem como modelo para as classes concretas. Sendo assim, as classes abstratas para serem utilizadas precisam herdadas por classes concretas. Uma classe abstrata pode conter métodos com sua implementação definida, os métodos concretos; e métodos que contenham apenas a assinatura, que são chamados de métodos abstratos.
  • 43. Orientação a objetos Rosicléia Frasson 42 Quando uma subclasse herda uma classe abstrata, obrigatoriamente todos os métodos abstratos devem ser sobrescritos, pois os mesmos não possuem implementação na superclasse. Uma classe abstrata pode ser extendida por outra classe abstrata. Dessa forma, a implementação dos métodos abstratos podem ser postergados para os níveis mais baixos da hierarquia. Na notação UML, o nome de uma classe abstrata é escrito em itálico. A mesma formatação também é aplicada para os métodos abstratos.
  • 44. Orientação a objetos Rosicléia Frasson 43 Interface Uma interface, assim como uma classe abstrata, possui como propósito forçar uma subclasse a reescrever todos os métodos abstratos, definindo um comportamento para eles. No entanto, as interfaces não possuem métodos concretos, apenas abstratos. Uma interface também não possui atributos, apenas constantes e variáveis estáticas. Uma interface não possui construtores. Os métodos declarados em uma interface devem ser implementados em todas as classes que implementam a interface. A implementação de uma interface por uma classe indica um relacionamento do tipo É UM com a interface. Uma classe pode implementar mais de uma interface. Uma interface pode estender outra interface. Se uma interface estendida por outra, for implementada por uma subclasse, esta última deverá implementar todos os métodos abstratos definidos nas duas interfaces.
  • 45. Orientação a objetos Rosicléia Frasson 44 Classes Wrappers As classes Wrappers fornecem um mecanismo para empacotar valores primitivos em um tipo objeto, para que estes sejam inclusos em atividades reservadas a objetos. Além disso, estas classes fornecem um conjunto de funções utilitárias para os tipos primitivos, como a conversão de um tipo primitivo em String e vice-versa. Com exceção da classe Character, as classes wrappers possuem dois construtores: um que recebe o tipo primitivo como argumento e outro que recebe uma String como argumento. Double d1 = new Double(1.0); Double d2 = new Double("1.0"); Integer i1 = new Integer(3); Integer i2 = new Integer("6"); As classes Wrappers fornecem métodos para conversão de uma String em um tipo primitivo correspondente. ● Boolean.parseBoolean; ● Byte.parseByte; ● Short.parseShort; ● Integer.parseInt; ● Long.parseLong; ● Float.parseFloat; ● Double.parseDouble; As classes wrappers também fornecem um método que retorna o tipo primitivo por ela encapsulado. Para efetuar essa conversão existem os métodos intValue, doubleValue, floatValue, booleanValue, byteValue, shortValue e longValue. Embora a partir do Java 5, existe o recurso de autoboxing que efetua o desencaixotamento de forma automática. Integer a = new Integer(12); int b = a.intValue(); Exceções Na linguagem de programação Java e na grande maioria das linguagens de programação, os métodos invocados são empilhados em uma estrutura de dados. Isso significa que quando um método termina a sua execução, o fluxo do programa volta para o método que o invocou, ou seja, o próximo
  • 46. Orientação a objetos Rosicléia Frasson 45 elemento da pilha. Caso aconteça alguma situação inesperada durante a execução do método, a JVM verifica se existe algum tratamento para o erro e em caso negativo, faz uma varredura nos métodos da pilha em busca de um tratamento para o problema. A inexistência de um tratamento para o erro gerado faz com que o programa seja encerrado. O mecanismo da linguagem Java relativo a exceções é baseado no conceito que as exceções são lançadas e capturadas. Quando uma exceção ocorre um objeto do tipo Exception é criado e lançado dentro do método. Se o método não capturar a exceção a mesma é passada para o invocador. Isso acontece sucessivamente até que a exceção seja capturada ou chegue na JVM, onde é capturada automaticamente. O trabalho com exceções se resume a decidir onde as exceções serão capturadas e como será o tratamento da mesma.
  • 47. Orientação a objetos Rosicléia Frasson 46 Todas as exceções herdam direta ou indiretamente da classe Throwable, formando uma hierarquia de herança. Como todas as exceções descendem de Throwable, todas herdam os métodos desta superclasse. Seguem os mais utilizados: Método Descrição getMessage Retorna uma descrição para a exceção. printStackTrace Exibe o rastreamento da pilha. toString Retorna um objeto String contendo uma descrição completa da exceção. Na hierarquia de exceções exibida anteriormente, pode ser observado que a classe Throwable possui as subclasses Error e Exception. As classes derivadas de Error representam situações graves durante a execução do programa e que não podem ser tratados pelo programador, como por exemplo, a JVM ficar sem espaço na memória. Geralmente os programas não conseguem se recuperar de um Error, sendo assim, não é necessário codificar um tratamento para o mesmo. A classe Exception e suas subclasses representam situações excepcionais que podem ser capturadas pelo aplicativo. Consequentemente podem ser tratadas. Dentro das exceptions ainda existem as exceções checadas e não checadas. As exceções que são instâncias ou subclasses da classe RuntimeException refletem erros na lógica do programa e não são verificadas pelo compilador. Isso significa que pode haver um tratamento para o erro, no entanto, não existe a obrigatoriedade desse tratamento. As exceções não checadas mais comuns são: ● ArithmeticException: Indica situações de erro em processamentos aritméticos. ● NumberFormatException: Exceção lançada na tentativa de converter uma String em um valor numérico, onde o conteúdo da mesma não representa um número adequado para o formato. ● ArrayIndexOutOfBoundsException: Indica a tentativa de acesso a um elemento de um array fora dos limites válidos. ● NullPointerException: Indica a tentativa de acessar a referência a um objeto que não foi criado. Já as exceções verificadas compreendem as classes derivadas de Exception e que não derivam de RuntimeException. Essas exceções necessariamente precisam ser tratadas e normalmente são
  • 48. Orientação a objetos Rosicléia Frasson 47 causadas por condições que não estão no controle do programa, como uma falha de conexão de rede ou uma resposta de um outro aplicativo. As exceções verificadas precisam ser tratadas. O tratamento de uma exceção através do bloco try catch. Dentro do bloco try são colocados os comandos que podem gerar uma exceção. O bloco try deve ser seguido por um ou mais blocos catch e/ou um bloco finally. Vale ressaltar que um método pode lançar várias exceções. Neste caso, todas as exceções que eventualmente possam ser lançadas devem ser tratadas. Nos blocos catch são capturadas as exceções. Cada bloco catch define o tipo de exceção que pode tratar. Vários blocos catch podem ser definidos para um mesmo bloco try. No entanto, apenas um será executado. O tipo de exceção deve coincidir com o tipo especificado em uma instrução catch. Se não coincidir a exceção não será capturada. A captura de uma exceção impede que o programa seja encerrado anormalmente. Quando uma exceção é lançada ela deve ser capturada e tratada em alguma parte do código fonte. Quando um programa não captura a exceção, a mesma é tratada pela JVM. O tratador de exceções padrão da JVM apenas encerra a execução e exibe uma mensagem de erro seguida por uma lista das chamadas de métodos que levaram a exceção. O bloco finally contém instruções que sempre serão executadas, independente de uma exceção ser lançada pelo try . Geralmente esse bloco possui instruções que liberam recursos utilizados durante o processamento do bloco try precisam ser liberados, independente da execução ter encerrado com
  • 49. Orientação a objetos Rosicléia Frasson 48 sucesso ou ter sido interrompida por uma exceção. O bloco finally será executado mesmo que exista um comando return no bloco try. Normalmente esse bloco é indicado para o fechamento de arquivos e operações de limpeza. A cláusula throws é utilizada para propagar a exceção para um nível acima na pilha de execução. Na cláusula throws são especificadas as exceções que o método pode lançar, porém não serão tratadas dentro do mesmo. Essa cláusula aparece após a lista de parâmetros e antes do corpo do método. Ela contém a lista de exceções que o método pode lançar caso algum problema ocorra em tempo de execução. Em Java, é possível que uma aplicação defina seu próprio tipo de exceção. Para criar um novo tipo de exceção é necessário que a classe extenda de uma das classes da hierarquia de exceções. O comando throw lança uma exceção manualmente.
  • 50. Collections Rosicléia Frasson 49 Collections Uma coleção é um objeto onde vários elementos podem ser agrupados. Em java, existe uma arquitetura para representar e armazenar as coleções. Essa arquitetura e composta por interfaces e classes concretas com uma série de métodos que realizam operações como inserção, remoção, pesquisa e ordenação dos elementos de uma coleção. List A interface List é responsável por armazenar elementos em forma de lista. Uma lista permite elementos duplicados e mantém os mesmos na ordem em que foram inseridos. A interface List resolve alguns problemas do array como tamanho infinito e métodos para inserção e pesquisa. A interface List possui as implementações ArrayList, LinkedList e Vector. ArrayList<String> arrayList = new ArrayList(); LinkedList<String> linkedList = new LinkedList(); Vector<String> vector = new Vector(); A interface List possui uma série de métodos. Seguem os mais utilizados:
  • 51. Collections Rosicléia Frasson 50 ● add: O método add adiciona no fim da lista um elemento. ● size: O método size retorna a quantidade de elementos que a lista possui. ● remove: O método remove retira um elemento da lista. ● contains: O método constains verifica se um elemento está na lista. ● sort: O método sort recebe um List como argumento e ordena em ordem crescente. Para efetuar a ordenação um objeto precisa implementar a interface Comparable que define o método compareTo. ● min: Retorna o menor elemento da coleção. ● reverse: O método reverse inverte a lista. Set Um conjunto Set não permite elementos duplicados. Os elementos possuem uma forma especial de ordenação. A interface Set deve ser utilizada quando a ordem dos elementos não é importante, visto que performance é muito superior a List. Collection<Integer> colecao = new HashSet<Integer>(); long tempoInicial = System.currentTimeMillis(); for (int i = 0; i < 10000000; i++) { colecao.add(i); } for (int i = 0; i < 10000000; i++) {
  • 52. Collections Rosicléia Frasson 51 colecao.contains(i); } long tempoFinal = System.currentTimeMillis(); System.out.printf("Tempo em milisegundos: ", (tempoFinal - tempoInicial));
  • 53. Conexão com a base de dados JDBC Rosicléia Frasson 52 Conexão com a base de dados As bases de dados estão presentes em nossa sociedade há muito tempo e correspondem a um conjunto de dados inter relacionados referentes a um determinado domínio. Antes dos advento dos computadores, as empresas armazenavam seus dados em arquivos físicos. Com a popularização da informática, esses dados passaram a ser armazenados em softwares específicos para este fim. A estes softwares damos o nome de SGBD. Um Sistema Gerenciador de Banco de Dados possui um ambiente adequado e eficiente para armazenamento e recuperação de dados. Modelo Entidade-Relacionamento O modelo entidade-relacionamento é composto por atributos, entidades compostas pelos atributos e o relacionamento entre as entidades. Entidades : São objetos do mundo real dentro do domínio da aplicação, que possuem informações necessárias para armazenamento na base de dados. A entidade é representada por um retângulo que contém o nome da entidade. Atributos: São as propriedades que descrevem as entidades. Poderiam ser atributos da entidade livro, por exemplo, o título, autor, edição, ano de publicação e a editora. Chaves: São atributos ou conjuntos de atributos que permitem identificar sem ambiguidade cada instância de uma entidade, ou seja, garante a distinção entre as ocorrências das entidades. Relacionamentos: São associações entre duas entidades ou entre uma entidade e ela mesma. O relacionamento é representado por um losango. Esse losango é ligado por linhas aos retângulos que representam as entidades participantes do relacionamento.
  • 54. Conexão com a base de dados JDBC Rosicléia Frasson 53 Tipos de relacionamento: Existem três tipos de relacionamento entre as entidades. ● um para um: é usado quando uma entidade A, se relaciona com uma entidade B e vice-versa. Este relacionamento é representado pelo sinal 1:1. ● um para muitos: é usado quando uma entidade A pode se relacionar com uma ou mais entidades B. Este relacionamento é representado pelo sinal 1:N. ● muitos para muitos: é usado quando várias entidades A se relacionam com várias entidades B. Este relacionamento é representado pelo sinal N:M ou N:N. Modelo Relacional O modelo relacional representa os dados em uma base de dados como uma coleção de tabelas (relações). Todas as tabelas possuem um nome e um conjunto de atributos com seus respectivos nome e domínios. Tabela: É onde as informações ficam armazenadas. Atributos: São todas as informações que existem em uma tabela. Essas informações também são chamadas de campos. Domínio: Representa todos os valores possíveis que um atributo pode receber. Tuplas: Representam as informações armazenadas em uma tabela. Informalmente as tuplas são chamadas de registros. Chave primária: É uma coluna ou um conjunto de colunas cujos valores distinguem uma linha
  • 55. Conexão com a base de dados JDBC Rosicléia Frasson 54 das demais dentro da tabela. Chave estrangeira: É uma coluna ou uma combinação de colunas, cujos valores aparecem necessariamente na chave primária de uma tabela. A chave estrangeira permite a implementação dos relacionamentos em um banco de dados. Exemplo Supermercado Linguagem SQL A linguagem SQL - Structured Query Language - é a linguagem padrão utilizada para gerenciar a base de dados. O SQL é uma linguagem padrão para a grande maioria das bases de dados, embora existam algumas variações entre fabricantes diferentes de SGBDs. A linguagem SQL está subdividida em duas linguagens: DML e DDL. Os comandos contidos neste documento são baseados no SGBD da Oracle. DDL A linguagem DDL - Data Definition Language - é composta por comandos usados para alterar a estrutura da base de dados. Em outras palavras, comandos para inserir, atualizar e apagar a estrutura da base de dados. Seguem os comandos mais utilizados: CREATE TABLE É o comando utilizado para criar uma tabela na base de dados. As tabelas são organizadas por linhas e colunas. As tabelas e as colunas da mesma devem possuir um identificador. CREATE TABLE nome_tabela ( nome_coluna1 tipo_dado (tamanho), nome_coluna2 tipo_dado (tamanho), nome_coluna3 tipo_dado (tamanho), .... );
  • 56. Conexão com a base de dados JDBC Rosicléia Frasson 55 ALTER TABLE Comando utilizado para adicionar, remover ou alterar uma coluna de uma tabela. ● Para adicionar uma coluna: ALTER TABLE nome_tabela ADD nome_coluna tipo_dado; ● Para remover uma coluna: ALTER TABLE nome_tabela DROP COLUMN nome_coluna; ● Para editar uma coluna: ALTER TABLE nome_tabela MODIFY COLUMN nome_coluna tipo_dado; DROP TABLE Comando que elimina todos os dados e a estrutura da tabela. DROP TABLE nome_tabela; RENAME Comando utilizado para renomear uma tabela ou sequência. DROP TABLE nome_tabela; NOT NULL Garante a não existência de valores nulos para a coluna. Deve ser definido para cada coluna. UNIQUE A restrição unique bloqueia a possibilidade de registros repetidos para uma coluna, ou seja, garante que todos os valores de uma coluna sejam diferentes.
  • 57. Conexão com a base de dados JDBC Rosicléia Frasson 56 PRIMARY KEY Uma primary key é utilizada para identificar de forma única cada linha em uma tabela. A coluna referente a chave primária não pode conter valores nulos e/ou repetidos. As chaves primárias podem ser especificadas quando a tabela é criada ou com a alteração de estrutura com o comando alter table. FOREING KEY Uma chave estrangeira define o relacionamento entre duas tabelas. Uma chave estrangeira consiste de um campo que aponta para a chave primária de outra tabela ou da mesma tabela nos autorelacionamentos. A chave estrangeira garante a integridade dos dados, pois somente valores existentes na tabela relacionada podem preencher o campo referente a chave estrangeira. Onde: ● foreign key define a coluna da tabela filha; ● references indentifica a coluna e a tabela pai. SEQUENCE Uma sequence gera números sequenciais de acordo com regras predefinidas no momento de sua criação. Normalmente, as seqüências são usadas para criar um valor de chave primária que deve ser exclusivo para cada linha de uma tabela.
  • 58. Conexão com a base de dados JDBC Rosicléia Frasson 57 CREATE SEQUENCE nome_da_seqüência [increment by n] [start with n] [maxvalue n] or [minvalue n] [cycle | nocycle] [cache n | nocache]; Onde: ● increment by n: define o número a ser incrementado cada vez que a coluna nextval for referenciada. ● start with n: define o primeiro valor a ser gerado na sequência. ● minvalue n: define o valor mínimo a ser produzido na sequência. ● maxvalue n: define o valor máximo a ser produzido na sequência. ● cycle: especifica se a seqüência continuará a gerar valores após alcançar seu valor máximo ou mínimo ● cache n: especifica quantos valores o servidor Oracle alocará previamente na memória. Se o cache não for especificado explicitamente, o Oracle irá assumir o padrão, que é de gerar um cache de 20 valores. O comando nextval retorna o próximo número da sequência. Tipos de dados A tabela a seguir lista os tipos de dados mais utilizados no banco Oracle. Descrição Tipo de dado Armazena dados do tipo caracter de comprimento variável. VARCHAR2(comprimento) Armazena dados do tipo caracter de comprimento fixo. CHAR(comprimento) Armazena números flutuantes, porém aceita números inteiros. NUMBER(precisão, escala) Armazena datas e horas. DATE Armazena valores inteiros. INTEGER Vale ressaltar que a única diferença entre o CHAR e o VARCHAR é que o CHAR armazena caracteres alfanuméricos de tamanho fixo. Isso significa que se a string leite que corresponde ao nome de um produto for armazenada em uma coluna CHAR(50), a coluna conterá a string LEITE + 45 espaços em branco que são adicionados automaticamente para preencher o tamanho total da coluna.. DML
  • 59. Conexão com a base de dados JDBC Rosicléia Frasson 58 A linguagem DML - Data Manipulation Language - é composta por comandos usados para manipular as informações contidas na base de dados. Dentre os comandos mais utilizados estão: INSERT Comando utilizado para inserir um registro na base de dados. INSERT INTO nome_tabela (coluna1,coluna2,coluna3,...) VALUES (valor1,valor2,valor3,...); UPDATE Instrução utilizada para atualizar os registros existentes em uma tabela. UPDATE nome_tabela SET coluna1=valor1, coluna2=valor2, ... WHERE alguma_coluna = algum_valor; DELETE Comando utilizado para remover registros existentes em uma tabela. DELETE FROM nome_tabela WHERE alguma_coluna = algum_valor; SELECT Comando utilizado para recuperar dados de uma ou mais tabelas. O * seleciona todas as colunas de uma tabela. SELECT nome_coluna, nome_coluna FROM nome_tabela; SELECT * FROM nome_tabela; LIKE