JAVA e Orientação a Objetos 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 Pacotes JDBC 2 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 Projeto completo em JSP: Consultas e Relatórios Diversos exemplos práticos com JSP 3 O que é Java? 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. 4 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 parecido as duas. 5 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 • É multi-tarefa por padrão 6 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 stand-alone, aplicações client-server, aplicações para dispositivos móveis (celulares, Palms, javacards, etc) e aplicações para Internet (applets, JSP e servlets) 7 Principais usos • Área bancária • Serviços web distribuídos • Biotecnologia • Jogos • Processamento de imagens • Sistemas legados • Sistemas embutidos 8 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 discovery.com 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) 9 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 Aplicações para Web 10 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) • Linguagens Orientadas a Objeto (Small Talk, C++, Java) 11 Linguagens de Programação As linguagens de programação ainda diferem quanto a serem COMPILADAS ou INTERPRETADAS. Linguagens Interpretada Compilada Geração do Programa Escrever o código fonte Escrever o código fonte e compilar/linkeditar (gerar executável) Execução do Programa O S.O. precisa do O S.O. carrega Interpretador da direto o programa linguagem que vai ler o programa 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. 12 Linguagens de Programação 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. Linguagens Interpretada Java Compilada Geração do Programa Escrever o código fonte Escrever o código fonte e compilar (gerar byte code) Escrever o código fonte e compilar/linkeditar (gerar executável) Execução do Programa O S.O. precisa do Interpretador da linguagem que vai ler o programa O S.O. precisa da JVM para interpretar o byte-code O S.O. carrega direto o programa 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. 13 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 prática sejam a mesma coisa 14 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 o carro 15 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 qualquer tipo de programa, de uma forma ou de outra sempre utilizamos objetos. 16 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, EnviarParaImpressora, SincronizarAgencias, ImprimirNaTela, ComunicarOutroBanco, ComunicarOutraAgencia 17 Por que Orientação a Objetos? 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. Conta Agência Banco Tela BancodeDados Extrato Sincronizar TransferirDinheiro Comunicar Comunicar Imprimir Abrir Fechar 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. 18 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. Orientação a Objetos P. Procedural 19 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 Plataforma Java para servidores e computadores de grande porte. Possui um conjunto de funções maior do que o J2EE, visando integração em rede, aplicações web, etc. 20 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 automaticamente - ao contrário do C/C++ em que o programador é responsável por esta tarefa. 21 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 arquivo .class 22 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 Help (opcional) 23 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 (antigamente conhecido como Forte), disponível para Windows, Linux e Solaris. Porém é extremamente pesado! 24 JVM - Onde obter Somente a JVM: http://java.sun.com 25 SDK - Onde obter J2SE SDK (inclui JVM): http://java.sun.com 26 Help - Onde obter J2SE API Specification ONLINE: http://java.sun.com/j2se/1.4.1/docs/api/ 27 Help - Onde obter J2SE API Specification DOWNLOAD: http://java.sun.com/j2se/1.4/download.html 28 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 Windows JEdit (http://www.jedit.org) Notepad / Wordpad Editpad Lite (http://www.editpadlite.com) Linux Vi / Emacs Gedit / Kedit 29 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 instalação de programas, a maioria dos programas que utiliza a JVM irá procurá-la neste diretório. Deixar o SDK neste diretório padrão poupará esforços com configurações adicionais de outros softwares que utilizem Java. 30 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 O Linux, por sua vez, /var/tmp 31 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 utilizadas pelo Java para seu funcionamento. 32 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 inicialização do sistema. 33 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!”); } } 34 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 Executar o código e verificar se está correto: java HelloWorld 35 Importante! Don’t panic! Raramente erros! a compilação dá certo sem Geralmente os programas apresentam erros de sintaxe. Isso é normal! 36 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 bytecode (arquivo com a extensão .class). Utilizamos o comando JAVA para chamar a JVM, que irá interpretar o byte-code (arquivo .class). 37 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 se existem outros. 38 Erros de compilação – erros comuns Erros que externos ao código fonte ‘javac' não é reconhecido como um comando interno ou externo, um programa operável ou um arquivo em lotes. ‘java' não é reconhecido como um comando interno ou externo, um programa operável ou um arquivo em lotes. 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. 39 Erros de compilação – erros comuns error: cannot read: Teste.java 1 error 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 (.) 40 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. Erro no arquivo Teste.java Teste.java:4: ';' expected ^ 1 error Na linha 4 O compilador esperava (expected) achar um “ponto-e-vírgula” no final da linha O mesmo tipo de erro (<simbolo> expected) acontece quando no código está faltando algum símbolo de parênteses ou chaves. 41 Formato de uma classe class <nome> { int x; char c; funcao <nome>() { ... } Atributos do objeto Métodos } 42 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 43 Fundamentos da Linguagem 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 int soma() { x = a + b; return x; } 44 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 acima e também números 45 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): Várias linhas (multi-line): Multi-line com Javadoc: // comentário /* comentário */ /** 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 documentação externa. 46 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, throw, transient, true, try, void e while 47 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 nome da classe (inclusive maiúsculas e minúsculas) com a extensão .java 48 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) public static void main(String[] args) { //inicialização } A classe principal é a classe que será chamada pela JVM: java ClassePrincipal 49 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: int media = 0; 50 Variáveis em Java Variáveis para números inteiros: Tipo Variação Espaço em memória byte -128 até +127 1 byte short -32.768 até +32.767 2 bytes int -2.147.483.648 até +2.147.483.637 4 bytes long -922.337.203.685.475.808 até +922.337.203.685.475.807 8 bytes Obs: não temos o tipo unsigned como em C++ 51 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. Tipo Variação Espaço em memória float -3.4 x 10 38 até +3.4 x 10 38 4 bytes double -1.7 x 10 308 até +1.7 x 10 308 8 bytes 52 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: char meuCaracter = 'a'; 53 Variáveis em Java Tipos booleanos Utilizados para expressões lógicas, ocupam 1 bit, e possuem somente dois valores: true false Exemplo: boolean controle = false; 54 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: if(nome.equals(“Joao da Silva”)) System.out.println(“iguais”); 55 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 "Maria" é uma literal 56 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 A literal 2147483638 será tratada como tipo long 57 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: byte x = (byte) 10; 58 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 modificadores de tipo 59 Literais Booleanos – somente dois valores possíveis String – deve estar entre aspas duplas Exemplo de linha de código: true false String nome = "Maria"; Literais char – deve estar entre aspas simples Exemplo de linha de código: char c = 'a'; 60 Literais Para caracteres não expressáveis: '\t' '\b' '\n' '\r' Exemplo de linha de código: = = = = tab backspace nova linha voltar ao começo da linha (retorno do carro) System.out.println("Hoje o dia esta com\n Sol"); Sairia na tela como: Hoje o dia esta com Sol 61 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: final int MEDIA = 5; 62 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 Tabulações: devem ser abertas após a chave de abertura { e retroceder após a chave de fechamento } 63 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 inicialização, senão o compilador acusará um erro. 64 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; Acesso normal as variáveis do escopo x = 2; Acesso normal as variáveis do escopo principal } y = 3; ERRO: a variável não existe mais } 65 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: var += 1; 66 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: x = ((10 + (r * 4)) / 11) - 5; 67 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: public static void main(String[] args){ Calculo calc = new Calculo(); calc.expressao(); } Execute o código. Altere o código para que 2 seja dividido por 4 antes de ser multiplicado por 156. 68 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: se (notaAluno > 5) imprimaNaTela(“Aprovado!”); senão imprimaNaTela(“Reprovado!”); Formato no Java: if (<condicao>) <expressao1> else <expressao2> Onde o uso do else não é obrigatório 69 Expressões Condicionais if (<condicao>) <expressao1> else <expressao2> A condição da sentença acima geralmente envolve Operadores Lógicos, que em Java são: é igual diferente menor menor ou igual maior maior ou igual == != < <= > >= Operadores boleanos: e ou negação && || ! if (i == 1) if (i != 1) if ((i == 1) && (g >= 6)) if (!(i < 1)) Java também admite if na forma ternária: Imprima( (media > 5) ? "Aprovado" : "Reprovado" ) 70 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. class Bissexto { void verifica() { int ano = 1999; if () System.out.println(“Ano “ + ano + “ eh bissexto”); else System.out.println(“Ano “ + ano + “ nao eh bissexto”); } } Criar uma classe chamada UsaBissexto, que irá conter um método main, e dentro deste método chamar o método verifica. 71 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 { System.out.println(“Sábado"); } 72 Expressões Condicionais Uma outra forma de expressão condicional é o switch, que permite executar expressões condicionalmente baseadas em um valor inteiro. 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; case 7: System.out.println("Sábado"); break; } O switch executa a expressão case correspondente ao valor de sua expressão (nesse caso, diaSemana). 73 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. 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!"); } Se não houver um case correspondente, é executada a expressão default caso esta exista, senão nada é executado. 74 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 do que ficar reescrevendo o mesmo código várias vezes para cada aluno. 75 Laços Como na maioria das linguagens, em Java temos 3 tipos de laços: while do-while Em português, ENQUANTO. Executará o bloco de código apenas se uma condição for verdadeira. Semelhante ao while, com a diferença de que executará o bloco de código pelo menos uma vez. for Executará o bloco de código um número de vezes determinado por uma variável. 76 Laços Sintaxe: while (<condicao>) <codigo> do <codigo> while (<condicao>); int i = 0; while (i < 5) { System.out.println(i); i++; } int i = 0; do { System.out.println(i); i++; } while(i < 5); for (<valor inicial>; <condicao>; <atualizacao>) <codigo> for (int i = 0; i < 5; i++) { System.out.println(i); System.out.println("Teste de laço"); } 77 Exercício Escrever um programa que utilize while para inverter um número inteiro. 1. 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); } } 78 Ramificações Os comandos de ramificação permitem um controle mais avançado do fluxo nos laços. O Java suporta 3 comandos: break continue Permite sair no meio de um laço (break significa quebrar) Permite pular para a próxima iteração de um laço return Permite terminar a execução de um método 79 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 System.out.println("Palavra simples"); 80 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 System.out.println("Nao possui palavras comp."); 81 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 interrompe, e não executa o resto. O controle volta para a linha seguinte à que chamou a função. 82 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 diferente, a princípio. 83 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 compilador acusará erro. 84 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: Carro fusca = new Carro(); 85 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: fusca.modelo = “2004"; 86 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 char = ‘\u000’ = espaço String = null 87 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). No caso de Objetos, os próprios objetos são passados para o método, e não uma cópia (isso chama-se passagem por referência). 88 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. int soma(int a, int b) { int result = (a + b); return (result); } int soma(int a, int b) { return (a + b); } Caso não possua valor de retorno, o método deve conter em seu início a palavra void. void mostrarLogotipo() { // codigo } 89 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 classe. 90 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. Observar e entender os resultados. 91 class Carro { String combustivel; boolean ligado; boolean andando; public void ligar() { if(ligado) else{ } } System.out.println(“Erro: O carro ja esta ligado”); 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”); } } 92 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 diretamente pela classe sem precisar instanciála. 93 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++; Variável contador sendo incrementada TesteStatic t2 = new TesteStatic(); t2.contador++; Mesma variável contador sendo incrementada System.out.println(t2.contador); System.out.println(TesteStatic.contador); } Acesso a variável sem criar objeto } 94 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 precisamos criar nenhum objeto para utilizá-lo. 95 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: Util.inverte("abcdef"); 96 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 false e true, respectivamente, nosso simulador de Carro ficaria logicamente incorreto. 97 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 primeiramente devemos torná-los privados, o que impede de qualquer instância ler e alterálos. 98 Encapsulamento class Carro { String modelo; private String combustivel; private boolean ligado, andando; Atributos encapsulados // Funções ligar, desligar, andar e parar acessando agora as // variáveis privadas Método para atribuição e validação public void setCombustivel(String valor) { if ( valor.equals(“Gasolina”) || valor.equals(“Alcool”) ) combustivel = valor; else System.out.println(“Combustivel invalido!”); } Método para leitura public String getCombustivel() { return combustivel; } } 99 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; } } 100 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; } } 101 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 qual dos métodos sobrecarregados utilizar. 102 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 não possui tipo de retorno (nem o modificador void) 103 Construtores de Classes Quando utilizamos a instrução Carro fusca = new Carro(); Carro() está sendo o construtor executado. 104 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() {} O compilador assume que existe este construtor // Outros métodos } 105 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. Podemos fazer sobrecarga do construtor. 106 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. } 107 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. Este tamanho é fixo, e não pode ser alterado. 108 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 de tamanhos variáveis, existem outros tipos de estruturas em Java. 109 Arrays Para declarar um Array: <tipo>[] <nome> = new <tipo>[<quantidade>] ou: <tipo> <nome>[] = new <tipo>[<quantidade>] Exemplos: int[] x = new int[10]; int x[] = new int[10]; 110 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: notasTurma[0] = 5.5; 111 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, e não uma função, portanto não deve ser seguido por um par de parênteses! 112 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: java parametro1 parametro2 ... 113 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): int[][] i = new int[3][3]; 114 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]; cada objeto deve ser inicializado, um por um 115 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? 5. Qual o valor da expressão skiResorts[4]? 116 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); } } } 117 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 como sub-classe e a herdada como superclasse. 118 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, apenas acrescentar o atributo desejado. 119 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 construtor padrão não são herdados. 120 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 (herdamos apenas uma classe), nunca múltipla como em C++, o que evita complicações. 121 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 super. 122 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 não seja o padrão, é preciso explicitar que é outro construtor da super-classe que estamos chamando. 123 Herança class Pai { public Pai() { System.out.println("Construtor da super classe padrao"); } } class Filha extends Pai { // Construtor padrão declarado Mesmo declarando ou não o construtor padrão, public Filha() {} o construtor padrão da super classe será herdado public static void main(String[] args) { Filha teste = new Filha(); } } 124 Herança class Pai { public Pai() { System.out.println("Construtor da super classe padrao"); } Declarando um construtor diferente } do construtor padrão, é como se na class Filha extends Pai { // Construtor declarado public Filha(String s) { System.out.println(s); } primeira linha do construtor houvesse a instrução super(); , que chama o código do construtor padrão da super classe. public static void main(String[] args) { Filha teste = new Filha("Construtor da classe Filha"); } } 125 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. continua 126 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 ContaEspecial, e chamar o método extrato. 127 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): com as coleções heterogêneas. com os parâmetros polimórficos. 128 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 CarroFusca Calhambeque Caminhão 129 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). Esta coleção é uma Coleção Heterogênea. 130 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] autos[1] autos[2] autos[3] = = = = new new new new CarroFusca(); Automovel(); Calhambeque(); Caminhao(); 131 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” Caminhão - “Fom!” 132 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. Este fato é conhecido como parâmetro polimórfico. 133 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: abstract class Automovel 134 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 subclasses. 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 do polimorfismo. 135 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 subclasses, utilizamos o modificador final: final void ligar() 136 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á 137 chamar o método extrato() de cada elemento do array. 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 qualquer classe, mesmo que essa não seja uma sub-classe da Interface. 138 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: public interface ContasDeBanco 139 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: class Banco implements ContasDeBanco, ContasExternas 140 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 superclasse ContaCorrente. A super-classe ContaCorrente implementa esta interface. 141 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 seguido pela representação hexadecimal do objeto. Algumas vezes sobrescrevemos esse método para imprimir alguma mensagem quando o programa manda imprimir o objeto na tela. 142 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 comparar duas Strings. getClass(), clone(), etc 143 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 do tipo ContaCorrente. 144 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 programa Java disparou uma exception. 145 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 alguma mensagem informativa e sair gentilmente do programa. 146 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; } } else { errorCode = -5; } return errorCode; 147 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; } 148 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: tentar acessar uma posição que não existe inserir um elemento com algum tipo inválido procurar por um elemento que não existe 149 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: Exception ArrayException InvalidIndexException NoSuchElementException ElementTypeException 150 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 Exception, que é por sua vez descendente da classe Throwable. 151 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 incondicionalmente (utilizar finally não é obrigatório) 152 Tratamento de Erros – Como usar Tente compilar e executar o seguinte código: 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)); } } A saída será algo desse tipo: java.lang.ArithmeticException: / by zero at TesteErro.divide(TesteErro.java:3) at TesteErro.main(TesteErro.java:9) Exception in thread "main" 153 Tratamento de Erros – Como usar Quanto se tentou dividir 3 por 0, uma exceção ArithmeticException foi lançada. Como não havia ninguém para capturá-la nesta classe, o JVM capturou, exibiu uma mensagem de erro e fechou o programa. Podemos capturar e gerenciar a exceção antes: static int divide(int a, int b) { try { int resposta = (a / b); return resposta; } catch (ArithmeticException e) { System.out.println("Divisao por zero!"); return Integer.MAX_VALUE; } } 154 Tratamento de Erros – Como usar Agora a saída ficou: Divisao por zero! 3/0 = 2147483647 6/2 = 3 Quando uma exceção não é gerenciada, ela é lançada para a função que chamou a função atual. Para isso, especifica-se na declaração da função quais exceções ela lança, com o comando throws. Podemos fazer o gerenciamento de exceções como a seguir: 155 Tratamento de Erros – Como usar class TesteErro { static int divide(int a, int b) throws ArithmeticException { int resposta = (a / b); return resposta; } public static void main(String[] args) { try { System.out.println("3/0 = " + divide(3, 0)); System.out.println("6/2 = " + divide(6, 2)); } catch (ArithmeticException e) { System.out.println("Ocorreu um erro aritmético: " + e.getMessage()); } } A saída fica assim: Ocorreu um erro aritmético: / by zero 156 Tratamento de Erros – Como usar As exceções de linguagem (como divisão por zero ou array com índice não permitido) são descendentes da classe RuntimeException (que é descendente de Exception), e não precisam ser tratadas obrigatoriamente. Todos os outros tipos de exceção precisam obrigatoriamente ser tratadas, com try-catch, ou com throws. O compilador irá avisar que uma exceção não está sendo tratada através do erro de compilação: unreported exception <tipo da excessao>; must be caught or declared to be thrown 157 Tratamento de Erros – Como usar As exceções podem ser criadas e lançadas programaticamente também. Podemos usar uma classe já existente, ou criar a própria exceção, herdando de Exception ou uma classe mais especializada. Este tópico não será abordado, e pode ser visto no tutorial da Sun. 158 Exercício 1. No método principal da classe UsaConta, temos o trecho de código onde inicializamos as posições do array de contas. Por exemplo: contas[0] = new ContaEspecial(); contas[1] = new ContaEstudante(); Nada impede que tentemos inicializar uma posição que não existe, já que a exceção ArrayIndexOutOfBoundsException é classe filha de RunTimeException (ou seja, é uma exceção que não exige obrigação de ser tratada). continua 159 Exercício - continuação Consultar a documentação desta classe apenas para ver sua descrição e de quais classes ela descende. Colocar este trecho de código dentro de um bloco try/catch (como visto), usando como exceção a classe ArrayIndexOutOfBoundsException. Dentro do bloco catch imprimir na tela uma mensagem avisando que a posição acessada é inválida. Tentar inicializar (no bloco try) uma posição nãoexistente do array. 160 Wrapper Classes Para cada variável primitiva temos a respectiva classe que envolve tais variáveis. Tipo Primitivo boolean byte char double float int long short Classe Boolean Byte Char Double Float Integer Long Short 161 Wrapper Classes Estas classes são extremamente úteis, pois possuem métodos de conversão de um tipo primitivo para outro, e na prática muito utilizadas (ver documentação do Java). Vários destes métodos são estáticos. Por exemplo, a classe Integer possue um método chamado parseInt(). Este método converte uma String em um inteiro. Exemplo: String valor = “100”; int x = Integer.parseInt(valor); 162 Pacotes Pacotes nada mais são do que agrupamentos de classes. São utilizados para organizar a estrutura de classes, tendo em vista que existem milhares de classes criadas ao redor do mundo, e que existem centenas que acompanham a versão básica do Java. Todas as classes utilizadas até agora percentem ao pacote java.lang, que é implicitamente incluído em nossos programas. 163 Pacotes Existem várias outras classes que estão em outros pacotes (como por exemplo as classes que realizam Entrada/Saída), e para tais classes precisamos avisar o programa que utilizaremos tais pacotes. Fazemos isso através da instrução abaixo: import <nome-do-pacote> Obs: sem o símbolo de maior (<) e menor (>) 164 Pacotes Para utilizarmos a classe FileReader (que lê arquivos) , por exemplo, que está contida no pacote java.io: import java.io.FileReader; Para utilizarmos qualquer classe do pacote java.io: import java.io.*; 165 Pacotes Para criarmos um pacote, como primeira instrução das classes que irão o compor, devemos indicar o nome do pacote desejado com a seguinte instrução: package <nome-do-pacote>; É importante que todas as classes que irão formar o pacote tenham esta instrução. Tais classes devem estar dentro de um diretório com o mesmo nome do pacote. 166 Pacotes Como exemplo, poderíamos criar um pacote chamado agencia que conteria as classes ContaEspecial e ContaEstudante. Para utilizar tais classes, o programa principal deve “importar” as classes do pacote agencia: import agencia.*; Lembrando sempre que se os diretórios forem diferentes do diretório atual, devemos informar ao classpath (através das variáveis de ambiente ou durante a compilação). 167 Pacotes É possível ainda transformar um pacote de classes em um único arquivo com a extensão .jar. Tal arquivo nada mais é do que um arquivo comprimido. Com a ferramenta Jar ainda é possível criar aplicações executáveis para qualquer plataforma. Tais operações não são tão simples como criar um diretório como pacote. Para tal, existe uma trilha do Java Tutorial que cobre somente este assunto. 168 Exercício Com as classes do exercício anterior (ContaEspecial e ContaEstudante) criar um pacote chamado agencia: 1. criar uma pasta chamada agencia. exceto a classe UsaConta, MOVER todas as classes para dentro da pasta agencia. colocar a instrução package agencia; dentro de cada uma destas classes da pasta. certificar que todas as classes do pacote sejam públicas. Utilizar as classes dentro do pacote com a instrução import na classe UsaConta. Mudar o pacote de diretório e tentar utilizá-lo. 169 JDBC JDBC é um conjunto de classes e interfaces utilizados para que programas Java conversem com Sistemas Gerenciadores de Banco de Dados (ou simplesmente Banco de Dados) que utilizem o padrão SQL. Exemplo: Oracle, MS SQL Server, Sybase, etc Através do JDBC escrevemos apenas um código, que funciona com qualquer banco de dados SQL. 170 JDBC O princípio do funcionamento do JDBC é baseado no uso de interfaces: um conjunto de interfaces é entregue aos fabricantes de banco de dados pela Sun, que utilizam estas interfaces para implementarem os drivers para seu banco de dados. utilizamos estas interfaces implementadas (ou seja, classes) em nossas aplicações para conversar com o banco de dados desejado. 171 JDBC Podemos nos comunicar diretamente com o banco de dados, caso estejamos de posse do driver de tal banco (que em alguns casos é pago). Caso não se possa utilizar (ou comprar) um driver que converse direto com tal banco, o Java ainda pode “conversar” com o ODBC (já presente no Windows e Solaris). Isso é chamado de bridge JDBC-ODBC. 172 JDBC - onde obter O JDBC já faz parte do SDK desde a versão 1.1 O pacote que utilizaremos é o java.sql; Para instalar um driver em particular, este deve incluir as instruções de instalação. Geralmente consiste apenas em colocar o arquivo na pasta adequada. O ODBC já faz parte do Windows e Solaris. 173 JDBC - Conectando Como exemplo, vamos tomar uma base de dados em Microsoft Access, chamada Funcionarios, armazenada no arquivo Funcionarios.mdb Tal base possui apenas uma tabela chamada Cadastro: Campo Id Nome Idade Cargo Tipo auto-incremento cadeia de caracteres inteiro cadeia de caracteres 174 JDBC - Conectando Conectar uma aplicação a um Sistema Gerenciador de Banco de Dados (SGDB) exige dois passos: carregar o driver necessário para a conexão. estabelecer a conexão em si. 175 JDBC - Carregando um driver Carregar um driver exige apenas uma linha de código: Class.forName(<nome do driver>); Como em nosso exemplo iremos utilizar JDBCODBC, chamaremos a classe que faz a conexão: Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 176 JDBC - Carregando um driver Para utilizar um driver diferente, na documentação do mesmo está indicada o nome da classe que deveremos chamar. Por exemplo, se o nome da classe é jdbc.DriverXYZ, devemos utilizar a seguinte linha de código: Class.forName("jdbc.DriverXYZ"); Após carregar o driver, nossa aplicação estará pronta para fazer a conexão com o SGBD. 177 JDBC - Fazendo a conexão O segundo passo é utilizar o driver carregado para fazer a conexão. A seguinte linha de código mostra como funciona a idéia: Connection con = DriverManager.getConnection( <url>, <login>, <senha> ); 178 JDBC - Fazendo a conexão login é o login utilizado para acessar o SGBD. Se nosso login fosse, por exemplo, dbadmin: Connection con = DriverManager.getConnection( <url>, <login>, <senha> ); Connection con = DriverManager.getConnection( <url>, “dbadmin”, <senha> ); senha é a senha utilizada para acessar o SGBD. Se nossa senha para dbadmin fosse masterkey: Connection con = DriverManager.getConnection( <url>, “dbadmin”, “masterkey” ); 179 JDBC - Fazendo a conexão Connection con = DriverManager.getConnection( <url>, <login>, <senha> ); url, como estamos utilizando JDBC-ODBC, nossa URL começa com: jdbc:odbc: em seguida colocamos o nome da base de dados configurada no ODBC: jdbc:odbc:Funcionarios Cada driver avisará em sua documentação qual protocolo indicar ao jdbc. Por exemplo, um suposto protocolo acme nos avisaria que deveríamos usar: jdbc:acme: 180 JDBC - Fazendo a conexão Então, utilizando nossa base de dados Funcionarios, do Access (que não possui login nem senha) ficaríamos com a seguinte linha: Connection con = DriverManager.getConnection( <url>, <login>, <senha> ); Connection con = DriverManager.getConnection( “jdbc:odbc:Funcionarios”, “”, “” ); Pronto, estamos conectados ao SGDB. 181 JDBC - Fazendo consultas Para fazermos uma declaração SQL para o SGDB, após conectarmos precisamos criar um objeto Statement (em português, declaração). Statement stmt = con.createStatement(); Simplesmente criamos um objeto Statement e pedidos para ele executar nossa declaração SQL. utilizamos o método executeQuery para SELECTs. utilizamos o método executeUpdate para criar ou modificar tabelas. 182 JDBC - Fazendo consultas Em nosso exemplo da base de dados Funcionarios, iremos selecionar todos os dados da tabela Cadastro: stmt.executeQuery(“SELECT * FROM CADASTRO”); Instruções para criar e atualizar tabelas (função executeUpdate) não produzem resultados. Instruções com SELECT produzem resultados. 183 JDBC - Fazendo consultas stmt.executeQuery(“SELECT * FROM CADASTRO”); Para receber os resultados da linha de código acima precisamos criar um objeto ResultSet (em português, conjunto de resultados). Em nosso exemplo então teríamos a seguinte linha de código: ResultSet rs = stmt.executeQuery(“SELECT * FROM CADASTRO”); 184 JDBC - Fazendo consultas O objeto instanciado rs recebe todas as linhas do conjunto de resultados. Para irmos para a próxima linha, devemos chamar o método next. O objeto rs começa apontando para ANTES da primeira linha de resultado. Ou seja, devemos chamar ele antes de querer acessar qualquer resultado. 185 JDBC - Fazendo consultas Para acessar os elementos de cada linha de resultados, devemos utilizar o método getXXX apropriado (ver documentação). Nosso exemplo ficaria como abaixo: while (rs.next()){ int id = rs.getInt(“Id”); String n = rs.getString(“Nome"); int idade = rs.getInt(“Idade"); String c = rs.getString(“Cargo"); System.out.println(“Nome: ”+ n +”/tCargo: ” + c); } Saída tela: as operações, não podemos Apósna todas esquecer de fechar Nome: Jorgina de Freitasa conexão! Cargo: advogada Nome: Nicolau dos Santos Neto Cargo: juiz Nome: Paulo Cesar Farias Cargo: tesoureiro con.close(); Nome: Eurico do Vasco Miranda Cargo: gerente esportivo 186 JDBC - Resumo Carregar o driver apropriado Conectar utilizando o driver Criar um objeto para a declaração SQL Executar a declaração Pegar os resultados, se existirem. Fechar a conexão! 187 Exercício 1. Utilizando o arquivo banco.mdb (contido no CD): configurar o ODBC para acessá-lo. Utilizando o pacote agencia: criar uma classe UsaConta, que irá conter o método main. essa classe irá acessar o banco (seguindo os passos vistos), e ver o número de contas existentes na tabela contas (utilizando a instrução SQL que pede o máximo de contas existentes) e com este número criar um array de ContasCorrentes. após isso, selecionar tipo (especial ou estudante), saldo e titular de todas as contas e instanciar cada posição do array com estes dados. utilizando a classe Util, chamar o método impressao para este array 188 Bibliografia Java Home http://java.sun.com The Java Tutorial http://java.sun.com/docs/books/tutorial/index.html Java Almanac http://javaalmanac.com Developer Services http://developer.java.sun.com/developer/technicalArticles/Interviews/bioIt-conf/ Tutorial Java Unicamp http://www.ic.unicamp.br/~cmrubira/aacesta/java/javatut11.html Aulas Java - UFPE http://www.di.ufpe.br/~java/jai/aula1/polimorfismo.html Introdução ao Java – Prof. Peter Jandl Jr. – Núcleo de Educação a Distância – Univ. S. Francisco – 1999 189 Bibliografia Learning Java Code – Autor: Vinicius Morandin Senger http://www.globalcode.com.br Programação Orientada a Objetos – Autor:Ivan Luiz Marques Ricarte http://www.dca.fee.unicamp.br/courses/PooJava/ Aulas de Engenharia de Software FEI http://www.fei.br/eletrica/rbianchi/engesoft/aulas/EngSoft-aula-4.ppt Revista Info Exame – Edição novembro/2002Editora Abril http://www.infoexame.com.br Sistemas Orientados a Objetos – Aula 20 http://www.fic.br/~gaucho/SOO-I/aulas/aula20.htm Teach Yourself Java in 21 Days http://newdata.box.sk/bx/java/httoc.html Object Oriented Computing http://java.icmc.usp.br/ooc_course/ 190