JAVA
Agenda
Tecnologia Java
JVM, Java e suas versões
Java - Instalação e configuração Fundamentos
Orientação a Objetos Classe Object
Tratamento de erros Wrapper classes
Agenda
Como funciona o Ambiente WEB Conceitos básicos de HTML
Práticas Inicias / Servlets
Diretivas JSP e Objetos implícitos JavaBeans
Conectividade com Banco de Dados
Projeto completo em JSP: Definição, Criação dos
Objetos e Menu Principal
Projeto completo em JSP: Cadastro
Java não é apenas uma linguagem de
programação, é uma plataforma, introduzida no mercado em 1995 pela Sun Microsystems.
Porque Java está tão em evidência atualmente?
Porque é o resultado de um trabalho
consistente de pesquisa e desenvolvimento de mais do que uma simples linguagem de
programação, mas de todo um ambiente de desenvolvimento e execução de programas, orientado a objetos, portável e seguro.
O que é Java?
É sempre importante destacar que Java e
Javascript são linguagens distintas. Javascript é uma linguagem elaborada pela Netscape que
geralmente está embutida em códigos HTML. Java é uma linguagem completa e distinta do Javascript. O maior erro foi dar o nome
Por que Java?
• É uma linguagem completa (e não apenas uma linguagem para
Internet)
• Não é um produto, é uma especificação
• É totalmente Orientada a Objetos (o que permite maior
legibilidade do código, bem como grande reuso do mesmo)
• É uma linguagem simples se comparada com outras • É multiplataforma (portável)
• É segura e robusta
Por que Java?
• Vasta biblioteca disponível por padrão
• Vasta biblioteca disponível na Internet
• Padrão conciso, não muda radicalmente há cada nova versão,
mantendo a compatibilidade com a versão anterior
• Com a mesma linguagem você pode programar aplicações
Principais usos • Área bancária
• Serviços web distribuídos
• Biotecnologia
• Jogos
• Processamento de imagens
• Sistemas legados
Histórico
Início dos anos 90 – A Sun propõe uma linguagem para uso em qualquer dispositivo eletrônico. Tal linguagem deveria ser:
• Simples, porém completa • Robusta
• Portável • Compacta
• Independente de Plataforma
Em 1991, a Linguagem Oak é projetada por James Gosling e a equipe Green
Já em 1993, com a explosão da Internet, o projeto foi direcionado à aplicações voltadas para esta.
Em 1994, devido a problemas de patente, a linguagem Oak passa a se chamar Java (nome de uma ilha asiática que produz um dos melhores cafés do mundo)
Princípios da Computação
O software é responsável por controlar o hardware, e
nada mais é do que um conjunto de instruções na linguagem em que o computador entende (0s e 1s)
Tipos de Software:
Sistema Operacional
Aplicações Stand-Alone
Aplicações Cliente-Servidor
Linguagens de Programação
As linguagens de programação agem como tradutoras. Elas traduzem uma linguagem próxima da linguagem humana para a linguagem que os
computadores entendem (0s e 1s).
Com a evolução das linguagens, elas foram distanciando-se cada vez mais da linguagem de máquina e aproximando-se da linguagem natural.
Evolução das linguagens:
• Linguagem de Máquina
• Linguagens Não-Estruturadas
• Linguagens Estruturadas (Ansi C, Pascal)
As linguagens de programação ainda diferem quanto a serem COMPILADAS ou INTERPRETADAS.
As linguagens compiladas tem a vantagem de possuir execução mais rápida, porém sempre tem-se o trabalho de compilar o código após sua escrita.
O S.O. carrega direto o programa O S.O. precisa do
Interpretador da linguagem que vai ler o programa
Execução do Programa
Escrever o código fonte e
compilar/link-editar (gerar executável) Escrever o código
fonte Geração do Programa Compilada Interpretada Linguagens
Java utiliza uma técnica intermediária. Um código-fonte Java gera um código
intermediário chamado BYTE-CODE. Este código é interpretado pela JAVA VIRTUAL MACHINE, que traduz o byte-code para o S.O.
Este processo é mais rápido que uma linguagem puramente interpretada, porém mais lento que uma linguagem compilada. A vantagem é a portabilidade, uma vez que existe JVM para vários S.Os.
O S.O. precisa da JVM para interpretar o byte-code Escrever o código fonte e compilar (gerar byte code)
Java
O S.O. carrega direto o
programa O S.O. precisa do
Interpretador da linguagem que vai ler o programa Execução do
Programa
Escrever o código fonte e compilar/link-editar (gerar executável) Escrever o código
fonte Geração do Programa Compilada Interpretada Linguagens
Princípios da Programação
Em Orientação a Objetos
funções são chamadas de métodos
variáveis são chamadas de atributos
É mais natural quando definimos qualquer
objetos pensarmos em termos de atributos do que pensarmos em variáveis, embora na
Por que Orientação a Objetos?
A idéia principal da Orientação a Objetos é
diminuir o abismo entre o mundo real e a modelagem que usamos na programação
Vamos supor como exemplo um simulador,
onde devemos descrever uma pessoa comum:
essa pessoa tem um nome, anda, fala. Dirije um
carro.
aqui identificamos dois objetos:
a pessoa
Por que Orientação a Objetos?
Na Orientação a Objetos, diretamente já
definiríamos em nosso programa:
um objeto Pessoa e um objeto Carro.
Em qualquer paradigma de programação, em
Por que Orientação a Objetos?
Numa linguagem procedural agrupamos blocos de
códigos para uma determinada tarefa em funções. Estas funções são colocadas em uma biblioteca
independente, o que geralmente não garante
organização, e torna muito difícil a reutilização do código.
Numa possível aplicação bancária teríamos, por
exemplo as seguintes funções agrupadas numa biblioteca:
ObterExtrato, TransferirDinheiro, AbrirBancoDados,
Numa linguagem orientada a objetos tentaríamos primeiro definir cada Objeto do programa (Conta, Agência, Banco, Tela, Banco de Dados) e definir o que cada um destes Objetos faria.
Além da organização mais natural, o código ficaria muito mais legível. É muito mais natural entender uma função com o nome de Conta.Extrato() do que uma função perdida no código com o nome ObterExtrato() ou então
Obter_Extrato_Conta().
Mas o mais importante, são muitas novas características que a OO traz para a programação, dentre as principais: Herança, Polimorfismo e
Encapsulamento, que serão visto adiante.
Um Objeto é definido por uma CLASSE.
Por que Orientação a Objetos?
Por que Orientação a Objetos?
A Orientação a Objetos não exclui a Programação Procedural. A OO engloba a PP, acrescentando muitas características
poderosas e úteis a programação, poupando tempo e esforço do programador.
P. Procedural
Java e suas edições
• J2SE – Java 2 Standard Edition
Plataforma Java para computadores de mesa, com suas funções padrões.
• J2ME – Java 2 Micro Edition
Plataforma Java para dispositivos portáteis, como celulares, Palms, Javacards, etc. Possui um conjunto de funções menor do que o J2SE.
• J2EE – Java 2 Enterprise Edition
Java Virtual Machine
Atualmente temos a JVM disponibilizada em diversas
formas (JRE, Javacards, etc). A maioria dos navegadores também inclui ou suporta a JVM.
Quando um programa é executado, a JVM é quem
controla as instruções da CPU, registradores, o
controle de pilhas, controle de garbage collector e área de memória.
Garbage collector é automático, ou seja, a memória
que não está mais em uso é desalocada
Java Virtual Machine
A JVM implementa internamente a segurança. Por
exemplo, ela não permite que applets executem códigos maliciosos, como apagar arquivos do
computador.
A JVM é quem carrega os arquivos .class (arquivos
gerados pela compilação do código de um programa Java) para a memória – class loader.
Também é a JVM quem verifica a integridade de um
Java - Ferramentas necessárias
Para rodar qualquer aplicativo Java:
Java Virtual Machine
Para desenvolver um aplicativo Java é preciso:
Editor de texto – para desenvolver e escrever o código
Compilador e bibliotecas (SDK) – para compilar o código
JVM – para testar e executar o código gerado
Qual obter?
Existem ambientes integrados (possuem tudo em um único produto) vendidos por terceiros, como:
Borland Jbuilder
Symantec Visual Café IBM WebSphere
Kawa
Um ambiente de desenvolvimento proporciona maior facilidade para a escrita do código, depuração e construção de telas gráficas.
Iremos utilizar as ferramentas mais simples possíveis, gratuitas e fornecidas pela própria SUN.
Existe ainda o ambiente integrado da Sun, o Java One
JVM - Onde obter
SDK - Onde obter
Help - Onde obter
J2SE API Specification
Help - Onde obter
J2SE API Specification
Editor de textos - Onde obter
Qualquer editor de textos simples pode ser utilizado. O ideal é que tal editor apresente pelo menos o número das linhas em sua interface, o que facilitará a detecção de erros.
Java
JEdit (http://www.jedit.org)
Windows
Notepad / Wordpad
Editpad Lite (http://www.editpadlite.com)
Linux
Instalação
O ideal é que o diretório de instalação seja o sugerido pelo instalador, que irá criar um diretório logo acima do diretório raiz.
No Windows, será algo do tipo:
C:\jdk1.4\
No Linux e demais UNIX:
/jdk1.4/
Embora nos dois sistemas existam diretórios específicos para a
Configuração – Variáveis de Ambiente
Variáveis de ambiente são valores guardados pelo Sistema Operacional e usados por qualquer programa que precise usá-los. Como exemplo, vários programas que precisam usar um diretório temporário para criar arquivos
perguntam ao Sistema Operacional o valor da variável de ambiente TEMP ou TMP.
O Windows irá responder C:\windows\temp
Configuração – Variáveis de Ambiente
O Java precisa de que duas variáveis de ambiente estejam corretamente configuradas: PATH e CLASSPATH
PATH – essa variável de ambiente informa o caminho (path
em inglês) para vários programas poderem ser acessados
diretamente, sem que seja preciso estar no diretório em que os mesmos foram instalados.
CLASSPATH – essa variável informa onde estão as classes
Exercício
1. Fazer o download, e instalar o SDK da Sun.
Utilizando os passos já descritos:
Configurar o PATH
Configurar o CLASSPATH
Caso seja Win98, carregar o DOSKEY na
Olá Mundo!
Orientado a Objetos
class HelloWorld {
public static void main(String[] args) {
Objeto1 meuObjeto = new Objeto1();
meuObjeto.imprimaNaTela();
} }
class Objeto1 {
public void imprimaNaTela() {
System.out.println(“Ola, mundo!”);
Exercício
1. Copiar separadamente o código Orientado a Objetos
em dois arquivos de texto com o seguintes nomes: HelloWorld.java
Objeto1.java
Compilar o código digitando na linha de comando: javac HelloWorld.java
Para chamar a linha de comando, clique no botão Iniciar, em
seguida Programas, e finalmente clique em MS-DOS ou Prompt de Comando
Importante!
Don’t panic!
Raramente a compilação dá certo sem
erros!
Geralmente os programas apresentam
JAVAC E JAVA
Utilizamos o comando JAVAC para chamar o
compilador Java. Ele irá transformar o código fonte (arquivo com a extensão .java em byte-code (arquivo com a extensão .class).
Utilizamos o comando JAVA para chamar a
JVM, que irá interpretar o byte-code (arquivo
Erros de compilação
Durante a compilação, o compilador irá listar 1
ou mais erros (caso eles existam).
Caso isso aconteça, devemos sempre olhar e
corrigir sempre o primeiro erro desta lista.
Um erro simples de sintaxe (por exemplo esquecer
o “ponto-e-vírgula”) pode fazer o compilador entender que existam vários outros erros.
Após corrigir este erro, compilar de novo e verificar
Erros de compilação – erros comuns
Erros que externos ao código fonte
O PATH não está configurado corretamente e o sistema operacional não consegue achar o compilador e a jvm.
Solução: configurar corretamente a variável de ambiente PATH.
‘javac' não é reconhecido como um comando interno ou externo, um programa operável ou um arquivo em lotes.
Erros de compilação – erros comuns
O compilador não está achando o arquivo fonte.
Possíveis causas:
o nome foi digitado incorretamente
o arquivo fonte não está no diretório atual
o CLASSPATH não está configurado corretamente
Soluções:
verificar se o nome do arquivo foi digitado corretamente verificar se o arquivo está no diretório atual
verificar se o CLASSPATH está configurado com o diretório atual (.)
error: cannot read: Teste.java
Erros de compilação – erros comuns
Para localizarmos a maioria dos erros que pertencem
ao código fonte, o compilador avisa em qual arquivo o erro está localizado, e em qual linha. Em seguida
mostra qual o erro cometido.
Teste.java:4: ';' expected
^
1 error
Na linha 4
Erro no arquivo Teste.java
O compilador esperava (expected) achar um “ponto-e-vírgula” no final da linha
Formato de uma classe
class <nome> {
}
int x; char c;
Atributos do objeto
funcao <nome>() { ...
}
Fundamentos da Linguagem
Java é sensível a letras maiúsculas e
minúsculas (case-sensitive)
Ex: maria ≠ Maria ≠ MAria ≠ MARIA
Formatação livre de código
Os dois exemplos abaixo produzem o mesmo efeito:
x = 1 + 5; x =
1 + 5
Ao final de cada comando é obrigatório o uso
do ponto-e-vírgula
Ex: x = 1 + 5;
Blocos de código são colocados entre chaves
Fundamentos da Linguagem
int soma() {
x = a + b;
return x;
Fundamentos da Linguagem
Identificadores – nomes de classes, variáveis e
funções – devem:
iniciar com os seguintes caracteres:
A até Z (maiúscula ou minúscula)
_ (undescore)
$ (cifrão)
os próximos caracteres podem ser qualquer um dos
Fundamentos da Linguagem
Comentários – são textos colocados dentro de um código fonte apenas como forma de identificar trechos do código,
como um lembrete. No momento da compilação o compilador ignora os trechos que estão em comentário
Java suporta os seguintes tipos de comentários
Dentro de uma mesma linha (inline): // comentário
Várias linhas (multi-line): /* comentário */
Multi-line com Javadoc: /** comentário */
Javadoc são comentários colocados em uma formatação
específica dentro do código que depois podem ser extraídos em formato HTML, o que torna desnecessária a escrita da
Fundamentos da Linguagem
Palavras reservadas – palavras que não podem
ser utilizadas como nome de variáveis, nome de classes, etc
Em Java:
abstract, boolean, break, byte, byvalue, case,
catch, char, class, continue, default, do, double, else, extends, false, final, finally, float, for, goto, if, implements, import, instanceof, int,
interface, long, native, new, null, package,
private, protected, public, return, short, static, super, switch, synchronized, this, threadsafe,
Fundamentos da Linguagem
Um programa Java é composto por uma ou
mais classes.
Cada classe deve estar em um arquivo
diferente (em princípio).
Este arquivo deve ter o exatamente o mesmo
Fundamentos da Linguagem
Uma aplicação stand-alone em Java precisa ter em
sua classe principal um método também principal, que indica onde o programa começa.
Este é o método main (principal em português)
A classe principal é a classe que será chamada pela
JVM:
java ClassePrincipal
public static void main(String[] args) {
//inicialização
Variáveis em Java
Para declararmos uma variável, utilizamos a seguinte
instrução:
<tipo da variável> <nome da variável>
Exemplo:
int media; char teste;
A variável também já pode ser inicializada durante sua declaração, o que sempre é um bom modo de programar.
Exemplo:
Variáveis em Java
Variáveis para números inteiros:
Obs: não temos o tipo unsigned como em C++
8 bytes
-922.337.203.685.475.808 até
+922.337.203.685.475.807
long
4 bytes
-2.147.483.648 até
+2.147.483.637
int
2 bytes
-32.768 até +32.767
short
1 byte
-128 até +127
byte
Espaço em memória Variação
Variáveis em Java
Variáveis para números decimais (ou ponto
flutuante):
O Java possui 2 tipos de variáveis para números
decimais. A diferença entre elas é a sua precisão.
8 bytes
-1.7 x 10 308 até +1.7 x 10 308 double
4 bytes
-3.4 x 10 38 até +3.4 x 10 38 float
Espaço em memória Variação
Variáveis em Java
Tipo caracter
Diferentemente de outras linguagens, o Java utiliza o padrão Unicode ao invés do padrão ASCII.
Isso torna possível o suporte a línguas como árabe e japonês.
Isso faz com que o tipo caracter em Java ocupe 2 bytes ao invés de 1 byte como em outras linguagens.
Exemplo:
Variáveis em Java
Tipos booleanos
Utilizados para expressões lógicas, ocupam 1 bit, e
possuem somente dois valores:
true
false
Exemplo:
Variáveis em Java
Todas as variáveis vistas até agora são ditas
“primitivas”. Ou seja, não é preciso declarar nenhum objeto para utilizá-las.
O tipo String (cadeia de caracteres) embora seja uma
classe é declarado como se fosse um tipo primitivo:
String nome = “Joao da Silva”;
Por ser uma classe, temos vários métodos já
embutidas (que serão vistos adiante).
Por ser um objeto, deve ser comparada usando o
método equals. Exemplo:
Literais
São os valores propriamente ditos, escritos no
código
Exemplo:
meuInt = 10;
nome = "Maria";
meuInt é uma variável do tipo int, e nome é uma String
10 é uma literal
Literais
Literais para Inteiros
Toda literal inteira será tratada como:
int – caso o valor esteja dentro da capacidade do tipo int
long – caso seja maior que a capacidade do int
Supondo as duas linhas de código abaixo:
se (x > 10)
se (x > 2147483638)
A literal 10 será tratada como tipo int
Literais
Para forçar um literal int a ser tratado como
long podemos utilizar os modificadores de tipo:
Exemplo de código:
se (x > (long) 10)
O mesmo serve para forçarmos uma literal int
a ser tratada como byte ou short:
Literais
Números com ponto flutuante
todos os números com ponto flutuante são tratados
como double
para utilizarmos o tipo float devemos utilizar os
Literais
Booleanos – somente dois valores possíveis
true false
String – deve estar entre aspas duplas
Exemplo de linha de código:
String nome = "Maria";
Literais char – deve estar entre aspas simples
Exemplo de linha de código:
Literais
Para caracteres não expressáveis:
'\t' = tab
'\b' = backspace
'\n' = nova linha
'\r' = voltar ao começo da linha (retorno do carro)
Exemplo de linha de código:
System.out.println("Hoje o dia esta com\n Sol");
Sairia na tela como:
Constantes
Constantes são variáveis que possuem um valor fixo,
que não pode ser alterado.
Geralmente usamos constantes no lugar de uma literal
que é muito usada no código.
Para declarar uma constante devemos utilizar o
modificador de tipo final.
Para facilitar a identificação, as constantes devem ser
declaradas em letra maiúscula.
Exemplo:
Convenções
Convenções utilizadas
Nome de Classes: primeiro caracter de todas as palavras maiúsculo e o restante minúsculo.
Ex.: HelloWorld, MeuProgramaEmJava, BancoDeDados
Variáveis e funções: idem as classes, porém o primeiro caracter é minúsculo.
Ex.: minhaFuncao, minhaVariavelInt
Constantes: Tudo maiúsculo
Escopo de Variáveis
Escopo de uma variável define em qual lugar
podemos acessar tal variável.
Uma variável que está definida dentro de um
método não pode ser acessada fora deste método.
Variáveis dentro de um método são conhecidas
como variáveis locais.
Variáveis locais devem ter um valor de
Escopo de Variáveis
Podemos ter dentro de um bloco de código
outro bloco de código. Exemplo:
{
int x = 0; x = 1;
{
// novo bloco de código
int y = 0;
y = 2; x = 2; }
y = 3; }
Acesso normal as variáveis do escopo
Acesso normal as variáveis do escopo principal
Operadores
Em Java temos os seguintes operadores:
+ Soma
- Subtração
/ Divisão
* Multiplicação
% Resto da Divisão
++ Auto-incremento pré e pós-fixado
-- Auto-decremento pré e pós-fixado
op= Pode ser utilizado com qualquer operador
Exemplo:
var = var + 1;
Pode ser representado como:
Operadores - Precedência
No exemplo abaixo:
x = 10 + r * 4 / 11 - 5;
Qual operação seria realizada primeiro?
Java possui uma tabela de precedência que indica
qual operação seria realizada primeiro.
Um bom código ignora esta tabela e coloca
parêntesis adequadamente, o que melhora a sua legibilidade:
Exercício
1. Criar uma classe chamada Calculo, que contenha um
método chamado expressao (void expressao()) que calcule a seguinte expressão e atribua o resultado a uma variável chamada Result:
87 + ((156 * 2) / 4)
Imprimir na tela o resultado utilizando a função System.out.println();
Criar uma classe chamada Principal, e dentro dela
criar o método principal da seguinte forma:
Execute o código. Altere o código para que 2 seja dividido por 4
antes de ser multiplicado por 156.
public static void main(String[] args){
Calculo calc = new Calculo();
calc.expressao();
Expressões Condicionais
Uma expressão condicional serve para controlar o
fluxo do nosso programa
Exemplo: Poderíamos imaginar um programa que calcule a média dos alunos de uma sala e diga se o mesmo foi
aprovado ou não:
Formato no Java:
Onde o uso do else não é obrigatório
se (notaAluno > 5) imprimaNaTela(“Aprovado!”); senão imprimaNaTela(“Reprovado!”);
if (<condicao>) <expressao1>
Expressões Condicionais
A condição da sentença acima geralmente envolve Operadores Lógicos, que em Java são:
== é igual if (i == 1) != diferente if (i != 1) < menor
<= menor ou igual
> maior
>= maior ou igual
Operadores boleanos:
&& e if ((i == 1) && (g >= 6))
|| ou
! negação if (!(i < 1))
Java também admite if na forma ternária:
Imprima( (media > 5) ? "Aprovado" : "Reprovado" )
if (<condicao>) <expressao1>
Exercício
1. Criar uma classe chamada Bissexto, com um método
chamado verifica que irá utilizar expressão condicional para verificar se um ano é bissexto ou não:
Um ano é bissexto caso seu valor seja divisível por 4. Copiar o código abaixo.
Preencher o conteúdo do if.
Criar uma classe chamada UsaBissexto, que irá conter um
método main, e dentro deste método chamar o método verifica.
class Bissexto {
void verifica() { int ano = 1999; if ()
System.out.println(“Ano “ + ano + “ eh bissexto”); else
System.out.println(“Ano “ + ano + “ nao eh bissexto”); }
Expressões Condicionais
Considere o seguinte código com if:
int diaSemana = 2;
if (diaSemana==1) {
System.out.println(“Domingo"); }
else if (diaSemana==2) {
System.out.println(“Segunda-feira"); }
else if (diaSemana==3) {
System.out.println(“Terça-feira"); }
else if (diaSemana==4) {
System.out.println(“Quarta-feira"); }
else if (diaSemana==5) {
System.out.println(“Quinta-feira"); }
else if (diaSemana==6) {
System.out.println(“Sexta-feira"); }
else {
Expressões Condicionais
Uma outra forma de expressão condicional é o switch, que permite executar expressões
condicionalmente baseadas em um valor inteiro.
O switch executa a expressão case correspondente
ao valor de sua expressão (nesse caso, diaSemana).
int diaSemana = 7;
switch (diaSemana) {
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;
Expressões Condicionais
No fim de cada case, se coloca um break para terminar o
switch, e o programa continuar a partir do fim do bloco do switch. Sem o break, o controle passa aos case
subseqüentes.
Se não houver um case correspondente, é executada a
expressão default caso esta exista, senão nada é executado.
int diaSemana = 2;
switch (diaSemana) {
case 2: System.out.println("Segunda é um dia chato."); case 3:
case 4: case 5:
case 6: System.out.println("É dia de trabalho!"); break; case 1:
case 7: System.out.println("É dia de dormir!"); break; default: System.out.println("Dia inválido!");
Laços
Laços são códigos de bloco que queremos
repetir várias vezes.
Por exemplo, poderíamos querer que nosso
programa calcule todas as médias dos alunos enquanto ainda houverem alunos sem notas calculadas.
Isso torna o código mais legível e muito menor
Laços
Como na maioria das linguagens, em Java
temos 3 tipos de laços:
while
Em português, ENQUANTO. Executará o bloco de código apenas se uma condição for verdadeira.
do-while
Semelhante ao while, com a diferença de que executará o bloco de código pelo menos uma vez.
for
Laços
Sintaxe:
while (<condicao>)
<codigo>
do
<codigo>
while (<condicao>);
for (<valor inicial>; <condicao>; <atualizacao>)
<codigo>
int i = 0;
while (i < 5) {
System.out.println(i); i++;
}
int i = 0;
do {
System.out.println(i); i++;
} while(i < 5);
for (int i = 0; i < 5; i++) { System.out.println(i);
Exercício
1. Escrever um programa que utilize while para
inverter um número inteiro.
Utilizar a seguinte estrutura
class Inverte{
void inverteNumero(){ int numero=123456789; int numeroInvertido=0; while(<condicao>){
//Logica para inversao do numero }
System.out.println(numeroInvertido); }
Ramificações
Os comandos de ramificação permitem um
controle mais avançado do fluxo nos laços. O Java suporta 3 comandos:
break
Permite sair no meio de um laço (break significa quebrar)
continue
Permite pular para a próxima iteração de um laço
return
Ramificações
O comando break é utilizado para se sair de
um laço.
String palavra = "guarda-chuva"; boolean achou = false;
for (int i = 0; i < palavra.length(); i++) {
if (palavra.charAt(i) == '-') { achou = true;
break; }
}
if (achou)
System.out.println("Palavra composta"); else
Ramificações
O comando break pode ser utilizado com um
label (rótulo), para sair de laços aninhados. String[] palavras = {"disco-voador", "ufo"};
boolean achou = false;
busca:
for (int j = 0; j < palavras.length; j++) {
for (int i = 0; i < palavras[j].length(); i++) { if (palavras[j].charAt(i) == '-') {
achou = true; break busca; }
} }
if (achou)
System.out.println("Possui palavra composta"); else
Ramificações
O comando return é utilizado para sair de uma
função, retornando um valor (quando o tipo da função não for void).
Quando usado antes do fim da função, return a
Classes
Objetos são definidos através de classes.
Objetos possuem características e
funcionalidades, o que em OO chamamos de
atributos e métodos.
Uma aplicação é formada por um conjunto de
classes que desenvolvemos ou já estão desenvolvidas.
Cada classe deve estar em um arquivo
Classes
Uma aplicação stand-alone deve conter um
método main.
A classe que contiver o método main deverá
ser a classe compilada pelo javac e depois chamada pela JVM.
Quando o compilador encontrar uma classe que
referencie outra, primeiro ele procura um
arquivo .java da classe referenciada. Caso não haja, o compilador procura o arquivo compilado (.class). E, caso o .class não seja achado, o
Classes e atributos
Como exemplo vamos definir um objeto Carro através da classe
Carro com os seguintes atributos:
class Carro {
String modelo;
String combustivel;
boolean arCondicionado; }
Para utilizarmos esta classe, ou seja, criarmos um objeto carro,
devemos declarar na classe que irá utilizar o objeto Carro (em nosso caso, é a classe UsaCarro) a seguinte instrução:
Carro <nome do objeto> = new Carro();
Exemplo:
Classes e atributos
Utilizar um objeto é semelhante a declararmos uma
variável dentro do código.
Criar um objeto de um determinado tipo dentro do
código chama-se instanciar um objeto. Em nosso exemplo, instanciamos um objeto do tipo Carro.
Para acessarmos as variáveis (ou atributos) dentro da
classe UsaCarro utilizamos o nome do objeto seguido de ponto (.) e o nome da variável.
Em nosso exemplo:
Classes e atributos
Os atributos dentro da classe Carro podem ser: privados - somente dentro da classe Carro as variáveis
privadas serão acessadas. Dentro da classe UsaCarro não podem ser.
públicos - tanto dentro do seu escopo (classe Carro) quanto na sua instância (dentro da classe UsaCarro), a variável
pública pode ser acessada.
Quando instanciamos uma classe, caso suas variáveis
não tenham valor de inicialização, os valores padrão são:
Numérica = 0 ou 0.0 boolean = false
Classes e métodos
Os métodos podem ou não conter parâmetros. Exemplo:
mostrarLogotipo(); soma(int a, int b);
Os parâmetros podem ser variáveis primitivas ou
então Objetos.
No caso de variáveis primitivas, as variáveis são passadas para o método por cópia (isso chama-se passagem por valor).
Classes e métodos
Um método pode ou não ter valor de retorno.
Caso possua valor de retorno, o método pode
retornar variáveis primitivas ou objetos.
Caso não possua valor de retorno, o método deve
conter em seu início a palavra void.
int soma(int a, int b) { int result = (a + b); return (result);
}
void mostrarLogotipo() { // codigo
}
int soma(int a, int b) { return (a + b);
Classes e métodos
Assim como acontece com os atributos, os
métodos também podem ser:
privados - somente dentro da classe que os define
tais métodos poderão ser acessados;
públicos - tais métodos serão acessíveis de qualquer
Exercício
1. Criar uma classe chamada Carro e transferir
o código do próximo slide.
Criar uma classe chamada UsaCarro, o método
main, instanciar um objeto Carro e chamar os métodos definidos em uma ordem aleatória para teste.
Instanciar outro objeto Carro e também testar.
class Carro {
String combustivel; boolean ligado; boolean andando; public void ligar() {
if(ligado)
System.out.println(“Erro: O carro ja esta ligado”); else{
ligado=true;
System.out.println(“OK! O carro foi ligado”); }
}
public void desligar() {
if(!ligado || andando)
System.out.println(“Erro: O carro ja esta desligado ou esta andando”); else{
ligado=false;
System.out.println(“OK! O carro foi desligado”); }
}
public void andar() {
if(!ligado || andando)
System.out.println(“Erro: O carro ja esta andando ou esta desligado”); else{
andando=true;
System.out.println(“OK! Agora o carro esta andando”); }
}
public void parar() { if(!andando)
System.out.println(“Erro: O carro ja esta parado”); else{
andando=false;
System.out.println(“OK! Agora o carro esta parado”); }
Atributos estáticos
Quando criamos um atributo estático, este
atributo será único para todos os objetos instanciados dessa classe.
Para isso utilizamos o modificador static na
declaração do atributo.
Podemos acessar atributos estáticos
Atributos estáticos
Exemplo:
class TesteStatic {
public static int contador = 0; }
class UsaStatic {
public static void main(String[] args) {
TesteStatic t1 = new TesteStatic();
t1.contador++;
TesteStatic t2 = new TesteStatic();
t2.contador++;
System.out.println(t2.contador);
System.out.println(TesteStatic.contador); }
}
Variável contador sendo incrementada
Mesma variável contador sendo incrementada
Métodos estáticos
Métodos estáticos funcionam como os atributos
estáticos, ou seja, podemos chamá-los sem precisar instanciar um objeto de uma classe.
Um caso típico e que até agora usamos sem
perceber é o método println quando
chamamos System.out.println. Para usá-lo não criamos um objeto da classe System.
O método main também é estático, pois não
Métodos estáticos
Para criar um método estático indicamos o
modificador static em sua declaração.
Criamos métodos estáticos para realizar
funções geralmente não atribuídas a nenhum método do nosso programa, como funções que invertem uma String, por exemplo. Poderíamos chamar tal classe de Util.
Para chamar o método inverte de nossa
suposta classe Util, por exemplo:
Encapsulamento
Encapsulamento nada mais é do que
protegermos nossos atributos de acesso externo direto.
Em nosso exemplo da classe Carro, se a classe
UsaCarro (ou qualquer outra classe que
instanciasse nosso objeto) quisesse mudar o valor dos atributos ligado e andando para
Encapsulamento
Do mesmo modo, para o atributo que define o
tipo de combustível poderíamos atribuir um nome de empresa, ou qualquer outra String
que não fizesse sentido.
Para encapsular os atributos de uma classe
Encapsulamento
class Carro { String modelo;
private String combustivel;
private boolean ligado, andando;
// Funções ligar, desligar, andar e parar acessando agora as // variáveis privadas
public void setCombustivel(String valor) {
if ( valor.equals(“Gasolina”) || valor.equals(“Alcool”) ) combustivel = valor;
else System.out.println(“Combustivel invalido!”); }
public String getCombustivel() {
return combustivel; } } Atributos encapsulados Método para atribuição e validação
Variável this
Todo objeto de uma classe possui por definição uma
variável chamada this que se refere ao próprio objeto.
class TesteThis {
int x = 1;
public void testandoThis() { int x = 2;
this.x = 10; }
Sobrecarga de métodos
Sobrecarregar um método significa escrever
métodos com o mesmo nome, porém com parâmetros diferentes em quantidade e/ou tipo.
Exemplo:
class Calculo {
public static int soma(int a, int b) { return a + b;
}
public static int soma(int a, int b, int c) { return a + b + c;
}
public static float soma(float a, float b) { return a + b;
Sobrecarga de métodos
Não podemos fazer a sobrecarga de um
método mudando apenas seu valor de retorno e mantendo a mesma lista de parâmetros, pois algumas vezes em nossos programas
descartamos o valor de retorno.
Isso torna impossível para o compilador saber
Construtores de Classes
Construtores são utilizados para inicializar
atributos no ato da instanciação de uma classe.
Ao invés de primeiro instanciar o objeto e
depois ficarmos atribuindo cada valor para cada atributo, programamos a classe para que logo que ela seja instanciada tais valores sejam
atribuídos.
Construtor é um método especial:
possui o mesmo nome da classe
Construtores de Classes
Quando utilizamos a instrução
Carro fusca = new Carro();
Construtores de Classes
Mesmo que não declaremos em nosso código
um construtor, Java assume que existe um construtor sem código:
class Carro {
String modelo, combustivel;
Carro() {}
// Outros métodos
}
Construtores de Classes
Exemplo:
class Carro {
public String modelo;
private String combustivel;
public Carro(String modelo, String combustivel) { this.modelo = modelo;
this.combustivel = combustivel; }
}
Ao modificarmos o construtor, o compilador não assumirá mais que o construtor padrão existe.
Destrutores
Assim como temos os construtores para realizar
instrução durante a instância de uma classe, também temos os destrutores para executar alguma instrução desejada antes do objeto ser retirado da memória.
Utilizamos a instrução finalize para tal:
protected void finalize() {
// Código a ser executado antes do descarte do objeto.
Arrays
Arrays são estruturas que armazenam múltiplos
valores do mesmo tipo.
O tamanho de um array é fixado no momento
de sua criação.
Arrays
Um elemento do array é um dos valores
armazenados, e pode ser acessado através da sua posição.
Para armazenar valores de tipos diferentes ou
Arrays
Para declarar um Array:
<tipo>[] <nome> = new <tipo>[<quantidade>]
ou:
<tipo> <nome>[] = new <tipo>[<quantidade>]
Exemplos:
Arrays
Para acessar uma das variáveis do array,
devemos indicar qual a sua posição.
A posição inicial é a posição 0. Um array de 10
elementos, por exemplo, tem suas posições de 0 a 9.
Acessando:
Arrays
Como saber o tamanho de um Array?
for (int i = 0; i < jogoLoto.length; i++)
System.out.println(jogoLoto[i]);
Nota: length é uma propriedade de todas as arrays,
Arrays
Um array já pode ter seus valores inicializados
durante sua declaração:
int[] jogoLoto = {13, 15, 28, 29, 37, 42};
A função main possui um Array de Strings que
representam os argumentos de linha de comando de execução da aplicação.
Passamos os parâmetros quando chamamos a
aplicação na linha de comando:
Arrays
Arrays podem ter mais de uma dimensão, como
por exemplo as Matrizes, que são Arrays bidimensionais.
Exemplo de uma matriz quadrada 3x3 (3 linhas
e 3 colunas):
Arrays
Também podemos inicializar os valores durante
a declaração:
String[][] flintstones =
{
{ "Flintstones", "Fred", "Wilma", "Pebbles", "Dino" },
{ "Rubbles", "Barney", "Betty", "Bam Bam" },
};
Também podemos ter arrays/matrizes de
Objetos:
Carro carros[] = new Carro[10];
Questões
1. Qual o índice de Brighton no array abaixo?
String[] skiResorts = {
"Whistler Blackcomb", "Squaw Valley", "Brighton", "Snowmass", "Sun Valley", "Taos"
};
2. Qual a expressão para acessar essa posição.
3. Qual é o valor da expressão skiResorts.length?
4. Qual o índice do último valor do array?
Exercício
1. O programa abaixo contém um bug.
Encontre-o e o corrija.
class Porquera {
public static void main (String[] args) {
StringBuffer[] stringBuffers = new StringBuffer[10];
for (int i = 0; i < stringBuffers.length; i++) {
stringBuffers[i].append("StringBuffer at index "+i); }
}
Herança
A herança em OO é semelhante ao conceito da
herança genética:
uma classe que herda outra classe recebe todos os
métodos e atributos da classe herdada.
uma classe que herda outra classe é do mesmo tipo
da classe herdada.
uma classe que herda outra classe é conhecida
Herança
Para avisar que uma classe está herdando
outra usamos a instrução extends.
Em nosso exemplo do Carro, poderíamos ter
uma classe chamada Pickup, que teria todas as características que um carro tem e mais o
atributo capacidadeDeCarga. Para isso basta a classe Pickup herdar a classe Carro, e então não precisamos reescrever todo o código,
Herança
class Carro { String modelo;
private String combustivel;
private boolean ligado, andando;
// Funções ligar, desligar, andar e parar // Funções setCombustivel e getCombustivel
}
class Pickup extends Carro {
int capacidadeDeCarga;
}
Métodos construtores diferentes do método
Herança
Não herdamos métodos e atributos privados,
somente públicos:
para isso existe o modificador protected.
protected é um método ou atributo privado que é
público apenas para a sub-classe.
Em Java a herança é sempre simples
Herança
Na sub-classe podemos reescrever qualquer
método ou atributo, e o que ficará valendo será este (o da sub-classe).
Para nos referirmos a algum método ou
atributo da super classe utilizamos a instrução
Herança
Caso a sub-classe não implemente um
construtor, o compilador assumirá que ela
possui o construtor padrão, que no caso será o herdado da super classe.
Caso a sub-classe implemente um construtor
diferente do padrão, neste estará implícito o código do construtor padrão da super-classe.
Para usar outro construtor da super-classe que
Herança
class Pai {
public Pai() {
System.out.println("Construtor da super classe padrao"); }
}
class Filha extends Pai {
// Construtor padrão declarado
public Filha() {}
public static void main(String[] args) { Filha teste = new Filha();
} }
Herança
class Pai {
public Pai() {
System.out.println("Construtor da super classe padrao"); }
}
class Filha extends Pai {
// Construtor declarado
public Filha(String s) { System.out.println(s); }
public static void main(String[] args) {
Filha teste = new Filha("Construtor da classe Filha"); }
}
126
Exercício
1. Criar uma classe chamada ContaCorrente, que
tenha os seguinte atributo:
saldo (que será privado, porém poderá ser
herdado).
titular (do tipo String, que será pública).
Fazer o construtor da classe, que atribui o valor 0
(zero) para o saldo.
A ContaCorrente ainda deve possuir um método
chamado extrato, que encapsula o atributo saldo e nos retorna o seu valor.
O método que atribui valor ao saldo deverá
chamar-se deposito, e recebe como parâmetro o valor do depósito. Dentro da função, o valor do depósito é somado ao saldo.
Exercício (continuação)
Criar uma classe chamada ContaEspecial que
irá herdar a classe ContaCorrente. Esta classe possui um atributo adicional: limite (limite do cheque especial). Atribua um valor qualquer para o limite.
sobrescrever o método extrato para que retorne o total disponível para saque como sendo o saldo somado com o limite.
Escrever uma classe chamada UsaConta, que
será a classe principal, e dentro dela instanciar contas do tipo ContaCorrente, e do tipo
Polimorfismo
Polimorfismo, do grego, significa muitas
formas. É um dos recursos poderosos da OO.
Significa que temos uma super-classe que é
derivada em várias sub-classes, por isso dizemos que assume várias formas.
O polimorfismo nos beneficia de dois modos
(que serão vistos a seguir):
Polimorfismo
Vamos continuar em nosso exemplo de carro,
mas agora usando uma classe mais genérica como super classe, uma classe chamada
Automóvel:
Automóvel
Calhambeque
Polimorfismo
Com o polimorfismo poderíamos ter uma
coleção de objetos Automóvel (por exemplo um Array):
Automovel[] autos = new Automovel[10];
Cada elemento deste array poderá ser da
própria classe Automovel ou qualquer tipo derivado desta super classe (CarroFusca,
Calhambeque ou Caminhão).
Polimorfismo
Como devemos inicializar cada elemento de um
Array de objetos, informamos neste momento a qual das formas da classe Automovel o
elemento pertence:
autos[0] = new CarroFusca();
autos[1] = new Automovel();
autos[2] = new Calhambeque();
Polimorfismo
Vamos supor que em nossa classe Automovel
temos um método chamado buzina().
é claro que Java tem funções para som!
Vamos supor ainda que cada sub-classe
reescreveu o método buzina, de acordo com o som característico:
CarroFusca - ouvimos algo como “beep-beep”;
Calhambeque - “huuuuuuuuuuuuuuuugooo”
Polimorfismo
Uma classe UsaAutomovel instancia nossa classe
Automovel, e poderia ter o seguinte laço:
for(int i=0;i<autos.length;i++){ autos[i].buzina();
}
Quando o Java executar este trecho, ele saberá qual
método de qual sub-classe executar, ou seja,
ouviremos a buzina característica de cada sub-classe.
Classes e métodos abstratos
Quando uma classe é dita abstrata, ela não
pode ser instanciada, somente herdada.
Em nosso exemplo da classe Automovel e suas
sub-classes (CarroFusca, Calhambeque e Caminhao), poderíamos tornar a classe Automovel uma classe abstrata.
Para tornar uma classe abstrata utilizamos o
modificador abstract:
Classes e métodos abstratos
Dentro de uma classe abstrata podemos ter métodos
abstratos.
Um método abstrato não tem corpo de instrução, e
tem que ser obrigatoriamente implementado nas sub-classes.
Em nossa classe Automovel, por exemplo, vamos
tornar nosso método buzina() um método abstrato.
abstract void buzina();
Funções abstratas são usadas para garantir o sucesso
Classes e métodos final
Uma classe pode receber o modificador final
para indicar que não pode ser mais herdada:
final class CarroFusca
Da mesma maneira, para que um método não
possa ser redefinido em alguma das sub-classes, utilizamos o modificador final:
Exercício
1. Modificar o exercício anterior (8) de forma que:
a classe ContaCorrente seja abstrata e o método extrato() desta
classe também o seja.
além da classe ContaEspecial agora também vamos usar outra
sub-classe de ContaCorrente: a classe ContaEstudante. Ou seja, ContaEstudante também irá herdar ContaCorrente.
a classe ContaEstudante terá um limite que será bem menor do
que o da classe ContaEspecial.
as duas sub-classes deverão ser do tipo final.
Criar uma classe chamada UsaConta, que conterá um método main.
declarar dentro deste método um array de objetos do tipo
ContaCorrente (2 ou mais objetos).
inicializar cada um deles (pelo menos 1 de cada sub-classe)
Criar uma classe chamada Util, que contém um método estático
chamado impressao, sem tipo de retorno, que recebe como parâmetro um array de ContaCorrente.
dentro deste método haverá um laço que imprime o titular e irá
Interfaces
No exemplo anterior, usamos a função buzina()
abstrata para garantir o polimorfismo entre todas as sub-classes da super-classe
Automovel.
Essa é uma forma de obrigar o polimorfismo
entre as classes de uma mesma “família”.
Interfaces são classes que implementam apenas métodos sem corpo de código e
constantes e que podem ser utilizadas por
Interfaces
Interfaces servem principalmente para
organizar várias partes de um código:
a Sun fornece uma interface para banco de Dados.
Cada fabricante de banco de dados que quiser utilizar o Java deve implementar as funções de
acesso ao banco de dados usando estas interfaces. Desta forma, o acesso aos mais variados bancos de dados é feito sempre da mesma forma.
A declaração de uma interface é semelhante a
declaração de uma classe:
Interfaces
Para usarmos uma interface:
class Banco implements ContasDeBanco
Podemos ter herança em interfaces.
Interfaces podem herdar interfaces.
Podemos herdar múltiplas interfaces:
o resultado será a soma dos métodos e constantes das duas interfaces.
caso haja duas funções iguais em interfaces diferentes, com o mesmo nome e parâmetros iguais, elas devem ter o
mesmo tipo de retorno.
para implementar mais de uma interface:
Exercício
1. Modificar o exercício anterior (9) de forma
que agora tenhamos uma interface chamada
Conta, onde estejam definidos os cabeçalhos dos métodos extrato e deposito da super-classe ContaCorrente. A super-super-classe
Classe Object
Em Java todas as classes são, por padrão,
derivadas da classe Object.
Em conseqüência disso, herdamos algumas
funções, as quais podemos sobrescrever:
toString(): retorna uma String cujo conteúdo é o nome da
Classe Object
Por exemplo, dentro da nossa classe Carro podemos
sobrescrever o método toString():
public String toString(){
return(“Simulador de Carros versão 1.0”);
}
Dentro da classe UsaCarro, mandamos “imprimir”
nosso objeto Carro:
System.out.println(Carro);
Existem outras funções (ver documentação) como: equals() - a classe String sobrescreve este método para
Exercício
1. Dentro da classe ContaCorrente,
sobreescrever os métodos toString(),
equals().
o método toString() irá retornar o nome do
titular da conta.
duas contas serão iguais quando o titular e o
saldo da conta forem os mesmos.
Verificar na documentação da classe Object
o cabeçalho de tais métodos.
Na classe UsaConta comparar dois objetos
Tratamento de Erros
Erros estão constantemente ocorrendo nos
programas, por exemplo, quando ocorre uma divisão por zero, ou se tenta abrir um arquivo que não existe, ou se tenta acessar uma
posição inexistente de um array.
Em Java, um erro é chamado de “exceptional
event” (em português evento incomum). Ou simplesmente exception.
Quando um erro então ocorre, dizemos que o
Tratamento de Erros
Quando o programa dispara uma exceção, a
JVM cria um objeto com todas as informações sobre o erro ocorrido (tipo do erro, estado do programa, etc).
Podemos criar um trecho de código necessário
para pegar (catch) essa exceção (e manipular esse objeto com o erro ocorrido).
Podemos tentar recuperar o erro ocorrido ou exibir
Tratamento de Erros
Outra vantagem de usar gerenciamento de exceções é a
organização do código. Por exemplo, ao tentar ler um arquivo:
initialize errorCode = 0; open the file;
if (theFileIsOpen) {
determine the length of the file; if (gotTheFileLength) {
allocate that much memory; if (gotEnoughMemory) {
read the file into memory;
if (readFailed) { errorCode = -1; } }
else { errorCode = -2; } }
else { errorCode = -3; } close the file;
if (theFileDidntClose && errorCode == 0) { errorCode = -4; } else { errorCode = errorCode and -4; }
}
Tratamento de Erros
Utilizando o gerenciamento de exceções teríamos:
try {
open the file;
determine its size;
allocate that much memory; read the file into memory; close the file;
} catch (fileOpenFailed) { doSomething;
} catch (sizeDeterminationFailed) { doSomething;
} catch (memoryAllocationFailed) { doSomething;
} catch (readFailed) { doSomething;
} catch (fileCloseFailed) { doSomething;
Tratamento de Erros
A maioria das exceções está organizada em
grupos, que gerenciam determinados tipos de erros parecidos.
Por exemplo, ao utilizarmos um array,
poderíamos:
Tratamento de Erros
Podemos querer tratar cada um destes erros
especificamente, ou tratar qualquer erro sem distinção que ocorra com o array.
Como em Java as exceções são objetos, teríamos, por
exemplo, a seguinte hierarquia de classes:
ArrayException
NoSuchElementException
InvalidIndexException ElementTypeException
Tratamento de Erros
Poderíamos então fazer um bloco para pegar cada
erro específico, ou apenas utilizar um bloco com
ArrayException ou Exception.
Quanto mais específica a classe de exceção utilizada,
maiores serão os detalhes e as mensagem de erro.
InvalidIndexException, NoSuchElementException e
ElementTypeException são apenas exemplos.
Todas as exceções são classes descendentes da classe
Tratamento de Erros – Como usar
O gerenciamento de erros é feito através de 3
instruções:
try - identifica um bloco onde uma exceção pode
ser lançada
catch - vem logo após um bloco try, e identifica
um bloco de instruções que é um gerenciador para um tipo de exceção
finally - identifica um bloco que é executado
Tratamento de Erros – Como usar
Tente compilar e executar o seguinte código:
A saída será algo desse tipo:
class TesteErro {
static int divide(int a, int b) { int resposta = (a / b);
return resposta; }
public static void main(String[] args) {
System.out.println("3/0 = " + divide(3, 0)); System.out.println("6/2 = " + divide(6, 2)); }
}
java.lang.ArithmeticException: / by zero