Upload
eduardo-carvalho
View
316
Download
3
Embed Size (px)
Citation preview
Autor: Eduardo R. Carvalhoemail: [email protected]
Introdução ao Java
Apresentação Versão 1.3
Autor: Eduardo R. Carvalhoemail: [email protected]
24/04/15 Introução a Java 2
Apresentação
• Professor–Eduardo R. de CarvalhoCel: 91329676Contatos:
• Alunos– Resumo pessoal ?– Qual é a grande motivação para escolher este curso ?– Área de Atuação ?
24/04/15 Introução a Java 3
Agenda• [ Aula 1 ]
– Introdução– Variáveis– Operadores– Controle de Fluxo
• [ Aula 2 ]– Conhecendo a IDE– Introdução a Orientação a Objetos (UML)
• Classe – Atributos e Métodos
• Objetos– Relação com a memória
• Construtores• Herança
– Relação com construtores• Relacionamento “É UM” e “TEM UM”
24/04/15 Introução a Java 4
Agenda• [ Aula 3 ]
– Introdução a Orientação a Objetos (UML) (Cont)• Encapsulamento
– Modificadores de acesso em classes, atributos e métodos• Polimorfismo
– Overload ( sobre carga )– Override ( reescrita )
• Classe Abastrata• Interface• Modificadores de acesso
– final– static.
24/04/15 Introução a Java 5
Agenda
• [ Aula 4 ]–Modificadores de acesso
• final• static
–Orientação a Objetos ( cont. )• Classe Abastrata• Interface
–Revisão de Passagem de parametros• Valor ( tipos primitivos )• Referência ( objetos )
24/04/15 Introução a Java 6
Agenda• [ Aula 5 ]
– Tratamento de exceções ( pág 151 )• Bloco try/catch• Tipos de Exceções
– Verificadas– Não verificadas
• Objeto Exception• Lançamento de exceções
– throws– throw
• Restrições
– Javadoc• Tags• Importância da documentação
• [ Aula 6 ]
24/04/15 Introução a Java 7
[ Aula 1 ] - Agenda
• [ Aula 1 ]– Introdução–Variáveis–Operadores–Controle de Fluxo
24/04/15 Introução a Java 8
Java• Muitos associam Java com uma maneira de deixar suas
páginas da web mais bonitas, com efeitos especiais, ou para fazer pequenos formulários na web.
• O que associa as empresas ao Java?– Já iremos chegar neste ponto, mas antes vamos ver o motivo pelo
qual as empresas fogem das outras linguagens:
• Quais são os seus maiores problemas quando está programando?– ponteiros?– Liberar memória?– organização?– falta de bibliotecas boas?– ter de reescrever parte do código ao mudar de sistema
operacional?– custo de usar a tecnologia?
24/04/15 Introução a Java 9
Java• Java tenta amenizar esses problemas. Alguns
desses objetivos foram atingidos muito tempo atrás, porque, antes do Java 1.0 sair, a idéia é que a linguagem fosse usada em pequenos dispositivos, como tvs, aspiradores, liquidificadores e outros. Apesar disso a linguagem teve seu lançamento mirando o uso dela nos clientes web (browsers) para rodar pequenas aplicações (applets). Hoje em dia esse não é mais o foco da linguagem.
• O Java é desenvolvido e mantido pela Sun (http://www.sun.com) e seu site principal é o http://java.sun.com. (java.com é um site mais institucional, voltado ao consumidor de produtos e usuários leigos, não desenvolvedores).
24/04/15 Introução a Java 10
Principais Características• Orientada a Objetos - Baseado no modelo de
Smalltalk; • Portabilidade - Independência de plataforma
- "write once run anywhere"; • Recursos de Rede - Possui extensa biblioteca
de rotinas que facilitam a cooperação com protocolos TCP/IP, como HTTP e FTP;
• Segurança - Pode executar programas via rede com restrições de execução;
24/04/15 Introução a Java 11
Principais CaracterísticasAlém disso, podem-se destacar outras vantagens
apresentadas pela linguagem:• Sintaxe similar a Linguagem C/C++.
• Facilidades de Internacionalização
• Simplicidade na especificação, tanto da linguagem como do "ambiente" de execução (JVM);
• É distribuída com um vasto conjunto de bibliotecas (ou APIs);
• Possui facilidades para criação de programas distribuídos e multitarefa (múltiplas linhas de execução num mesmo programa);
24/04/15 Introução a Java 12
Principais Características• Desalocação de memória automática por processo
de coletor de lixo (garbage collector);
• Carga Dinâmica de Código - Programas em Java são formados por uma coleção de classes armazenadas independentemente e que podem ser carregadas no momento de utilização.
• Compilador Just In Time – Disponibiliza um mecanismo de verificar instruções que foram executadas varias vezes e as traduzem para linguagem nativa.
24/04/15 Introução a Java 13
JVM – Java Virtual Machine
• Programas Java não são traduzidos para a linguagem de máquina como outras linguagens estaticamente compiladas e sim para uma representação intermediária, chamada de bytecodes.
24/04/15 Introução a Java 14
JVM – Java Virtual Machine–O código Java é armazenado num arquivos
.java–Um programa .java é compilado para
arquivos .class–Bytecodes são interpretados em tempo de
execução
JVM – Java Virtual Machine
24/04/15 Introução a Java 15
24/04/15 Introução a Java 16
JVM? JRE? JDK?O que você vai baixar no site do java?• JVM = apenas a virtual machine, esse
download não existe• JRE = Java Runtime Environment, ambiente
de execução Java, formado pela JVM e bibliotecas, tudo que você precisa para executar uma aplicação Java.
• JDK = Nós, desenvolvedores, faremos o download do JDK do Java SE (Standard Edition).
Aonde Baixar o JAVA
• Site da Sun–http://java.sun.com/javase/downloads –Selecione o JDK 1.6 U7–Selecione o Sistema Operacional
24/04/15 Introução a Java 17
O que Configurar ?
• Configurações de Variáveis de Ambiente do Windows
• PATH–Caminho para o Arquivo java.exe e
javac.exe
24/04/15 Introução a Java 18
O que Configurar ?
24/04/15 Introução a Java 19
24/04/15 Introução a Java 20
Objetivos do Java• No decorrer do curso você pode achar que o Java tem baixa
produtividade, que a linguagem a qual você está acostumado é mais simples de criar os pequenos sistemas que estamos vendo aqui.
• Queremos deixar claro de que a premissa do Java não é a de criar sistemas pequenos, onde temos um ou dois desenvolvedores, mais rapidamente que linguagens como php, perl, entre outras.
• O foco da plataforma é outro: aplicações de médio a grande porte, onde o time de desenvolvedores tem várias pessoas e pode sempre vir a mudar e crescer. Não tenha dúvidas que criar a primeira versão uma aplicação usando Java, mesmo utilizando IDEs e ferramentas poderosas, será mais trabalhoso que usar uma linguagem script ou de alta produtividade. Porém, com uma linguagem orientada a objetos e madura como o Java, será extremamente mais fácil e rápido fazer alterações no sistema, desde que você siga as boas práticas, recomendações e design patterns.
24/04/15 Introução a Java 21
Compilando o primeiro programa
• Vamos para o nosso primeiro código! O programa que imprime uma linha simples!
1.class MeuPrograma {
2. public static void main(String[] args) {
3. System.out.println("Minha primeira” + “aplicação Java!!");
4. }
5.}
• Crie um Diretório com seu Nome e Salve o Programa com o seguinte Nome :
MeuPrograma.java
24/04/15 Introução a Java 22
Compilando o primeiro programa
• Entendendo :
1.class MeuPrograma {2. public static void main(String[] args) {
3. System.out.println("Minha primeira + “aplicação Java!!");
4. } // Fim do Metodo main
5.}
2. Declaração do Nome da Classe
1. Palavra Reservada que indica inicio de uma classe
Chaves que indicam inicio e fim de bloco de código
?
24/04/15 Introução a Java 23
Compilando o primeiro programa
1.class MeuPrograma {2. public static void main(String[] args) {
3. System.out.println("Minha primeira” + “aplicação Java!!");
4. } // Fim do Metodo main
5.}
2. Declaração do tipo de retorno do metodo, void indica sem retorno
1. Não se Preocupe com isso agora ... , só saiba que o método main necessita disso.
3. Nome do método, no caso o nome dele é main
4. Declaração de Parâmetros do método , no caso ele recebe um array de Strings chamado de args.
Os Parênteses são Obrigatórios para todo método.
24/04/15 Introução a Java 24
A numeração das linhas não faz parte do código e não deve ser digitada; é apenas didático. O java é case sensitive.Tome cuidado com maiusculas e minusculas.
Compilando o primeiro programa
24/04/15 Introução a Java 25
Compilando o primeiro programa
• Após digitar o código acima, grave-o como MeuPrograma.java em algum diretório. Para compilar, você deve pedir para que o compilador de Java da Sun, chamado javac, gere o bytecode correspondente do seu código Java.
24/04/15 Introução a Java 26
Compilando o primeiro programa• Acesse a Linha de Comando do Windows• Procure o diretório onde o código MeuPrograma.java foi salvo.
• Digite na linha de comando a instrução abaixo
C:\cd <meu_diretorio>C:\meu_diretorio\javac MeuPrograma.javadir
• O que teremos no diretório !!!
24/04/15 Introução a Java 27
Palavras Reservadas
booleanbytechardoublefloatintlongshortvoid
falsenulltrue
abstractfinalnativeprivateprotectedpublicstaticsynchronizedtransientvolatile
breakcasecatchcontinuedefaultdoelsefinallyforifreturnswitchthrowtrywhile
classextendsimplementsinterfacethrowsenum
importpackage
instanceofnewsuperthis
24/04/15 Introução a Java 28
Variáveis• Variáveis de instância (atributos não-
estáticos): valores únicos por instância de objeto.
• Variáveis de Classe (atributos estáticos): declarado através do modificador static, seu valor é único para todas as instâncias de objetos.
• Variáveis locais: variáveis declaradas dentro de { e }, como métodos.
• Parâmetros: classificados sempre como variáveis, os parâmetros são declarados na assinatura de métodos.
24/04/15 Introução a Java 29
Regras e Convenções
• Variáveis– Nomes de variáveis são case-sensitive.– Pode conter qualquer identificador legal de
qualquer tamanho iniciando com uma letra, $ ou underscore (_). Mas recomenda-se sempre iniciar com uma letra.
– Espaços em branco não são permitidos.– Caracteres subseqüentes podem ser letras,
números $ ou underscore. – Por convenção, usar palavras inteiras ao invés de
abreviações.– Palavras chaves ou reservadas não são
permitidas.
24/04/15 Introução a Java 30
Regras e Convenções
• Variáveis– Se o nome consistir de uma só palavra,
recomenda-se que se declare usando letras minúsculas. Se consistir de mais de uma palavra, recomenda-se capitalizar a primeira letra da palavra subsequente a primeira, como por exemplo:• cargo• cargoAtual
– Para constantes, a convenção muda: todas as palavras em letras maiúsculas separadas por underscore, como por exemplo:• NUMERO_DE_CONEXOES
24/04/15 Introução a Java 31
Declaração de Variáveis
tipo variavel [ = valor]
boolean result = true;
int i = 100000;
Declaração do Tipo da Variável
Declaração Variável
Valor Atribuído
Atribuição de Valor
24/04/15 Introução a Java 32
Tipos Primitivos• byte: 8 bits com sinal
– De -27 à 27-1 ou de -128 à 127
• short: 16 bits com sinal– De -215 à 215-1 ou de -32.768 à 32.767
• int: 32 bits com sinal– De -231 à 231-1 ou de -2.147.483.648 à 2.147.483.647
• long: 64 bits com sinal– De -263 à 263-1
• float: 32 bits com sinal– De 1.40239846e-46 à 3.40282347e+38
24/04/15 Introução a Java 33
Tipos Primitivos• double: 64 bits com sinal
– De 4.94065645841246544e-324 à 1.7976931348623157e+308
• boolean: true ou false
• char: 16 bits sem sinal– De '\u0000' à '\uffff' ou de 0 à 65.535
24/04/15 Introução a Java 34
Tipos Primitivos: Observações
• Para otimização de memória, recomenda-se, sempre que possível, utilizar arrays de byte ou short ao invés de int ou long.
• O mesmo é válido para arrays de float ao invés de double.
• Os tipos float e double NUNCA devem ser usados para valores precisos, como moeda, por exemplo. Para isso, recomenda-se utilizar a classe java.math.BigDecimal.
• Para cadeias de caracteres a linguagem Java provê suporte através da classe java.lang.String.
• A classe String não é tecnicamente um tipo primitivo mas devido a sua importância é tratado como se fosse.
• Objetos do tipo String são imutáveis.
24/04/15 Introução a Java 35
Tipos Primitivos: Valores Defaults
Tipo do Dado Valor Defaultbyte 0
short 0
int 0
long 0L
float 0.0f
double 0.0
char '\u0000'
String null
boolean false
24/04/15 Introução a Java 36
Literais
• Um literal é simplesmente a representação do código-fonte dos tipos de dados primitivos – em outras palavras, um inteiro, um ponto flutuante, um booleano ou caractere que você digite enquanto escreve o código. A seguir temos exemplos de literais primitivos.
24/04/15 Introução a Java 37
Exemplos de Literais
boolean result = true;char capitalC = 'C';byte b = 100; short s = 10000;
int i = 100000;
Declaração do Tipo da Variável
Declaração Variável
Valor Atribuido
Atribuição de Valor
24/04/15 Introução a Java 38
Literais: Tipo NuméricosRepresentação de Tipos Numéricos
int decimal = 26; //O número 26 em decimalint octal = 032; //O número 26 em octalint hexa = 0x1a; //O número 26 em hexadecimal
24/04/15 Introução a Java 39
Literais: Ponto Flutuante
Representação de Pontos Flutuantes
double d1 = 123.4;double d1 = 123.4D; //ou ddouble d2 = 1.234e2; //o mesmo valor de d1, mas
//em notação científicafloat f1 = 123.4f; //ou F
24/04/15 Introução a Java 40
Literais: Tipo CaractereRepresentação de Caracteres
char p = 'C';char a = '\u0043'; // Valor UnicodeString s = “Linguagem Java”;String x = “Linguagem \u0043#”; //Linguagem C#
24/04/15 Introução a Java 41
Literais: Seqüências Especiais de Caracteres
\b: Backspace\t: TAB\n: Quebra de Linha\f: Alimentação de Folha\r: Retorno de Linha\": Aspas Duplas\': Aspas Simples\\: Barra Invertida
24/04/15 Introução a Java 42
Exercícios1) Criar um pequeno programa que define
algumas variáveis. Tentar criar alguns atributos usando nomes ilegais e ver que tipo de erro é reportado pelo compilador . Usar as regras e convenções como guia.
2) Criar um programa que imprima a seguinte mensagem na tela:
c:\>java TesteDeString“Java
iseverywhere!”
24/04/15 Introução a Java 43
Questões1) O termo "variável de instância" é outro nome para:
atributo não-estático1) O termo "variável de classe" é outro nome para:
atributo estático1) Uma variável local tem um estado temporário; Ela é
declarada dentro de:um método
1) Uma variável declarada entre parênteses de um método é chamada de:
parâmetro1) Quais são os oito tipos primitivos suportados pela linguagem
Java?byte, short, int, long, float, double, boolean e char
1) Strings são representadas através da classe:java.lang.String
24/04/15 Introução a Java 44
Operadores
• Cinco tipos de operadores:–Atribuição–Aritméticos–Manipulação de bits–Relacionais–Condicionais
24/04/15 Introução a Java 45
Operador de Atribuição
• A expressão da direita é atribuída à variável da esquerda:
– int var1 = 0, var2 = 0;– var1 = 50; // var1 recebe o valor de 50– var2 = var1 + 10; // var2 ficou igual a 60
• A expressão da direita é sempre avaliada antes da atribuição.
• As atribuições podem ser agrupadas:
var1 = var2 = var3 = 50;
24/04/15 Introução a Java 46
Operadores Aritméticos
• Realizam operações aritméticas básicas– Operam sobre variáveis e literais
numéricos
int a, b, c, d;
a = 2 + 2; // adição
b = a * 3; // multiplicação
c = b - 2; // subtração
d = b / 2; // divisão
e = b % 2; // retorna o resto da divisão
24/04/15 Introução a Java 47
Operadores Aritméticos
• A maioria das operações resultam num int ou long:
– byte b1 = 1, b2 = 2, b3;– b3 = b1 + b2; // error: result is an int // b3 is byte
• Valores byte, char, e short são promovidos a int antes da operação.
• Se algum argumento for long, o outro é promovido a long, e o resultado é long.
24/04/15 Introução a Java 48
Conversões e Casts
• O Java converte automaticamente valores de um tipo numérico para outro tipo maior.
• O Java não faz automaticamente o “downcast.”
byteshort
int long
byteshort
int long
24/04/15 Introução a Java 49
Incrementar e Decrementar
• O operador ++ incrementa 1 unidade
1. int var1 = 3;
2. var1++; // var1 esta igual a 4
• O operador ++ pode ser usado de duas maneiras:
1. int var1 = 3
2. Int var2 = 0;
3. var2 = ++var1; //Pré Incrementa var1 e depois atribui o Valor a var2.
4. var2 = var1++; //Atribui o Valor a var2 e depois incrementa var1
O operador -- decrementa 1 unidade
24/04/15 Introução a Java 50
Comparações
• Operadores relacionais e de igualdade:• > maior que • >= maior igual que • < menor que• <= menor igual que • == igual a • != diferente de
• int var1 = 7, var2 = 13; • boolean res = true; • res = (var1 == var2); // res igual a false
• res = (var2 > var1); // res igual a true
24/04/15 Introução a Java 51
Operadores Lógicos
• Os resultados de expressões Booleanas podem ser combinados usando operadores lógicos
1. int var0 = 0
2. int var1 = 1
3. int var2 = 2;
4. boolean res = true;
5. res = (var2 > var1) & (var0 == 3); // now false
6. res = !res; // now true
&& & e , e (bit a bit)
|| | ou, ou (bit a bit)
^ Ou Exclusivo
! negativa
24/04/15 Introução a Java 52
Precedência de Operadores
Operador Descrição Associação
1 ++ -- + - ~ ! (type) Operadores Unários Direita
2 * / % Multiplicação , Divisão , Resto da divisão Esquerda
3 + - + Adição , Subtração, Concatenar Strings Esquerda
4 << >> >>> Shift Esquerda
5 < > <= >= instanceof
Relacional , Comparação de Tipos Esquerda
6 == != Igualidade Esquerda
7 & Bit/Logico E Esquerda
8 | Bit/Logico Ou Esquerda
9 ^ Bit/Logico Ou Exclusivo Esquerda
10 && Logico E Esquerda
11 || Logico Ou Esquerda
12 ?: Operador Condicional Direita
13 = Atribuição de Valor Direita
24/04/15 Introução a Java 53
Comandos de Fluxo• Sentenças de Decisão
– if-then– if-then-else– switch
• Sentenças de Loop– for– while– do-while
• Sentenças de Resumo– break– continue– return
24/04/15 Introução a Java 54
Comandos de Fluxo: if-then
Sintaxe:
if(condição) { // se condição atendida comandoA(); // então
comandoB();} // fim se
ouif(condição) comandoA();
24/04/15 Introução a Java 55
Comandos de Fluxo: if-then-else
Sintaxe:
if(condição) { // se condição atendida então: comandoA();
comandoB();} else { // se condição não atendida
comandoC();}
Ou
(condição) ? <se a condição antendida> : <se a condição não foi atendida> ;
24/04/15 Introução a Java 56
Comandos de Fluxo: ifExemplos: if-then e if-then-else
1. class MeuPrograma {2. public void facaAlgo(boolean condicao, int x){3. if (condicao == true)4. adicionar(x);5. }6. public void facaAlgo(boolean condicao, int x, int y){7. if (condicao == true) {8. adicionar(x);9. } else {10. adicionar(x,y); 11. } 12. }13.}
24/04/15 Introução a Java 57
Comandos de Fluxo: if
Exemplos: if-then e if-then-else
1. class MeuPrograma {2. //Exercicio53. public void testeIfThenElse(String acao, int x,int y){4. if (acao.equals(“adicionarX”)){5. adicionar(x);6. } else if (acao.equals(“adicionarY”)){7. adicionar(y);8. } else if (acao.equals(“adicionarXY”)){9. adicionar(x,y);10. } else {11. adicionar(x);12. }13. }14. ...13.}
24/04/15 Introução a Java 58
Comandos de Fluxo: switchSintaxe:
switch(variavel a ser avaliada) { case 1: comando1(); comando2(); break; case 2: ... break; case X: ... break; default: ... }
24/04/15 Introução a Java 59
Comandos de Fluxo: switchExemplo
1. class MeuPrograma {2. //Exercicio 63. public void testeSwitchInt(int x){4. switch (x) {5. case 1:6. x = x + 1;7. break; 8. case 2:9. x = x + 2; 10. case 3:11. x = x + 3;12. default:13. x = x + 1; 14. } 15. System.out.println(x); // Saída?16. }17. ...13.}
24/04/15 Introução a Java 60
Comandos de Fluxo: switchExemplo
1. class MeuPrograma {2. public void testeSwitchChar(char resposta){3. switch (resposta) {4. case ‘s’:5. System.out.println(“SIM”); 6. break; 7. case ‘n’:8. System.out.println(“NÃO”); 9. break; 10. default:11. System.out.println(“Nem Sim nem NÃO”);12. }13. } 14. ...14.}
24/04/15 Introução a Java 61
Comandos de Fluxo: while
Sintaxe:
while(condição) { comandoA(); comandoB(); }
24/04/15 Introução a Java 62
Comandos de Fluxo: while
Exemplo
1. class MeuPrograma {
2. public void testeWhile( int tentativas ) {
3. int posicao = 0;
4. while ( posicao < tentativas ) {
5. System.out.println(“Posicao =” + posicao);
6. posicao++ // igual a posicao = posicao + 1;
7.
8. }
9. }
10. }
24/04/15 Introução a Java 63
Comandos de Fluxo: do-while
Sintaxe:
do { comandoA(); comandoB(); } while(condição);
24/04/15 Introução a Java 64
Comandos de Fluxo: do-while
Exemplo
1. class MeuPrograma {
2. public void testeDoWhile(int tentativas){
3. int posicao = 0;
4. do {
5. System.out.println(“Posicao =” + posicao);
6. posicao++;
7. } while (posicao < tentativas) ;
8. }
8.}
24/04/15 Introução a Java 65
Comandos de Fluxo: forSintaxe:
for(inicialização; condição; incremento) { comandoA(); comandoB();
}
24/04/15 Introução a Java 66
Comandos de Fluxo: for
Exemplo
1. class MeuPrograma {
2. public void testeFor(int tentativas){
3. for (int i = 0; i < tentativas ; i++) {
4. System.out.println(“Posicao =” + i);
5. }
6. }
7.}
24/04/15 Introução a Java 67
Comandos de Fluxo: forExemplo
1. class MeuPrograma {2. public void testeForSemArgumentos(int tentativas){3. int i = 0;4. for (;;) {5. if (i < tentativas) 6. break;7. System.out.println(“Posicao =” + i); 8. i++; 9. }10. }11. ....11.}
24/04/15 Introução a Java 68
Comandos de Fluxo: break
Exemplo
1. class MeuPrograma {
2. public void testeBreak(int tentativas){
3. int i = 0;
4. for (;;) {
5. if (i < tentativas)
6. break; // Abandona o Loop
7. System.out.println(“Posicao =” + i);
8. i++;
9. }
10. }
11.}
24/04/15 Introução a Java 69
Comandos de Fluxo: continue
Exemplo
1. class MeuPrograma {2. public void testeContinue(){3. String frase = “o rato roeu a roupa do rei de roma”;4. int numDeRs = 0;5. for (int i = 0; i < frase.length() ;i++) {6. if (frase.charAt(i) != ‘r’) {7. continue; // Vai para próxima iteração do Loop.8. }9. numDeRs ++;
} System.out.println(“ Caraca .... Não é que funciona ... ” + numDeRs );
2. }14.}
24/04/15 Introução a Java 70
Exercícios• Considere:
if (umNumero >= 0) if (umNumero == 0) System.out.println("primeira string");else System.out.println("segunda string");System.out.println("terceira string");
• Qual saída será reproduzida se umNumero for 3?
• Escreva um programa contendo o código anterior; faça umNumero = 3. – Qual é a saída do programa? – Era o esperado? Explicar o porque do resultado.
• Usando somente espaços e quebras de linhas, torne o código melhor de ser lido.
• Use { } para tornar o código mais legível.
Exercícios de Certificaçãopublic class BooleanTest {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
boolean c = true;
if (a == true)
if (b == true)
if (c == true) System.out.println("Tudo true");
else System.out.println("Nada true");
else if (a && (b=c)) System.out.println("Caraca o que é true");
else System.out.println("Que bagunça");
}
}
Qual será o produto da execução desta classe ?
24/04/15 Introução a Java 71
Exercícios de Certificaçãopublic class BooleanTest2{
public static void main(String[] args) {
int i =0;
while ( i > 0 ) {
System.out.println("While Valor de : i " + i );
}
do {
System.out.println("DoWhile Valor de : i " + i );
i++;
} while ( i > 2) ;
}
}
Qual será o produto da execução desta classe ?
24/04/15 Introução a Java 72
Exercícios de Certificação
• Quais das Alternativas abaixo será compilada sem warning ou Erro ?
a)float f1 = 1.2357;b)char a = “X”;c)byte b1 = 1452;d)boolean b = null;e)int k = 10;f)Double d = 10;
24/04/15 Introução a Java 73
24/04/15 Introução a Java 74
Exercicíos para CasaNão copie e cole de um exercício já existente! Aproveite para
praticar.
1) Imprima todos os números de 150 a 300.2) Imprima a soma de 1 até 1000.3) Imprima todos os múltiplos de 3, entre 1 e 100.4) Imprima os fatoriais de 1 a 10.
• O fatorial de um número n é n * n1 * n2 ... até n = 1. Lembrese de utilizar os parênteses.
• O fatorial de 0 é 1• O fatorial de 1 é (0!) * 1 = 1• O fatorial de 2 é (1!) * 2 = 2• O fatorial de 3 é (2!) * 3 = 6• O fatorial de 4 é (3!) * 4 = 24
• Faça um for que inicie uma variável n (número) como 1 e fatorial (resultado) como 1 e varia n de 1 até 10:
for (int n=1, fatorial=1; n <= 10; n++) {
24/04/15 Introução a Java 75
Questões
• O mais básico controle de fluxo suportado pelo Java é:
if-then• O ___ é similar a sentença while mas avalia a
expressão no ___ do loop. do-while e final
• Como escrever um loop infinito usando a sentença for?
for( ; ; ) { }
• Como escrever um loop infinito usando a sentença while?
while(true) { }
24/04/15 Introução a Java 76
Aula 2
• Agenda– IDE e suas principais características–OO Conceitos Básicos–OO Herança, Reescrita e Polimorfismo
24/04/15 Introução a Java 77
IDE• Acrônimo para Integrated Development
Environment ou Ambiente de Desenvolvimento Integrado
• Reúne ferramentas de apoio ao desenvolvimento de software com o objetivo de agilizar o processo.
• Geralmente as IDEs unem a técnica de RAD (Rapid Application Development), que consiste em permitir que os desenvolvedores obtenham um aproveitamento maior, desenvolvendo código com maior rapidez.
24/04/15 Introução a Java 78
IDE – Principais Características• Editor: permite a edição de código-fonte do
programa na linguagem suportada pela IDE; • Compilador: compila o código-fonte do
programa transformando-o em linguagem de máquina;
• Debug: auxilia no processo de encontrar e corrigir erros (bugs) no código-fonte do programa, na tentativa de aprimorar a qualidade de software;
• Modelagem: criação do modelo de classes, objetos, interfaces, associações e interações dos artefatos envolvidos no software;
24/04/15 Introução a Java 79
IDE – Principais Características• Geração de Código: característica mais explorada em
ferramentas CASE, a geração de código também é encontrada em IDEs, contudo com um escopo mais direcionado a templates de código comumente utilizados para solucionar problemas rotineiros.
• Distribuição (Deploy): auxilia no processo de criação do instalador do software, ou outra forma de distribuição do mesmo, seja discos ou via internet.
• Testes Automatizados: realiza testes no software de forma automatizada, com base em scripts ou programas de testes.
• Refatoração (refactoring): consiste na melhoria constante do código-fonte do software, seja na construção de código mais otimizado, mais limpo e/ou com melhor entendimento pelos envolvidos no desenvolvimento do software.
24/04/15 Introução a Java 80
IDE - NetBeans 6.1
Conhecendo o NetBeans 6.1www.netbeans.org
24/04/15 Introução a Java 81
OO – Conceitos Básicos
• Paradigma• Conceitos Básicos• Herança, Reescrita e Polimorfismo
Paradigma Procedural
• Apresenta problemas com o aumento de complexidade:– Dificuldade de manutenção– Problemas no isolamento de erros– Pouquíssimo reaproveitamento de código– Número excessivo de funções se torna fora de controle.
• Conseqüências : – Aumento no prazo de entrega de Sistemas – Diminui a precisão na estimativa de Sistemas– Sistemas com perda de qualidade– Alto custo de manutenabilidade.– Alto custo evolutivo.
24/04/15 Introução a Java 82
Paradigma OO• Visão do Mundo Real:
– É um paradigma avançado de programação que engloba um conjunto de teorias, padrões e métodos que juntos representam uma forma de organizar conhecimento. Este paradigma é baseado no conjunto de abstrações de classes e objetos e empacota dados e procedimentos em um mesmo elemento (objeto). Os objetos se comunicam pela passagem de mensagens.
– Este paradigma permite criar programas muito mais próximos da nossa realidade, programas que contenham uma conjunto de características e comportamentos.
24/04/15 Introução a Java 83
24/04/15 Introução a Java 84
OO – Conceitos Básicos
• O que é um objeto?–Um objeto é uma ocorrência específica
(instância) de uma classe e é similar a uma tabela no modelo relacional mas somente até o ponto onde representa uma coleção de dados relacionados com um tema em comum.
24/04/15 Introução a Java 85
OO – Conceitos Básicos• Exemplo de Objetos:
Características- cor- material- dimensões- fabricante*---------------Operações-apitar-boiar
Características- tamanho- tipo- fabricante*---------------Operações-add-sub-div-mult
Características- nome- cnpj- ie - produtos[]---------------Operações-fabricar-vender-comprar
24/04/15 Introução a Java 86
OO – Conceitos Básicos• Consideremos um programa para banco:
– O que toda conta tem e é importante para nós?• Número da Conta• Nome do Cliente• Saldo• Limite
– O que toda conta faz e é importante para nós?• Saca uma quantidade x• Deposita uma quantidade x• Imprime o nome do dono da conta• Devolve o saldo atual• Transfere uma quantidade x para uma outra conta y• Devolve o tipo de conta
24/04/15 Introução a Java 87
OO – Conceitos Básicos
• Com isso temos o projeto de uma conta bancária. Podemos pegar esse projeto e acessar seu saldo? Não. O que temos ainda é o projeto. Antes precisamos construir uma conta, para poder acessar o que ela tem, e pedir para ela fazer alguma coisa.
24/04/15 Introução a Java 88
OO – Conceitos Básicos
• Ao projeto da conta, isto é, a definição
da conta, damos o nome de classe. O que podemos construir a partir desse projeto, que são as contas de verdade,
damos o nome de objetos.
24/04/15 Introução a Java 89
OO – Conceitos Básicos• A palavra classe vem da taxonomia da biologia.
Todos os seres vivos de uma mesma classe biológica tem uma série de atributos e comportamentos em comuns, mas não são iguais, podem variar nos valores desses atributos e como realizam esses comportamentos.
• Homo Sapiens define um grupo de seres que possuem característcas em comuns, porém a definição (a idéia, o conceito) de um Homo Sapies é um ser humano? Não. Tudo está especificado na classe Homo Sapiens, mas se quisermos mandar alguem correr, comer, pular, precisaremos de uma instância de Homo Sapiens, ou então de um objeto do tipo Homo Sapiens.
24/04/15 Introução a Java 90
OO – Conceitos Básicos• Um outro exemplo: uma receita de bolo.• A pergunta é certeira: comemos uma receita
de bolo? Não. Precisamos instaciá-la, criar um objeto bolo a partir dessa especificação (a classe) para utilizá-la. Podemos criar centenas de bolos a partir dessa classe (a receita, no caso), eles podem ser bem semelhantes, alguns até idênticos, mas são objetos diferentes.
OO – Conceitos Básicos
• Classe X Objetoa)Classe: é definição do tipo, ou seja, é o código fonte
de seu objeto;b)Objeto: é cada instância derivada da classe (é a
classe sendo executada).
24/04/15 Introução a Java 91
24/04/15 Introução a Java 92
OO – Conceitos Básicos
• Definição da classe conta em UML:
24/04/15 Introução a Java 93
OO – Conceitos Básicos
• Definição da classe conta em Java:
1. class Conta {
2. int numero;
3. String nome;
4. double saldo;
5. double limite;
6. }
24/04/15 Introução a Java 94
OO – Conceitos Básicos• Por enquanto declaramos o que toda
conta deve ter. Estes são os
atributos que toda conta, quando criada, vai ter.
• Quando uma variável é declarada diretamente dentro do escopo da classe, é chamada de variável de
objeto, ou atributo.
24/04/15 Introução a Java 95
OO – Conceitos Básicos• Dentro da classe, também iremos declarar o que
cada conta faz, e como isto é feito. Os comportamentos que cada classe tem, isto é, o que ela faz.
• Por exemplo: de que maneira que uma Conta saca dinheiro?
• Iremos especificar isso dentro da própria classe Conta, e não em um local desatrelado das informações da própria Conta. É por isso que essas
“funções” são chamadas de métodos pois é a maneira de fazer uma operação com um objeto.
24/04/15 Introução a Java 96
OO – Conceitos Básicos• Por exemplo: Queremos criar um método
que realiza a operação de sacar uma determinada quantia e não retorna nenhuma informação para quem acionar esse método.
• Definição do método em UML:
24/04/15 Introução a Java 97
OO – Conceitos Básicos
• Definição do método em Java:
1. void sacar(double quantia) {
2. this.saldo = this.saldo - quantia;
3. }
24/04/15 Introução a Java 98
OO – Conceitos Básicos• Quando alguém realizar um saque será
preciso informar quanto quer sacar. Por isso precisamos declarar o método com o que chamamos de argumento(s) do método ou parâmetro(s).
• Essa variável é uma variável comum, chamada também de temporária ou local, pois ao final da execução desse método, ela deixa de existir.
24/04/15 Introução a Java 99
OO – Conceitos Básicos
• Da mesma forma, temos o método para realizar o depósito de uma quantia:
24/04/15 Introução a Java 100
OO – Conceitos Básicos
• Definição do método depositar em Java:
1. void depositar(double quantia){
2. this.saldo += quantia;
3. }
24/04/15 Introução a Java 101
OO – Conceitos Básicos
• Exercício:–Fazer as seguintes atividades:
• Definir a classe Conta;• Criar uma classe auxiliar (TesteConta) e
através do método main desta classe:– Criar uma Conta;– Definir um nome e um saldo inicial;– Realizar um saque;– Realizar um depósito;– Imprimir o saldo;
24/04/15 Introução a Java 102
OO – Conceitos Básicos• Um método pode retornar um valor para o código
que o chamou. No caso do nosso método sacar podemos devolver um valor booleano indicando se a operação foi bem sucedida.
1. boolean sacar(double quantia) {2. if (this.saldo < quantia) {3. return false;4. } else {5. this.saldo = this.saldo – quantia;6. return true;7. }8. }
24/04/15 Introução a Java 103
OO – Conceitos Básicos
• Definição do método sacar em UML:
24/04/15 Introução a Java 104
OO – Conceitos Básicos
• Exemplo de uso:
1. minhaConta.saldo = 1000;
2. boolean sucesso = minhaConta.sacar(2000);
3. if(sucesso) {
4. System.out.println(“Saque realizado com sucesso!”);
5. } else {
6. System.out.println(“Saque não realizado. Quantia “
7. + “superior ao saldo disponível.”);
8. }
24/04/15 Introução a Java 105
OO – Conceitos Básicos• Nosso programa pode manter na memória não só uma conta,
como mais de uma:
class TestaDuasContas {public static void main(String[] args) {
Conta minhaConta;minhaConta = new Conta();minhaConta.saldo = 1000;
Conta meuSonho;meuSonho = new Conta();meuSonho.saldo = 1500000;
}}
24/04/15 Introução a Java 106
OO – Conceitos Básicos• Quando declaramos uma variável para associar a
um objeto, na verdade, essa variável não guarda o objeto, e sim uma maneira de acessá-lo, chamada de referência.
• É por esse motivo que, diferente dos tipos primitivos como int e long, precisamos dar new depois de declarada a variável:
1. public static void main(String args[]) {2. Conta minhaConta = new Conta();3. Conta meuSonho = new Conta();4. }
24/04/15 Introução a Java 107
OO – Conceitos Básicos
Conta minhaConta = new Conta();
Conta meuSonho = new Conta();
Conta
Conta
minhaConta
meuSonho
Memória
OO – Conceitos Básicos
24/04/15 Introução a Java 108
24/04/15 Introução a Java 109
OO – Conceitos Básicos
• E se quisermos ter um método que transfira dinheiro entre duas contas?
24/04/15 Introução a Java 110
OO – Conceitos Básicos• Definição do método transferir em Java:
1. class Conta {2. // atributos e metodos...
3. boolean transferir(Conta contaDestino, double quantia) {4. if(quantia > this.saldo) {5. return false;6. } else { 7. this.saldo = this.saldo – valor;8. contaDestino.saldo = contaDestino.saldo + valor;9. return true;
10. }11. }12.}
24/04/15 Introução a Java 111
OO – Conceitos Básicos• Definição do método transferir em Java:
1. class Conta {2. // atributos e metodos...
3. boolean transferir(Conta contaDestino, double quantia) {4. if(sacar(quantia)) {5. contaDestino.depositar(quantia);6. return true;
7. }8. return false;
9. }10.}
24/04/15 Introução a Java 112
OO – Conceitos Básicos• Quando passamos uma Conta como
argumento, o que será que acontece na memória? O objeto é clonado?
• No java, a passagem de parâmetro funciona como uma simples atribuição como no uso do “=”. Então esse parâmetro vai copiar o valor da variável do tipo Conta que for passado como argumento. E qual é o valor de uma variável dessas? Seu valor é um endereço, uma referência, nunca um objeto. Por isso não há cópia de objetos aqui.
24/04/15 Introução a Java 113
OO – Conceitos Básicos• Quando usamos a palavra chave new, estamos construindo um
objeto. Sempre quando o new é chamado, executa o
construtor da classe. O construtor da classe é um bloco declarado com o mesmo nome que a classe:
class Conta {int numero;String dono;double saldo;double limite;
// ConstrutorConta() {
System.out.println("Construindo uma conta.");}
}
24/04/15 Introução a Java 114
OO – Conceitos Básicos• Então, quando fizermos a chamada abaixo, a
mensagem “construindo uma conta” aparecerá:
Conta c = new Conta();
• Um construtor é como uma rotina de inicialização que é chamada SEMPRE que um novo objeto é criado. Um construtor pode parecer mas não é um método.
24/04/15 Introução a Java 115
OO – Conceitos Básicos• Até agora, as nossas classes não possuíam
nenhum construtor. Então como é que era possível dar new, se todo new chama um construtor obrigatoriamente?
• Quando não declaramos nenhum construtor na classe, o Java automaticamente cria um, o construtor default. Ele não recebe nenhum argumento e o corpo dele é vazio.
• A partir do momento que declaramos um construtor, o construtor default não é mais fornecido.
24/04/15 Introução a Java 116
OO – Conceitos Básicos• Um construtor só pode rodar durante a construção do objeto, isto é,
nunca conseguiremos chamar o construtor em um objeto já construído. Porém, durante a construção de um objeto, podemos fazer com que um construtor chame outro:
class Conta {// Atributos e métodos
// ConstrutoresConta(String nome) {
this.nome = nome;}
Conta(String nome, int numero) {this(nome);this.numero = numero;
}}
24/04/15 Introução a Java 117
OO – Herança, Reescrita e Polimorfismo
• Como toda empresa, nosso Banco possui funcionários. Vamos modelar a classe Funcionario:
class Funcionario {String nome;String cpf;double salario;
// Contrutores e Métodos}
24/04/15 Introução a Java 118
OO – Herança, Reescrita e Polimorfismo
• Além de um funcionário comum, há também outros cargos, como os gerentes. Os gerentes guardam a mesma informação que um funcionário comum, mas possuem outras informações, além de ter funcionalidades um pouco diferentes. Um gerente no nosso banco possui também uma senha numérica que permite o acesso ao sistema interno do banco
24/04/15 Introução a Java 119
OO – Herança, Reescrita e Polimorfismo1. class Gerente {2. String nome;3. String cpf;4. double salario;
5. int senha;6. public boolean autentica (int senha) {7. if (this.senha == senha) {8. System.out.println("Acesso Permitido!");9. return true;10. } else {11. System.out.println("Acesso Negado!");12. return false;13. }14. }15. // Construtores e Métodos16. }
24/04/15 Introução a Java 120
OO – Herança, Reescrita e Polimorfismo
• É realmente necessário outra classe?
• Existe uma maneira de relacionarmos uma classe de tal maneira que uma delas herda tudo que a outra tem. Isto é uma relação de classe mãe e classe filha.
• No nosso caso, gostaríamos de fazer com que o Gerente tivesse tudo que um Funcionario tem, gostaríamos que ela fosse uma extensão de Funcionario. Fazemos isto através da palavra chave extends.
24/04/15 Introução a Java 121
OO – Herança, Reescrita e Polimorfismo
class Gerente extends Funcionario {int senha;public boolean autentica(int senha) {
if(this.senha == senha) {System.out.println("Acesso Permitido!");return true;
} else {System.out.println("Acesso Negado!");return false;
}}
}
24/04/15 Introução a Java 122
OO – Herança, Reescrita e Polimorfismo
• Todo momento que criarmos um objeto do tipo Gerente, este objeto possuirá também os atributos definidos na classe Funcionario pois agora um Gerente é um (is a) Funcionario:
24/04/15 Introução a Java 123
OO – Herança, Reescrita e Polimorfismoclass TestaGerente {
public static void main(String[] args) {Gerente gerente = new Gerente();gerente.nome = "João da Silva";gerente.senha = 4231;
}}
• Dizemos que a classe Gerente herda todos os atributos e métodos da classe mãe, no nosso caso, a Funcionario.
24/04/15 Introução a Java 124
Aula 3
• Agenda– Introdução a Orientação a Objetos (UML)
(Cont)• Encapsulamento
– Modificadores de acesso em classes, atributos e métodos
• Polimorfismo– Overload ( sobre carga )– Override ( reescrita )
24/04/15 Introução a Java 125
OO – Modificadores de Acesso
• Modificadores de nível de acesso determinam se outras classes podem usar um campo ou invocar método em particular.
• Há 3 níveis de controle de acesso:–Top Level: public ou package-private (sem
modificador)–Member Level: public, private, protected
ou npackage-p r i v a t e
24/04/15 Introução a Java 126
OO – Modificadores de Acesso• Uma classe pode ser declarada com o modificador
public, no caso em que esta classe é visível a qualquer outra classe.
• Se uma classe não tem modificador (o default, também conhecido como package-private), esta é visível somente dentro de seu próprio pacote.
• No nível de membro de classe ou Member Level, também podemos usar o modificador public ou sem modficador mas somente com classes do tipo Top Level, e com o mesmo comportamento.
24/04/15 Introução a Java 127
OO – Modificadores de Acesso• Para membros, há dois modificadores de acesso
adicionais:– private– protected
• O modificador private especifica que um membro de classe pode ser acessível SOMENTE por sua própria classe.
• O modificador protected especifica que um membro de classe pode ser acessado somente DENTRO de seu próprio pacote (como package-private) e, por uma subclasse dessa clase em outro pacote
24/04/15 Introução a Java 128
OO – Modificadores de Acesso
• A tabela abaixo mostra o acesso a membros permitido por cada modificador:
Níveis de Acesso
Modificador Classe Pacote Subclasse Público
public S S S S
protected S S S N
package-private S S N N
private S N N N
24/04/15 Introução a Java 129
OO – Modificadores de Acesso• Níveis de acesso nos afeta em duas maneiras:
1.Quando nós usamos classes de outra fonte, como classes da própria tecnologia Java, níveis de acesso determinam quais membros dessas classes nossas classes podem usar.
2.Quando nós escrevemos uma classe, nós precisamos decidir qual nível de acesso toda variável ou método deverá ter.
• A seguir vamos ver uma coleção de classes e como níveis de acesso afetam a visibilidade
24/04/15 Introução a Java 130
OO – Modificadores de Acesso• Dicas ao escolher um modificador de acesso:
• Se outros programadores forem usar nossas classes, nós temos que nos assegurar que erros de uso incorreto aconteçam. Níveis de acesso nos podem ajudar a:– Usar o mais restritivo nível de acesso que faz
sentido para um membro em particular. Não usar private somente se houver uma boa razão para isso.
– Evitar campos públicos exceto para constantes. Campos públicos induzem o desenvolvedor a uma implementação particular e a limitar a flexibilidade de mudanças no código.
24/04/15 Introução a Java 131
24/04/15 Introução a Java 132
OO - Herança, Reescrita e Polimorfismo• Reescrita
Todo fim de ano, os funcionários do nosso banco recebem uma bonificação. Os funcionários comuns recebem 10% do valor do salário e os gerentes, 15%.
Da mesma maneira podemos ter uma classe Diretor que estenda Gerente, e a classe Presidente pode estender diretamente de Funcionario.
Que fique claro que essa é uma decisão de negócio. Se você vai estender Diretor de Gerente ou não, vai depender se Diretor “é um” Gerente. Uma classe pode ter várias filhas, e as filhas só podem ter apenas uma mãe, é a chamada herança simples do java, ou seja, o java não permite herança multipla.
24/04/15 Introução a Java 133
OO - Herança, Reescrita e Polimorfismo
24/04/15 Introução a Java 134
OO - Herança, Reescrita e Polimorfismo• Todo fim de ano, os funcionários do nosso banco recebem uma bonificação. Os
funcionários comuns recebem 10% do valor do salário e os gerentes, 15%. Vamos ver como fica a classe Funcionario:
1. public class Funcionario {2. private String nome;3. private String cpf;4. private double salario;5. 6. public double getBonificacao() {7. return this.salario * 0.10;8. }9. // métodos
10.}
24/04/15 Introução a Java 135
OO - Herança, Reescrita e Polimorfismo• Se deixarmos a classe Gerente como ela está, ela vai herdar
o método getBonificacao.1. Gerente gerente = new Gerente();
2. gerente.setSalario(5000.0);
3. System.out.println(gerente.getBonificacao());
• O resultado aqui será 500. Não queremos essa resposta, não queremos este método que foi escrito na classe mãe, eu quero reescrever (sobrescrever, override) este método:
24/04/15 Introução a Java 136
OO - Herança, Reescrita e Polimorfismo1. public class Gerente extends Funcionario {
2. private int senha;
3. public double getBonificacao() {
4. return this.salario * 0.15;
5. }
6. // ...
7. }
• Agora sim o método está correto para o Gerente. Refaça o teste e veja que, agora, o valor impresso é o correto (750):
1. Gerente gerente = new Gerente();
2. gerente.setSalario(5000.0);
3. System.out.println(gerente.getBonificacao());
24/04/15 Introução a Java 137
OO - Herança, Reescrita e Polimorfismo
• Chamando o método reescrito– Depois de reescrito, não podemos mais chamar o método
antigo, porém podemos fazer isso de dentro da classe.– Imagine que para calcular a bonificação de um Gerente,
devemos fazer igual ao cálculo de um Funcionario porem adicionando R$ 1000. Poderíamos fazer assim:
1. public class Gerente extends Funcionario {2. private int senha;3. public double getBonificacao() {4. return this.salario * 0.10 + 1000;5. }6. // ...7. }
24/04/15 Introução a Java 138
OO - Herança, Reescrita e Polimorfismo• Aqui teríamos um problema: o dia que o getBonificacao do
Funcionario mudar, precisaremos mudar o método do Gerente também para acompanhar a nova bonificação. Para evitar isso, o getBonificacao do Gerente pode chamar o do Funcionario utilizando-se da palavra chave super.
1. public class Gerente extends Funcionario {
2. private int senha;
3. public double getBonificacao() {
4. return super.getBonificacao() + 1000;
5. }
6. // ...
7. }
24/04/15 Introução a Java 139
OO - Herança, Reescrita e Polimorfismo
• Essa invocação vai procurar o método com o nome getBonificacao de uma super classe de Gerente estende. No caso ele vai logo encontrar esse método em Funcionario.
• Em muitos casos isso ocorre, pois o método reescrito geralmente faz “algo a mais” que o método da classe mãe. Chamar ou não o método de cima é uma decisão sua, e depende do seu problema.
24/04/15 Introução a Java 140
OO - Herança, Reescrita e Polimorfismo• O que guarda uma variável do tipo Funcionario?
Uma referência para um Funcionario. • Na herança, vimos que Gerente é um Funcionario,
pois é uma extensão deste. Eu posso me referenciar a um Gerente como sendo um Funcionario. Se alguém precisa falar com um Funcionario do banco, pode falar com um Gerente! Por que? Pois Gerente é um Funcionario. Essa é a semântica da herança.
1. Gerente gerente = new Gerente();
2. Funcionario funcionario = gerente;
3. funcionario.setSalario(5000.0);
24/04/15 Introução a Java 141
OO - Herança, Reescrita e Polimorfismo
• Polimorfismo é a capacidade de um objeto poder ser referenciado de várias formas.(cuidado, polimorfismo não quer dizer que o objeto fica se transformando, muito pelo contrário, um objeto nasce de um tipo e morre daquele tipo, o que muda é a maneira como nos referenciamos a ele). Até aqui tudo bem, mas e se eu tentar: funcionario.getBonificacao();
• Qual é o retorno desse método? 500 ou 750? No Java, a chamada de método sempre vai ser decidida em tempo de execução. O Java vai procurar o objeto na memória e ai sim decidir qual método deve ser chamado, sempre relacionando com sua classe de verdade, e não a que estamos usando para referencia-lo. Apesar de estarmos nos referenciando a esse Gerente como sendo um Funcionario, o método executado é o do Gerente. O retorno é 750.
• Parece estranho criar um gerente e referenciá-lo como apenas um funcionário. Porque faria isso? Na verdade, a situação que costuma aparecer é a que temos um método que recebe um argumento do tipo Funcionario:
24/04/15 Introução a Java 142
OO - Herança, Reescrita e Polimorfismo1. public class ControleDeBonificacoes {2. private double totalDeBonificacoes = 0;3. public void registra(Funcionario funcionario) {4. this.totalDeBonificacoes +=5. funcionario.getBonificacao();6. }7. public double getTotalDeBonificacoes() {8. return this.totalDeBonificacoes;9. }10. }
• E, em algum lugar da minha aplicação (ou no main se for apenas para testes):
24/04/15 Introução a Java 143
OO – Herança, Reescrita e Polimorfismo• E, em algum lugar da minha aplicação (ou
no main se for apenas para testes):
1. ControleDeBonificacoes controle = new ControleDeBonificacoes();
2. Gerente funcionario1 = new Gerente();3. funcionario1.setSalario(5000.0);4. controle.registra(funcionario1);5. Funcionario funcionario2 = new Funcionario();6. funcionario2.setSalario(1000.0);7. controle.registra(funcionario2);8. System.out.println(9. controle.getTotalDeBonificacoes() );
24/04/15 Introução a Java 144
OO – Herança, Reescrita e Polimorfismo• Repare que conseguimos passar um Gerente para um método que recebe um
Funcionario como argumento. Pense como numa porta na agência bancária com o seguinte aviso: “Permitida a entrada apenas de Funcionários”. Um gerente pode passar nessa porta? Sim, pois Gerente é um Funcionario.
• Qual será o valor resultante? Não importa que dentro do método registra, do ControleDeBonificacoes receba Funcionario, quando ele receber um objeto que realmente é um Gerente, o seu método reescrito será invocado. Reafirmando: não importa como nos referenciamos a um objeto, o método que será invocado é sempre o que é dele.
• O dia que criarmos uma classe Secretaria, por exemplo, que é filha de Funcionario, precisaremos mudar a classe de ControleDeBonificacoes? Não. Basta a classe Secretaria reescrever os métodos que lhe parecer necessário. É exatamente esse o poder do polimorfismo juntamente com a herança e reescrita de método: diminuir acoplamento entre as classes, para que evitar que novos códigos resultem em modificações em inúmeros lugares.
• Repare que quem criou ControleDeBonificacoes pode nunca ter imaginado a criação da classe Secretaria ou Engenheiro. Isto proporciona um reaproveitamento enorme de código.
24/04/15 Introução a Java 145
OO – Herança, Reescrita e Polimorfismo
• Outro Exemplo :– Imagine que vamos modelar um sistema para a faculdade, que
controle as despesas com funcionários e professores. Nosso funcionário fica assim:
1. public class EmpregadoDaFaculdade {2. private String nome;3. private double salario;4. public double getGastos() {
return this.salario;1. }2. public String getInfo() {3. return “nome: ” + this.nome + “ com salário ” + this.salario;4. } 5. // métodos de get, set e outros6. }
• O gasto que temos com o professor não é apenas seu salário. Temos de somar um bônus de 10 reais por hora/aula. O que fazemos então? Reescrevemos o método. Assim como o getGastos é diferente, o getInfo também será, pois temos de mostrar as horas aula também.
24/04/15 Introução a Java 146
OO – Herança, Reescrita e Polimorfismo1. public class ProfessorDaFaculdade extends EmpregadoDaFaculdade {2. private int horasDeAula;3. public double getGastos() {4. return this.getSalario() + this.horasDeAula * 10;5. }6. public String getInfo() {7. String informacaoBasica = super.getInfo();8. String informacao = informacaoBasica + “ horas de aula: ” +9. this.horasDeAula;10. return informacao;11. }12. }
• Imagine que temos uma classe de relatório
1. public class GeradorDeRelatorio {2. public void adiciona(EmpregadoDaFaculdade f) {3. System. out.println(f.getInfo());4. System. out.println(f.getGastos());5. }6. }
24/04/15 Introução a Java 147
OO – Herança, Reescrita e Polimorfismo
• A novidade aqui é a palavra chave super. Apesar do método ter sido reescrito, gostaríamos de acessar o método da classe mãe, para não ter de copiar e colocar o conteúdo desse método e depois concatenar com a informação das horas de aula.
• Podemos passar para nossa classe qualquer EmpregadoDaFaculdade! Vai funcionar tanto para professor, quanto para funcionário comum.
• Um certo dia, muito depois de terminar essa classe de relatório, resolvemos aumentar nosso sistema, e colocar uma classe nova, que representa o Reitor. Como ele também é um EmpregadoDaFaculdade, será que vamos precisar alterar alguma coisa na nossa classe de Relatorio ? Não. essa é a idéia. Quem programou a classe GeradorDeRelatorio nunca imaginou que existiria uma classe Reitor, e mesmo assim o sistema funciona.
24/04/15 Introução a Java 148
OO – Herança, Reescrita e Polimorfismo1. public class Reitor extends ProfessorDaFaculdade {
2. // informações extras
3. public String getInfo() {
4. return super.getInfo() +
5. “ e ele é um reitor”;
6. }
7. // não sobreescrevemos o getGastos!!!
8. }
24/04/15 Introução a Java 149
OO – Herança, Reescrita e Polimorfismo1. Se não houvesse herança em Java, como você
poderia reaproveitar o código de outra classe?
2. Uma discussão muito atual é sobre o abuso no uso da herança. Algumas pessoas usam herança apenas para reaproveitar o código, quando poderia ter feito uma composição. Procure sobre herança versus composição.
3. Mesmo depois de reescrever um método da classe mãe, a classe filha ainda pode acessar o método antigo. Isto é feito através da palavra chave super.método(). Algo parecido ocorre entre os construtores das classes, o que?
24/04/15 Introução a Java 150
OO – Herança, Reescrita e Polimorfismo
Exercícios• Adicionar os seguintes métodos na classe Conta :
1. public void deposita (double valor) {2. this.saldo += valor; 3. }
4. public double getSaldo () {5. return this.saldo;6. }
7. /**8. * Atualiza o saldo baseado em um taxa9. * @param taxa double10. */11. public void atualiza (double taxa) {12. this.saldo += this.saldo * taxa;13. }
24/04/15 Introução a Java 151
OO – Herança, Reescrita e Polimorfismo
1. Crie duas subclasses da classe Conta, ou seja classes filhas de Conta.• ContaCorrente e ContaPoupanca.
Elas deverão sobrescrever o método atualiza, sendo que a classe ContaCorrente deverá utilizar o dobro da taxa da classe Conta, e a Classe ContaPoupanca deverá utilizar o triplo da taxa da Classe Conta.
Além disso, a ContaCorrente deverá sobrecrever o método deposita, afim de retirar a CPMF de 0.38% a cada depósito.
Então teremos :
• public class ContaCorrente extends Conta {• // Metodos • }
• public class ContaPoupanca extends Conta {• // Metodos• }
24/04/15 Introução a Java 152
OO – Herança, Reescrita e Polimorfismo
1. public class ContaCorrente extends Conta {2. // outros Metodos3. /**4. * Atualiza o saldo com o dobro da taxa classe conta 5. * @param taxa double6. */7. public void atualiza (double taxa) { 8. this.saldo += this.saldo * taxa * 2;9. }10. }
1. public class ContaPoupanca extends Conta {2. // outros Metodos 3. /**4. * Atualiza o saldo com o triplo da taxa classe conta 5. * @param taxa double6. */7. public void atualiza(double taxa) {8. this.saldo += this.saldo * taxa * 3;9. }10. }
24/04/15 Introução a Java 153
OO – Herança, Reescrita e Polimorfismo• Na classe ContaCorrente, reescreva o método deposita para
descontar a cpmf:
1. public class ContaCorrente extends Conta {
2. /**
3. * Atualiza o saldo com o dobro da taxa classe conta
4. * @param taxa double
5. */
6. public void atualiza (double taxa) {
7. this.saldo += this.saldo * taxa * 2;
8. }
9. public void deposita(double valor) {
10. this.saldo += valor * 0.9962;
11. }
12. }
24/04/15 Introução a Java 154
OO – Herança, Reescrita e Polimorfismo
• Crie uma classe com método main e instancie essas classes, atualize-as e veja o resultado. Algo como:
1. public class TestaContas {2. public static void main(String[] args) {3. Conta c = new Conta();4. ContaCorrente cc = new ContaCorrente();5. ContaPoupanca cp = new ContaPoupanca();6. c.deposita(1000);7. cc.deposita(1000);8. cp.deposita(1000);9. c.atualiza(0.01);10. cc.atualiza(0.01);11. cp.atualiza(0.01);12. System. out.println(c.getSaldo());13. System. out.println(cc.getSaldo());14. System. out.println(cp.getSaldo());15. } 16. }
24/04/15 Introução a Java 155
OO – Herança, Reescrita e Polimorfismo
• Após imprimir o saldo (getSaldo()) de cada uma das contas, o que acontece?
• O que você acha de rodar o código anterior da seguinte maneira:
1. Conta c = new Conta();2. Conta cc = new ContaCorrente();3. Conta cp = new ContaPoupanca();
• Compila? Roda? O que muda? Qual é a utilidade disso? Realmente essa não é a maneira mais útil do polimorfismo, veremos o seu real poder no próximo exercício. Porém existe uma utilidade de declararmos uma variável de um tipo menos específico que o objeto realmente é.
• É extremamente importante perceber que não importa como nos referimos a um objeto, o método que será invocado é sempre o mesmo! A JVM vai descobrir em tempo de execução qual deve ser invocado, dependendo de que tipo aquele objeto é, e não de acordo como nos referimos a ele.
24/04/15 Introução a Java 156
[ Aula 4 ]
• Orientação a Objetos ( cont. )–Classe Abstrata– Interface–Revisão de Passagem de parametros
• Valor ( tipos primitivos )• Referência ( objetos )
– Modificadores de acesso• final• static
24/04/15 Introução a Java 157
OO – Classe Abstrata• Vamos retornar a nossa classe Funcionario:1. public class Funcionario {
2. private String nome;
3. private String cpf;
4. private double salario;
5. public double getBonificacao() {
6. return this.salario * 1.2;
7. }
8. // outros métodos aqui
9. }
• Considere agora o nosso ControleDeBonificacao:
24/04/15 Introução a Java 158
OO – Classe Abstrata• Vamos retornar a nossa classe Funcionario:1. public class Funcionario {
2. private String nome;
3. private String cpf;
4. private double salario;
5. public double getBonificacao() {
6. return this.salario * 1.2;
7. }
8. // outros métodos aqui
9. }
• Considere agora o nosso ControleDeBonificacao:
24/04/15 Introução a Java 159
OO – Classe Abstrata1. public class ControleDeBonificacoes {2. private double totalDeBonificacoes = 0;3. public void registra(Funcionario f) {4. System.out.println("Adicionando bonificacao do
funcionario: " + f);5. this.totalDeBonificacoes += funcionario.getBonificacao();6. }7. public double getTotalDeBonificacoes() {8. return this.totalDeBonificacoes;9. }10. }
• Nosso método registra recebe qualquer referencia do tipo Funcionario, isto é, pode ser objetos do tipo Funcionario e qualquer de seus subtipos: Gerente, Diretor e eventualmente alguma nova subclasse que venha ser escrita, sem prévio conhecimento do autor da ControleDeBonificacao.
24/04/15 Introução a Java 160
OO – Classe Abstrata
• Estamos utilizando aqui a classe Funcionario para o polimorfismo: se não fosse ela teríamos um grande prejuízo: precisaríamos criar um método bonifica para receber cada um dos tipos de Funcionario, um para Gerente, um para Diretor, etc. Repare que perder esse poder é muito pior que a pequena vantagem que a herança traz em herdar código.
• Porém, em alguns sistemas, como é o nosso caso, usamos uma classe apenas com esses intuitos: de economizar um pouco código e ganhar polimorfismo para criar métodos mais genéricos e que se encaixem a diversos objetos.
• Faz sentido ter um objeto do tipo Funcionario? Essa pergunta é diferente de saber se faz sentido ter uma referência do tipo Funcionario: esse caso faz sim e é muito útil.
• Referenciando Funcionario temos o polimorfismo de referência, já que podemos receber qualquer coisa que seja um Funcionario. Porém, dar new em Funcionario pode não fazer sentido, isso é, não queremos receber um objeto do tipo Funcionario, queremos que aquela referência seja ou um Gerente, ou um Diretor, etc.
• Algo mais concreto que um Funcionario.
24/04/15 Introução a Java 161
OO – Classe Abstrata
1. ControleDeBonificacoes cdb = new ControleDeBonificacoes();2. Funcionario f = new Funcionario();3. cdb.adiciona(f); // faz sentido?
• Um outro caso em que não faz sentido ter um objeto daquele tipo, apesar da classe existir: imagine a classe Pessoa e duas filhas, PessoaFisica e PessoaJuridica. Quando puxamos um relatório de nossos clientes (uma array de Pessoa por exemplo), queremos que cada um deles seja ou uma PessoaFisica, ou uma PessoaJuridica. A classe Pessoa nesse caso estaria sendo usada apenas para ganhar o polimorfismo e herdar algumas coisas: não faz sentido permitir instanciá-la.
• Para resolver esses problemas temos as classes abstratas.
24/04/15 Introução a Java 162
OO – Classe Abstrata• O que exatamente vem a ser a nossa classe
Funcionario? Nossa empresa tem apenas Diretores, Gerentes, Secretarias, etc. Ela é uma classe que apenas idealiza um tipo, define apenas um rascunho.
• Para o nosso sistema é inadmissível um objeto ser apenas do tipo Funcionario (pode existir um sistema em que faça sentido ter objetos do tipo Funcionario ou apenas Pessoa, mas, no nosso caso, não).
• Usamos a palavra chave abstract para impedir que ela possa ser instanciada. Esse é o efeito diretor de se usar o modificador abstract na declaração de uma classe:
24/04/15 Introução a Java 163
OO – Classe Abstrata1. public abstract class Funcionario {2. private double salario;3. public double getBonificacao() {4. return this.salario * 1.2;5. }6. // outros atributos e métodos comuns a todos 7. // Funcionarios8. }
• E no meio de um código:
1. Funcionario f = new Funcionario() // não compila!!!
• Qual Exception é Gerada ??? Vamos ver ...
24/04/15 Introução a Java 164
Polimorfismo
Gerente
Funcionario
Funcionario fun = new Gerente();
Autenticavel auth = new Gerente();
Autenticavel
24/04/15 Introução a Java 165
OO – Classe Abstrata
• O código acima não compila. O problema é instanciar a classe, criar referência você pode (e deve, pois é útil). Se ela não pode ser instanciada, para que serve? Somente para o polimorfismo e herança dos atributos e métodos.
• Vamos então herdar dessa classe, reescrevendo o método getBonificacao:
1. public class Gerente extends Funcionario {
2. public String getBonificacao() {
3. return this.salario * 1.4 + 1000;
4. }
5. }
24/04/15 Introução a Java 166
OO – Classe Abstrata• Mas qual é a real vantagem de uma classe
abstrata? Poderíamos ter feito isto com uma herança comum. Por enquanto, a única diferença é que não podemos instanciar um objeto do tipo Funcionario, que já é de grande valia, dando mais consistência ao sistema.
• Que fique claro que a nossa decisão de transformar Funcionario em uma classe abstrata dependeu do nosso negócio. Pode ser que em um sistema com classes similares uma classe análoga a Funcionario faça sentido ser concreta.
24/04/15 Introução a Java 167
OO – Classe Abstrata [Métodos Abstratos]
• Se não tivéssemos reescrito o método getBonificacao, esse método seria herdado da classe mãe, fazendo com que ele devolvesse o salário mais 20%. Cada funcionário em nosso sistema tem uma regra totalmente diferente para ser bonificado.
• Será então que faz algum sentido ter esse método na classe Funcionario? Será que existe uma bonificação padrão para todo tipo de Funcionario? Parece que não, cada classe filha terá um método diferente de bonificação pois de acordo com nosso sistema não existe uma regra geral: queremos que cada pessoa que escreve a classe de um Funcionario diferente (subclasses de Funcionario) reescreva o método getBonificacao de acordo com as suas regras.
• Poderíamos então jogar fora esse método da classe Funcionario? O problema é que se ele não existisse, não poderíamos chamar o método apenas com uma referência a um Funcionario, pois ninguém garante que essa referência aponta para um objeto que possui esse método.
• Existe um recurso em Java que, em uma classe abstrata, podemos escrever que determinado método será sempre escrito pelas classes filhas. Isto é, um método abstrato.
• Ele indica que todas as classes filhas (concretas, isso é, que não forem abstratas) devem reescrever esse método, ou não compilarão. É como se você herdasse a responsabilidade de ter aquele método.
24/04/15 Introução a Java 168
OO – Classe Abstrata [Métodos Abstratos]
• Como declarar um método abstrato–Às vezes não fica claro como declarar um
método abstrato.–Basta escrever a palavra chave abstract
na assinatura do mesmo e colocar um ponto e vírgula em vez de abre e fecha chaves!
24/04/15 Introução a Java 169
OO – Classe Abstrata [Métodos Abstratos]
1. public abstract class Funcionario {2. public abstract double getBonificacao();3. // outros atributos e métodos4. }
• Repare que não colocamos o corpo do método, e usamos a palavra chave abstract para definir o mesmo. Porque não colocar corpo algum? Porque esse método nunca vai ser chamado, sempre quando alguém chamar o método getBonificacao, vai cair em uma das suas filhas, que realmente escreveram o método.
• Qualquer classe que estender a classe Funcionario será obrigada a reescrever este método, tornando-o “concreto”.
• Se não reescreverem esse método, um erro de compilação ocorrerá.
24/04/15 Introução a Java 170
OO – Classe Abstrata [Métodos Abstratos]
• O método do ControleDeBonificacao estava assim:
1. public void registra(Funcionario f) {2. System.out.println("Adicionando bonificacao do funcionario:
" + f);3. this.totalDeBonificacoes += funcionario.getBonificacao();4. }
• Como posso acessar o método getBonificacao se ele não existe na classe Funcionario?
• Já que o método é abstrato, com certeza suas subclasses têm esse método, o que garante que essa invocação de método não vai falhar. Basta pensar que uma referência do tipo Funcionario nunca aponta para um objeto que não tem o método getBonificacao, pois não é possível instanciar uma classe abstrata, apenas as concretas. Um método abstrato obriga a classe em que ele se encontra ser abstrata, o que garante a coerência do código acima compilar.
24/04/15 Introução a Java 171
OO – Classe Abstrata [Métodos Abstratos]
• Um outro Exemplo :–Nosso banco deseja todo dia de manhã
atualizar as contas bancárias de todas as pessoas. Temos dois tipos de conta, a ContaCorrente e a ContaPoupanca. A ContaPoupanca atualiza todo dia uma pequena porcentagem, já a ContaCorrente só precisa utilizar fator de correção mensal.
24/04/15 Introução a Java 172
OO – Classe Abstrata [Métodos Abstratos]
1. public class ContaCorrente extends Conta {2. private double limiteDoChequeEspecial = 1000.0;3. private double gastosNoChequeEspecial = 100.0;4. public void atualiza() {5. super.retira(this.gastosNoChequeEspecial *
0.08);6. }7. }
1. public class ContaPoupanca extends Conta {2. double correcaoMensal;3. public void atualiza() {4. super.deposita(this.saldo *
this.correcaoMensal);5. }6. }
24/04/15 Introução a Java 173
OO – Classe Abstrata [Métodos Abstratos]
• O que não está legal aqui? Por enquanto usamos herança para herdar um pouco de código, e assim não ter de reescrevê-lo.
• Mas já frisamos que essa não é a grande vantagem de se usar herança, a idéia é utilizar o polimorfismo adquirido. Podemos nos referenciar a uma ContaCorrente e ContaPoupanca como sendo uma Conta:
24/04/15 Introução a Java 174
OO – Classe Abstrata [Métodos Abstratos]1. public class AtualizadorDeSaldos {2. Conta[] contas;3. public void setContas(Conta[] contas) {4. this.contas = contas;5. }6. public void atualizaSaldos() {7. for (Conta conta : this.contas) {8. conta.atualiza(); // nao compila!!!9. }10. } 11. }
• Este código acima não compila! Se tenho uma referência para uma Conta, quem garante que o objeto referenciado tem o método atualiza? Ninguém. Podemos então colocá-lo na classe Conta:
24/04/15 Introução a Java 175
OO – Classe Abstrata [Métodos Abstratos]1.public class Conta {2. double saldo;3. public void retira(double valor) {4. this.saldo -= valor;5. }6. public void deposita(double valor) {7. this.saldo += valor;8. } 9. public double getSaldo() {10. return this.saldo();11. }12. public void atualiza() {13. // não faz nada, serve só para o polimorfismo14. }15.}
24/04/15 Introução a Java 176
OO – Classe Abstrata [Métodos Abstratos]
• O que ainda não está legal? Cada tipo de Conta, isto é, cada subclasse de Conta sabe como se atualizar. Só que quando herdamos de Conta nós já herdamos o método atualiza, o que não nos obriga a reescrevê-lo.
• Além disso, no nosso sistema, não faz sentido existir um objeto que é realmente da classe Conta, essa classe é só um conceito, uma idéia, ela é abstrata! Assim como seu método atualiza, o qual queremos forçar que as subclasse reescrevam.
24/04/15 Introução a Java 177
OO – Classe Abstrata [Métodos Abstratos]
1. public class Conta {2. double saldo;3. public void retira(double valor) {4. this.saldo -= valor;5. }6. public void deposita(double valor) {7. this.saldo += valor;8. } 9. public double getSaldo() {10. return this.saldo();11. }12. public abstract void atualiza();13. }
24/04/15 Introução a Java 178
OO – Classe Abstrata [Métodos Abstratos]• Podemos então testar esses conceitos criando 2 Contas (uma de
cada tipo) e chamando o método atualiza de cada uma delas:
1. public class TesteClassesAbstratas {2. public static void main (String args[]) {3. //criamos as contas4. Conta[] contas = new Conta[2];5. contas[0] = new ContaPoupanca();6. contas[1] = new ContaCorrente();7. //iteramos e chamamos atualiza8. for (Conta conta : contas) {9. conta.atualiza(0.01);10. }11. }12. }
24/04/15 Introução a Java 179
OO – Classe Abstrata [Métodos Abstratos]
• Para saber mais... –Uma classe que estende uma classe
normal também pode ser abstrata! Ela não poderá ser instanciada, mas sua classe pai sim!
–Uma classe abstrata não precisa necessariamente ter um método abstrato.
24/04/15 Introução a Java 180
OO – Classe Abstrata [Métodos Abstratos]
• Exercícios:– Repare que a nossa classe Conta é uma excelente candidata
para uma classe abstrata. Porque? Que métodos seriam interessantes candidatos a serem abstratos?
– Transforme a classe Conta para abstrata, no main tente dar um new nela e compile o código.
– Se agora não podemos dar new em Conta, qual é a utilidade de ter um método que recebe uma referência a Conta como argumento? Aliás, posso ter isso?
– Remova o método atualiza() da ContaPoupanca, dessa forma ele herdará o método diretamente de Conta. Transforme o método atualiza() da classe Conta para abstrato.
– Compile o código. Qual é o problema com a classe ContaPoupanca?
– Reescreva o método atualiza() na classe ContaPoupanca para que a classe possa compilar normalmente.
24/04/15 Introução a Java 181
OO – Interface
• Imagine que um Sistema de Controle do Banco pode ser acessado, além dos Gerentes, pelos Diretores do Banco. Então, teríamos uma classe Diretor:
1. public class Diretor extends Funcionario {2. public boolean autentica(int senha) {3. // verifica aqui se a senha confere com a recebida 4. //como parametro5. }6. }
• E a classe Gerente:
1. public class Gerente extends Funcionario {2. public boolean autentica(int senha) {3. // verifica aqui se a senha confere com a 4. // recebida como parametro no caso do gerente5. // verifica tambem se o departamento dele tem acesso6. }7. }
24/04/15 Introução a Java 182
OO – Interface
• Repare que o método de autenticação de cada tipo de Funcionario pode variar muito.
• Mas vamos aos problemas. Considere o SistemaInterno, e seu controle, precisamos receber um Diretor ou Gerente como argumento, verificar se ele se autentica e colocá-lo dentro do sistema:
1. public class SistemaInterno {2. public void login(Funcionario funcionario) {3. // chamar o método autentica? não da! 4. // Nem todo Funcionario tem5. }6. }
24/04/15 Introução a Java 183
OO – Interface• O SistemaInterno aceita qualquer tipo de Funcionario, tendo
ele acesso ao sistema ou não, mas note que nem todo Funcionario possui o método autentica. Isso nos impede de chamar esse método com uma referência apenas a Funcionario (haveria um erro de compilação). O que fazer então?
• Uma possibilidade: criar dois métodos login no SistemaInterno: um para receber Diretor e outro para receber Gerente. Já vimos que essa não é uma boa escolha. Porque?
• Cada vez que criarmos uma nova classe de Funcionario que é autenticável, precisaríamos adicionar um novo método de login no SistemaInterno.
Em Java, métodos podem ter o mesmo nome desde que não sejam ambíguos, isso é, que exista uma maneira de distinguir no momento da chamada.Isso se chama sobrecarga de método. (overloading, não confundir com overriding, que é um conceito muito mais poderoso no caso).
24/04/15 Introução a Java 184
OO – Interface
• Uma solução mais interessante seria criar uma classe no meio da árvores de herança, FuncionarioAutenticavel:
1. public class FuncionarioAutenticavel extends Funcionario {2. public boolean autentica(int senha) {3. // faz autenticacao padrao4. }5. }
• As classes Diretor e Gerente passariam a estender de FuncionarioAutenticavel, e o SistemaInterno receberia referências desse tipo, como a seguir:
1. public class SistemaInterno {2. public void login(FuncionarioAutenticavel fa) {3. int senha = //pega senha de algum lugar4. boolean ok = fa.autentica(senha);5. // aqui eu posso chamar o autentica!6. // Pois todo FuncionarioAutenticavel tem7. }8. }
24/04/15 Introução a Java 185
OO – Interface• Diagrama de Classe
24/04/15 Introução a Java 186
OO – Interface
• Repare que FuncionarioAutenticavel é uma forte candidata a classe abstrata. Mais ainda, o método autentica poderia ser um método abstrato.
• O uso de herança resolve esse caso, mas vamos a uma outra situação:
• Precisamos que todos os clientes também tenham acesso ao SistemaInterno. O que fazer? Uma opção é criar outro método login em SistemaInterno: mas já descartamos essa anteriormente.
• Uma outra, que é comum entre os novatos, é fazer uma herança sem sentido para resolver o problema, por exemplo, fazer Cliente extends FuncionarioAutenticavel.
• Realmente resolve o problema, mas trará diversos outros. Cliente definitivamente não é FuncionarioAutenticavel. Se você fizer isso, o Cliente terá, por exemplo, um método getBonificacao, um atributo salario e outros membros que não fazem o menor sentido para esta classe! Não faça herança quando a relação não é estritamente “é um”.
24/04/15 Introução a Java 187
OO – Interface• O que precisamos para resolver nosso problema? Arranjar uma
forma referenciar Diretor, Gerente e Cliente de uma mesma maneira, isto é, achar comum.
• Se existisse uma forma na qual essas classes garantissem a existência determinado método, através de um contrato, resolveríamos o problema.
• Toda classe define 2 itens:– o que uma classe faz (as assinaturas dos métodos)– como uma classe faz essas tarefas (o corpo dos métodos e
atributos privados)
24/04/15 Introução a Java 188
OO – Interface
• Podemos criar um “contrato” que define tudo o que uma classe deve fazer se quiser ter um determinado status. Imagine:
• Contrato Autenticavel:– Quem quiser ser Autenticavel precisa saber fazer:1. autenticar dada uma senha, devolvendo um booleano
• Quem quiser pode “assinar” esse contrato, sendo assim obrigado a explicar como será feita essa autenticação. A vantagem é que, se um Gerente assinar esse contrato, podemos nos referenciar a um Gerente como um Autenticavel.
24/04/15 Introução a Java 189
OO – Interface
• Podemos criar esse contrato em Java!
1. public interface Autenticavel {2. boolean autentica(int senha);3. }
• Chama-se interface pois é a maneira a qual poderemos conversar com um Autenticavel. Interface é a maneira através conversamos com um objeto.
• Lemos a interface da seguinte maneira: “quem desejar ser autenticavel precisa saber autenticar dado um inteiro e retornando um booleano”. Realmente é um contrato, onde quem assina se responsabiliza por reescrever esses métodos (cumprir o contrato).
• Uma interface pode definir uma série de métodos, mas nunca conter implementação deles. Ela só expõe o que o objeto deve fazer, e não como ele faz, nem o que ele tem. Como ele faz vai ser definido em uma implementação dessa interface.
24/04/15 Introução a Java 190
OO – Interface
• E o Gerente pode “assinar” o contrato, ou seja, implementar a interface. No momento que ele implementa essa interface, ele precisa escrever os métodos pedidos pela interface (muito próximo ao efeito de herdar métodos abstratos, aliás, métodos de uma interface são públicos e abstratos, sempre). Para implementar usamos a palavra chave implements na classe:
1. public class Gerente extends Funcionario implements Autenticavel {
2. int senha;3. // outros atributos e métodos4. public boolean autentica(int senha) {5. if(this.senha != senha)6. return false;7. // pode fazer outras possiveis verificacoes, 8. //como saber se esse departamento do gerente tem
9. //acesso ao Sistema10. return true;11. }12. }
24/04/15 Introução a Java 191
OO – Interface• O implements pode ser lido da seguinte maneira: “A classe
Gerente se compromete a ser tratada como Autenticavel, sendo obrigada a ter os métodos necessários, definidos neste contrato”.
• A partir de agora, podemos tratar um Gerente como sendo um Autenticavel. Ganhamos polimorfismo! Temos mais uma forma de referenciar a um Gerente. Quando crio uma variável do tipo Autenticavel, estou criando uma referência para qualquer objeto de uma classe que implementa Autenticavel, direta ou indiretamente:
1. Autenticavel a = new Gerente();2. //posso aqui chamar o metodo autentica!
• Novamente, o proveito mais comum aqui seria receber como argumento.
24/04/15 Introução a Java 192
OO – Interface
• Voltamos ao nosso SistemaInterno:
1. public class SistemaInterno {2. public void login(Autenticavel a) {3. int senha = //pega senha de algum lugar
4. boolean ok = fa.autentica(senha);
5. }
6. }
• Pronto! E já podemos passar qualquer Autenticavel para o SistemaInterno. Então precisamos fazer com que o Diretor também implemente essa interface.
1. public class Diretor extends Funcionario implements Autenticavel {
2. // metodos e atributos, alem de obrigatoriamente ter o autentica
3. }
24/04/15 Introução a Java 193
OO – Interface
24/04/15 Introução a Java 194
OO – Interface
• Agora podemos passar um Diretor. No dia em que tivermos mais um funcionário com acesso ao sistema, basta que ele implemente essa interface, para se encaixar no sistema.
• Qualquer Autenticavel passado para o SistemaInterno. Está bom para nós.
• Repare que pouco importa quem o objeto referenciado realmente é, pois ele tem um método autentica que é o necessário para nosso SistemaInterno funcionar corretamente. Aliás, qualquer outra classe que futuramente implemente essa interface poderá ser passada como argumento aqui. Ou se agora achamos que o Fornecedor precisa ter acesso: basta que ele implemente Autenticavel. Olhe só o tamanho do desacoplamento: quem escreveu o SistemaInterno só precisa saber que ele é Autenticavel.
24/04/15 Introução a Java 195
OO – Interface
• Não faz diferença se é um Diretor, Gerente, Cliente ou qualquer classe que venha por aí. Basta seguir o contrato! Mais ainda, cada Autenticavel pode se autenticar de uma maneira completamente diferente de outro Autenticavel!
• Lembrese: a interface define que todos vão saber se autenticar (o que ele faz) enquanto a implementação define como exatamente vai ser feito (como ele faz).
• A maneira como os objetos se comunicam num sistema orientado a objetos é muito mais importante do que como eles executam. O que um objeto faz é mais importante de como ele faz, seguindo essa regra seu sistema fica mais fácil de manter, modificar e muito mais! Como você já percebeu, esta é uma das idéias principais que queremos passar.
24/04/15 Introução a Java 196
OO – Interface
Você pode implementar mais de uma interface!• Diferentemente das classes, uma interface pode
herdar de mais de uma interface. É como um contrato que depende de que outros contratos sejam fechados antes deste valer. Você não herda métodos e atributos, e sim responsabilidades.
24/04/15 Introução a Java 197
OO – Interface
• Dificuldade no aprendizado de interfaces– Interfaces representam uma barreira no aprendizado do Java:
parece que estamos escrevendo um código que não serve pra nada, já que teremos essa linha (a assinatura do método) escrita nas nossas classes implementadoras. Essa é uma maneira errada de se pensar.
– O objetivo do uso de uma interface é deixar seu código mais flexível, e possibilitar a mudança de implementação sem maiores traumas. Não é apenas um código de prototipação, um cabeçalho!
– Os mais radicais dizem que toda classe deve ser “interfaceada”, isto é, só devemos nos referir a objetos através de suas interfaces. Se determinada classe não tem uma interface, ela deveria ter. Os autores deste material acham tal medida radical demais, porém o uso de interfaces em vez de herança é amplamente aconselhado. (consultar os clássicos livros Design Patterns, Refactoring e Effective Java).
– No livro Design Patterns, logo no início os autores citam 2 regras “de ouro”. Uma é “evite herança, prefira composição”, e a outra “programe voltado a interface e não a implementação”.
24/04/15 Introução a Java 198
OO – Interface• Exemplo de Utilização:
Pattern DAO
24/04/15 Introução a Java 199
OO – Interface
• Posso substituir toda minha herança por interfaces? Qual é a vantagem e a desvantagem?
• Uma interface também pode declarar constantes (não atributos de objeto). Qual é a utilidade?
24/04/15 Introução a Java 200
OO – Interface [Exercícios]1. Nossos banco precisa tributar dinheiro de alguns
bens que nossos clientes possuem.– Para isso vamos criar uma interface:
• public interface Tributavel {• double calculaTributos();• }
• Lemos essa interface da seguinte maneira: “todo que quiserem ser tributável precisam saber
calcular tributos, devolvendo um double”
24/04/15 Introução a Java 201
OO – Interface [Exercícios]
• Alguns bens são tributáveis e outros não, ContaPoupanca não é tributável, já ContaCorrente você precisa pagar 1% da conta, e o SeguroDeVida tem uma taxa fixa de 42 reais. (faça a mudança em ContaCorrente e cria a classe SeguroDeVida):
1. public class ContaCorrente extends Conta implements Tributavel {
2. // outros atributos e metodos3. public double calculaTributos() {4. return this.saldo * 0.1;5. }6. }
1. public class SeguroDeVida implements Tributavel {2. public double calculaTributos() {3. return 42;4. }5. }
24/04/15 Introução a Java 202
OO – Interface [Exercícios]
• Diagrama de Classe
24/04/15 Introução a Java 203
OO – Interface• Crie agora uma classe TestaTributavel com um main para
testar as atribuições, repare:
1. public class TestaTributavel {2. public static void main (String[] args) {3. ContaCorrente cc = new ContaCorrente();4. cc.deposita(100);5. Tributavel t = cc;6. System. out.println(t.calculaTributos());7. }8. }
• Tente agora chamar o método getSaldo através da referência t, o que ocorre? Porque?
24/04/15 Introução a Java 204
OO – Interface
3. (opcional) Crie um GerenciadorDeImpostoDeRenda que recebe todos os tributáveis de uma pessoa e soma seus valores, e um método para devolver seu total:
1. public class GerenciadorDeImpostoDeRenda {
2. double total;
3. public void adiciona(Tributavel t) {
4. System.out.println("Adicionando tributavel: " + t);
5. this.total += t.calculaTributos();
6. }
7. public double getTotal() {
8. return total;
9. }
10. }
24/04/15 Introução a Java 205
OO – Interface
• Crie um main para instaciar diversas classes que implementam Tributavel e passar como argumento para um GerenciadorDeImpostoDeRenda. Repare que você não pode passar qualquer tipo de conta para o método adiciona, apenas a que implementa Tributavel.
• Além disso pode passar o SeguroDeVida.
1. public class TestaGerenciadorDeImpostoDeRenda {2. public static void main (String[] args) {3. GerenciadorDeImpostoDeRenda gerenciador = 4. new GerenciadorDeImpostoDeRenda();5. SeguroDeVida sv = new SeguroDeVida();6. gerenciador.adiciona(sv);7. ContaCorrente cc = new ContaCorrente();8. cc.deposita(1000);9. gerenciador.adiciona(cc);10. System.out.println(gerenciador.getTotal());11. }12. }
24/04/15 Introução a Java 206
OO – Interface
• Repare que de dentro do Gerenciador você não pode acessar o método getSaldo, por exemplo, pois você não tem a garantia de que o Tributavel que vai ser passado como argumento tem esse método. A única certeza que você tem é de que esse objeto tem os métodos declarados na interface Tributavel.
• É interessante enxergar que as interfaces (como aqui no caso Tributavel) costumam ligar classes muito distintas, unidas por uma característica que elas tem em comum (SeguroDeVida e ContaCorrente são entidades completamente distintas, porém ambas possuem a característica de serem tributáveis).
4. (Opcional, Avançado) Transforme a classe Conta em uma interface. Atenção: faça isso num projeto a parte pois usaremos a Conta como classes nos exercícios futuros.
24/04/15 Introução a Java 207
OO – Revisão [Membros de Instância e de Classe]
24/04/15 Introução a Java 208
OO – Membros de Instância e de ClasseQuando um número de objetos são criados da mesma
classe, cada um tem suas distintas cópias de variáveis de instância. No caso da nossa classe Conta, as variáveis de instância são os atributos nome, número, saldo e limite. Cada objeto Conta tem seus próprios valores para estas variáveis, armazenadas em diferentes posições de memória.
Algumas vezes, nós queremos ter variáveis que são comuns a todos os objetos. Isto é realizado com o uso do modificador static. Atributos que possuem o modificador static nas suas declarações são chamados de campos estáticos ou variáveis de classe.
24/04/15 Introução a Java 209
OO – Membros de Instância e de Classe
• Esses atributos estão associados com a classe ao invés de um objeto. Cada instância de classe compartilha uma variável de classe, na qual está fixada em uma posição de memória. Qualquer objeto pode alterar o valor de uma variável de classe, mas variáveis de classe podem também ser manipuladas sem que aja uma instância da classe
24/04/15 Introução a Java 210
OO – Membros de Instância e de Classe• Exercício:
• É necessário que, ao se criar contas bancárias, o número de cada conta seja é seqüencial, iniciando em 1 para o primeiro objeto. Esse número é único para cada objeto.
• Ao mesmo tempo, precisamos de um campo para fazer um tracking de quantas contas bancárias estão criadas e permitindo saber o número da próxima conta.
• Implementar uma solução para esse problema.
24/04/15 Introução a Java 211
OO – Membros de Instância e de Classe
• Resolução:
• O campo necessário para fazer o tracking de quantas contas bancárias estão criadas não está associado a um objeto Conta individual, mas à classe Conta como um todo.
• Para isso, nós precisamos de uma variável de classe, numeroDeContas, como segue:
24/04/15 Introução a Java 212
OO – Membros de Instância e de Classepublic class Conta { private String nome; private int numero; private double saldo; private double limite;
private static int numeroDeContas = 0;}
Variáveis de classe são referenciadas pelo nome da própria classe, como no exemplo abaixo:
Conta.numeroDeContas;
24/04/15 Introução a Java 213
OO – Membros de Instância e de Classe• Isso torna claro que esse tipo de variável é
do tipo de variável de classe.
• Nós também podemos referenciar campos estáticos através de uma referência de objeto como:
contaSonho.numeroDeContas;
mas isso não é recomendável pois não segue a convenção e pode ser confundido com uma variável de instância.
24/04/15 Introução a Java 214
OO – Membros de Instância e de Classe• A linguagem Java suporta métodos estáticos assim
como variáveis estáticas. Métodos estáticos, na qual tem o modificador static em suas declarações, devem ser invocados com o nome da classe, não necessário haver uma instancia dessa classe:
NomeDaClasse.nomeDoMetodo(argumentos)
• Assim como as variáveis de instância, também podemos chamar métodos estáticos através dos objetos, porém isso é desencorajado e segue a mesma recomendação dada as variáveis de instância.
24/04/15 Introução a Java 215
OO – Membros de Instância e de Classe• Um uso comum para métodos estáticos é o
de acessar campos estáticos.
• Por exemplo:– Nós podemos adicionar um método estático para
acessar nos informar o número de contas criado no exercício anterior:
public static int getNumeroDeContas() { return numeroDeContas;}
24/04/15 Introução a Java 216
OO – Membros de Instância e de Classe• Nem todas as combinações de variáveis de instância
e de classe e métodos são permitidos:
– Métodos de instância podem acessar variáveis de instância e métodos de instância diretamente.
– Métodos de instância podem acessar variáveis de classe e métodos de classe diretamente.
– Métodos de classe podem acessar variáveis de classe e métodos de classe diretamente.
– Métodos de classe NÃO PODEM acessar variáveis de instância ou métodos de instância diretamente – para isso é necessário fazer uso de uma referência de objeto.
• Métodos estáticos não podem fazer uso da palavra chave this porque não há instância para que o this faça referência.
24/04/15 Introução a Java 217
OO – Constantes• O modificador static, na combinação com o
modificador final, é também usado para definir constantes. O modificador final indica que o valor deste campo NÃO pode mudar.
• Por exemplo:A seguinte declaração de variável define uma constante chamada PI, na qual seu valor é uma aproximação de PI (o comprimento de uma circunferência de um circulo e seu diâmetro):
static final double PI = 3.141592653589793;
24/04/15 Introução a Java 218
OO – Constantes• Constantes definidas dessa forma não
podem ter seus valores modificados, e uma tentativa disso causará um erro de compilação se o programa identificar.
• Por convenção, o nome de uma constante é definido por todas as letras do nome da variável em letra maiúscula. Caso seja um nome composto, as palavras são separadas por underscore.
24/04/15 Introução a Java 219
OO – Constantes• Se um tipo primitivo ou uma String é definida
como uma constante e seu valor é conhecido em tempo de compilação, o compilador troca o nome da constante em qualquer lugar do código por seu valor. Isso é chamado de constante de tempo de compilação. Se o valor de uma constante mudar por via de regra de negócio (por exemplo, PI passa a ser 3.975), é necessário recompilar todas as classes que fazem uso dessa constante para atualizar o valor atual.
• Interfaces podem também definir constantes, além de métodos.
24/04/15 Introução a Java 220
Passagem de Parâmetros• Argumentos primitivos, como um int ou um doublé,
são passados para métodos por valor. Isso significa que, qualquer mudança nos valores dos parâmetros existe somente dentro do escopo do método. Quando o método finaliza sua execução, os parâmetros são eliminados e qualquer mudança perdida.
• Exemplo:
// Método mainint x = 3;testePassagemPorValor(x);System.out.println("Após invocar o método, x é " + x);
24/04/15 Introução a Java 221
Passagem de Parâmetros// Muda o valor do parâmetro
public static void testePassagemPorValor (int p) {
p = 10;
}
Qual o valor de x?
24/04/15 Introução a Java 222
Passagem de Parâmetros• Parâmetros com tipos de dados de
referência, como objetos, também são passados para os métodos por valor. Isso significa que quando o método finaliza, as referencias passadas permanecem as mesmas de antes. CONTUDO, valores de atributos dos objetos podem ser alterados no método.
• Por exemplo, vamos considerar um método em uma classe que move objetos do tipo Circulo:
24/04/15 Introução a Java 223
Passagem de Parâmetrospublic void moveCirculo(Circulo circulo, int deltaX,
int deltaY) {// move o circulo dado um delta X e um delta Y
circulo.setX(circulo.getX() + deltaX); circulo.setY(circulo.getY() + deltaY);
//atribui uma nova referência ao círculo circulo = new Circulo(0, 0);}
O que acontecerá a uma instância de círculo e seus atributos após a execução desse método?
moveCirculo(meuCirculo, 23, 56);
24/04/15 Introução a Java 224
Modificador final• O modificador final também pode ser
utilizado, além das constantes, para métodos, parâmetros e classes. Quando um método, atributo ou classe é definido como final, este não pode ter seu valor reescrito.
24/04/15 Introução a Java 225
Exercícios
1. Criar métodos para teste de passagem de valor e de referência e responder:• Se uma referência não pode ser alterada dentro de um método,
há uma maneira de fazer com que uma referência externa seja alterada?
1. Dado o conceito sobre membros de instância e de classe, pergunta:• Há uma maneira de se fazer com que haja uma e somente uma
instância de uma classe em um sistema?
1. Dada uma classe abstrata X como fazer com que um método desta classe não seja reescrita por suas subclasses? Depois crie uma subclasse dessa classe abstrata na qual esta não permita mais herança.
2. Criar um aplicativo que permita realizar o cálculo de área de uma figura geométrica. Cada figura geométrica deverá ser criada informando suas dimensões e um método deverá ser chamado para fazer o cálculo.
24/04/15 Introução a Java 226
Exercícios1. Criar uma API (Application Program Interface) que permita:
• Conectar a um banco de dados• A partir da conexão, executar uma consulta• Obter o resultado da consulta• Fechar a conexão com o banco de dados
1. Cada um deverá implementar essa API para um tipo de banco de dados, respectivamente:
• Oracle• SQL Server• MySQL• Sybase• Informix• DB2
1. Criar um aplicativo teste.
2. Trocar as implementações entre cada um e rodar o aplicativo teste.
24/04/15 Introução a Java 227
Aula 5 – [Agenda] 07-07-2007• Tratamento de exceções ( pág 151 )
– Bloco try/catch
• Tipos de Exceções– Verificadas– Não verificadas
• Objeto Exception• Lançamento de exceções
– throws– throw
• Restrições• Javadoc
– Tags– Importância da documentação
24/04/15 Introução a Java 228
Tratamento de Exceções• Em nosso sistema bancário, o que
aconteceria se invocassemos o método sacar da classe Conta sem haver saldo suficiente?
• Infelizmente, só o usuário saberia que não há saldo suficiente pois apenas uma mensagem de erro é impressa na tela.
• No exemplo a seguir, vamos forçar uma conta a ter um saldo negativo:
24/04/15 Introução a Java 229
Tratamento de ExceçõesConta suaConta = new Conta();suaConta.depositar(100);suaConta.setLimite(100);suaConta.sacar(1000);
• Neste caso, o método sacar deveria funcionar?
• Em implementações profissionais, é muito que quem saiba tratar o erro é aquele que chamou o método e não a própria classe! Portanto, nada mais natural que a classe sinalizar que um erro ocorreu.
24/04/15 Introução a Java 230
Tratamento de Exceções• A solução mais simples, anteriormente
utilizada em nossa implementação, é a de marcar o retorno de um método como boolean e retornar true se tudo ocorreu da maneira planejada ou false caso contrário:
boolean sacar(double quantidade) { if (quantidade > this.saldo + this.limite) { System.out.println("Saldo não disponível!"); return false; } else { this.saldo = this.saldo – quantidade; return true; }}
24/04/15 Introução a Java 231
Tratamento de Exceções• Uma alternativa de tratamento:
Conta contaDeVoces = new Conta();contaDeVoces.setSaldo(100);contaDeVoces.setLimite(100);if (!contaDeVoces.sacar(1000)) { System.out.println("So sorry...");}
• Mas e se fosse necessário sinalizar quando o usuário passou um valor negativo como quantidade? Uma solução é alterar o retorno de boolean para int, e retornar o código do erro que ocorreu mas isto é considerado uma má prática.
24/04/15 Introução a Java 232
Tratamento de Exceções• Além de perdermos o retorno do método, o
valor retornado é “mágico”, e só legível perante extensa documentação, além de não obrigar o programador a tratar esse retorno, e em caso de um “esquecimento”, o programa continuará rodando.
• O exemplo a seguir mostra um caso onde, através do retorno, não será possível descobrir se ocorreu um erro ou não pois o método retorna um objeto do tipo Cliente:
24/04/15 Introução a Java 233
Tratamento de Exceçõespublic Cliente procuraCliente(int id) { if(idInvalido) { // Como avisar o método que chamou este
// que ocorreu um erro? } else { Cliente cliente = new Cliente(); cliente.setId(id); // outras atribuições return cliente; }}
24/04/15 Introução a Java 234
Tratamento de Exceções• É por esse e outros motivos que em Java há
uma maneira especial de tratar eventos excepcionais, casos onde acontece algo que normalmente não deveria acontecer. A isso damos o nome de Exception.
• Quando um erro ocorre dentro de um método, o método cria um objeto e lança isso para o sistema. O objeto, uma exception object, contém informações sobre o erro, incluindo seu tipo e o estado do programa quando o erro ocorreu.
24/04/15 Introução a Java 235
Tratamento de Exceções• A criação de um objeto de exceção e o
lançamento dele para o sistema é chamado de throw.
• Após o método lançar uma exceção, o sistema tenta encontrar alguma coisa para tentar identificar a causa dessa exceção. O conjunto de possíveis “causadores” da exceção é uma lista ordenada que contém os métodos que foram chamados até o método que causou o erro. Essa lista de métodos é conhecida como call stack.
• Um exemplo de call stack é mostrado a seguir:
24/04/15 Introução a Java 236
Tratamento de Exceções• Um exemplo de Call Stack:
main
Método com tratamentode exceção
Método sem tratamentode exceção
Método onde oerro ocorreu
Chamada de Método
Chamada de Método
Chamada de Método
24/04/15 Introução a Java 237
Tratamento de Exceções• O sistema procura no call stack por um
método que contém um bloco de código que capture a exceção. Esse bloco é chamado de exception handler. A procura começa com o método na qual o erro ocorreu e procede através do call stack na ordem reversa na qual os métodos foram chamados. Quando um handler apropriado é encontrado, o sistema passa a exceção para o handler.
• Um exception handler é considerado apropriado se o tipo de objeto de exceção lançado é igual ao tipo assinado no handler.
24/04/15 Introução a Java 238
Tratamento de Exceções• É dito ao exception handler para capturar a exception. Se
o sistema exaustivamente procurar em todos os métodos no call stack sem encontrar um exception handler apropriado, como é mostrado na figura a seguir, o sistema (e consequentemente a execução) termina.
main
Método com tratamentode exceção
Método sem tratamentode exceção
Método onde oerro ocorreu Procurando por um
exception handler apropriado
Procurando por um exception handler apropriado
Lança a exceção
Encaminha a exceção
Captura a exceção
24/04/15 Introução a Java 239
Exercício• Testar o seguinte código:
class Teste { public static void main(String[] args) { System.out.println("inicio do main"); metodo1(); System.out.println("fim do main"); } public static void metodo1() { System.out.println("inicio do metodo1"); metodo2(); System.out.println("fim do metodo1"); }
public static void metodo2() { System.out.println("inicio do metodo2"); int[] array = new int[10]; for(int i = 0; i <= 15; i++) { array[i] = i; System.out.println(i); } System.out.println("fim do metodo2"); }}
24/04/15 Introução a Java 240
Tratamento de Exceções• Como podem reparar, o método main chama o metodo1,
e esse por sua vez chama o metodo2. Cada um desses métodos pode ter suas próprias variáveis locais, sendo que, por exemplo, o metodo1 não enxerga as variáveis declaradas dentro do main.
• Como o Java (e muitas das outras linguagens) faz isso? Toda invocação de método é empilhada em uma estrutura de dados que isola a área de memória de cada um. Quando um método termina (retorna), ele volta para o método que o invocou. Ele descobre isso através da pilha de execução (call stack).
• Porém o nosso metodo2 possui um enorme problema: está acessando uma posição de array indevida.
• Qual é a saída? O que isso representa? O que ela indica?
24/04/15 Introução a Java 241
Tratamento de Exceções• A saída de execução do nosso programa conhecido rastro da
pilha (ou stacktrace). É uma saída importantíssima para nós programadores, tanto que em qualquer fórum um lista de discussão, é comum os programadores enviar, juntamente com a descrição do problema, o stacktrace.
• Porque isso aconteceu? O sistema de exceções do Java funciona da seguinte maneira:– Quando uma exceção é lançada (throw) a JVM entra em estado de
alerta, e vai ver se o método atual toma alguma precaução ao tentar executar esse trecho de código. Como podemos ver, o metodo2 não toma nenhuma medida diferente do que vimos até agora.
– Como o metodo2 não está tratando esse problema, a JVM para a execução dele anormalmente, sem esperar ele terminar, e volta um call stack a baixo, onde será feita nova verificação: o metodo1 está se precavendo de um problema chamando ArrayIndexOutOfBoundsException? Não. Volta para o main, onde também não há proteção, então a JVM morre.
24/04/15 Introução a Java 242
Tratamento de Exceções• Obviamente nós estamos forçando o erro, o
que não faria sentido tomarmos cuidado com ele. Seria fácil arrumar um problema desses, basta navegarmos na array no máximo até o seu tamanho máximo (length). Porém, apenas para entender o controle de fluxo de uma Exception, vamos colocar o código que vai tentar (try) executar o bloco perigoso, e caso o problema seja do tipo ArrayIndexOutOfBoundsException, ele será pego (catch).
24/04/15 Introução a Java 243
Exercício• Adicionar um try/catch em volta do laço for
pegando ArrayIndexOutOfBoundsException:
try { for(int i = 0; i <= 15; i++) { array[i] = i; System.out.println(i); }} catch (ArrayIndexOutOfBoundsException e) { System.out.println("erro: " + e);}
• O que é impresso agora?
24/04/15 Introução a Java 244
Exercício• Agora, em vez de fazerem o try em torno do
for inteiro, tentem apenas com o bloco de dentro do laço for. Qual é a diferença?
• Depois retirem o try/catch e coloque ele em volta da chamada do metodo2.
• Façam a mesma coisa, retirando o try/catch novamente e colocando em volta da chamada do metodo1. O que acontece?
• Reparem que a partir do momento que uma exception foi “catched” (tratada, handled), a execução volta ao normal a partir daquele ponto.
24/04/15 Introução a Java 245
Exceções de Runtime mais comuns• Que tal tentarmos dividir um número por zero?
Será que o sistema consegue fazer aquilo que nós definimos que não existe?
public class TestandoADivisao { public static void main(String args[]) { int i = 5571; i = i / 0; System.out.println("O resultado " + i); }}
• Tentem executar o programa acima. O que acontece?
24/04/15 Introução a Java 246
Exceções de Runtime mais comunspublic class TestandoReferenciaNula { public static void main(String args[]) {
Conta c = null; System.out.println("Saldo atual " + c.getSaldo());
}}
• Tentem executar o programa acima. O que acontece?
24/04/15 Introução a Java 247
Exceções de Runtime mais comuns• Reparem que um
ArrayIndexOutOfBoundsException ou um NullPointerException poderia ser facilmente evitado com o for corretamente escrito, ou com ifs que checariam os limites da array.
• Outro caso que também ocorre tal tipo de exceção é quando uma conversão explícita (cast) é feita. Em todos os casos tais erros provavelmente poderiam ser evitados pelo programador. É por esse motivo que o java não obriga a dar o try/catch nessas exceptions, e chamamos essas exceções de unchecked (em outras palavras, o compilador não checa se estamos tratando essas exceções).
24/04/15 Introução a Java 248
Checked Exceptions• Fica claro com os exemplos de código anteriores que não é
necessário declarar que estamos tentando fazer algo onde um erro possa ocorrer. Os dois exemplos, com ou sem o try/catch, compilaram e rodaram. Em um, o erro terminou o programa e no outro foi possível tratá-lo. Mas não é só esse tipo de exceção que existe em Java.
• Um outro tipo obriga os usuários que chamam o método ou construtor a tratar o erro. Um exemplo que podemos mostrar agora é o de abrir um arquivo para leitura, quando pode ocorrer o erro do arquivo não existir (veremo como trabalhar com arquivos em outra aula, não se preocupe com isto agora):
public static void metodo() { new java.io.FileReader(“arquivo.txt”);}
24/04/15 Introução a Java 249
Checked Exceptions• Para compilar e fazer o programa funcionar,
precisamos tratar o erro de um de dois jeitos. O primeiro é tratá-lo com o try e catch do mesmo jeito que usamos no exemplo anterior com uma array:
public static void metodo() { try { new java.io.FileReader(“arquivo.txt”); } catch (java.io.FileNotFoundException e) { System.out.println(“Nao foi possivel abrir o
arquivo para leitura”); }}
24/04/15 Introução a Java 250
Checked Exceptions• A segunda forma de tratar esse erro é
a de delegar ele para quem chamou o nosso método, isto é, passar para a frente.
public static void metodo() throws java.io.FileNotFoundException {
new java.io.FileReader(“arquivo.txt”);
}
24/04/15 Introução a Java 251
Checked Exceptions• No início existe uma grande tentação de sempre passar o erro
pra frente para outros tratarem dele. Pode ser que faça sentido dependendo do caso mas não até o main, por exemplo.
• Acontece que quem tenta abrir um arquivo sabe como lidar com um problema na leitura. Quem chamou um método no começo do programa pode não saber ou, pior ainda, tentar abrir cinco arquivos diferentes e não saber qual deles teve um problema!
• Não há uma regra para decidir em que momento do programa iremos tratar determinar exceção. Isso vai depender de em que ponto temos condições de tomar uma decisão em relação a um determinado erro. Enquanto não for o momento, iremos provavelmente preferir delegar a responsabilidade para o método que invocou.
24/04/15 Introução a Java 252
Checked Exceptions
24/04/15 Introução a Java 253
Checked Exceptions
24/04/15 Introução a Java 254
Mais de uma exception• É possível tratar mais de uma exception
quase ao mesmo tempo:• Com o try e catch:
try { objeto.metodoQuePodeLancarIOeSQLException();
} catch (IOException e) { // ..} catch (SQLException e) { // ..}
24/04/15 Introução a Java 255
Mais de uma exception• Com o throws:
public void abre(String arquivo) throws IOException, SQLException {
// ..}
24/04/15 Introução a Java 256
Mais de uma exception• Podemos também escolher tratar algumas exceções
e declarar as outras no throws.• 3. Com o throws e com o try e catch:public void abre(String arquivo) throws IOException { try { objeto.metodoQuePodeLancarIOeSQLException(); } catch (SQLException e) { // .. }}
• É desnecessário declarar no throws as exceptions que são unchecked, porém é permitido e, às vezes, facilita a leitura e a documentação do seu código.
24/04/15 Introução a Java 257
Lançando exceções• O método sacar da nossa classe Conta
devolve um boolean caso consiga ou não sacar:
boolean saca(double valor){ if(this.saldo < valor){ return false; }else{ this.saldo=valor; return true; }}
24/04/15 Introução a Java 258
Lançando exceções• Podemos também lançar uma Exception, o que é
extremamente útil. Dessa maneira resolvemos o problema de alguém poder esquecer de fazer um if no retorno de um método.
• A palavra chave throw lança uma Exception (diferente de throws, que apenas avisa da possibilidade de método lançar):
public void sacar(double valor){ if(this.saldo < valor){ throw new RuntimeException(); }else{ this.saldo=valor; }}
24/04/15 Introução a Java 259
Lançando exceções• No nosso caso o método sacar está lançando uma
do tipo unchecked. RuntimeException é a exception mãe de todas as exceptions unchecked. A desvantagem aqui é que ela é muito genérica, quem receber esse erro não sabe dizer exatamente qual foi o problema. Podemos então usar uma Exception mais específica:
public void sacar(double valor){ if(this.saldo < valor){ throw new IllegalArgumentException(); }else{ this.saldo=valor; }}
24/04/15 Introução a Java 260
Lançando exceções• IllegalArgumentException diz um pouco mais: algo foi
passado como argumento e seu método não gostou. Ela é uma Exception unchecked pois estende de RuntimeException e já faz parte da biblioteca do java. (IllegalArgumentException é melhor ser usado quando um argumento sempre é inválido, como por exemplo números negativos, referências nulas, etc).
• E agora para pegar esse erro, não usaremos um if/else e sim um try/catch, porque faz mais sentido pois é uma exceção a falta de saldo:
Conta cc = new ContaCorrente();cc.deposita(100);try{ cc.sacar(100);}catch(IllegalArgumentException e){ System.out.println("Saldo Insuficiente");}
24/04/15 Introução a Java 261
Lançando exceções• Podemos melhorar ainda mais e passar para o
construtor da IllegalArgumentException o motivo da exceção:
public void sacar(double valor){ if(this.saldo < valor){ throw new IllegalArgumentException("Saldo insuficiente"); }else{ this.saldo=valor; }}
• O método getMessage() definido na classe Throwable (mãe de todos os tipos de erros e exceptions) vai retonar a mensagem que passamos ao construtor da IllegalArgumentException.
24/04/15 Introução a Java 262
Lançando exceçõestry{ cc.sacar(100);}catch(IllegalArgumentException e){
System.out.println(e.getMessage());
}
24/04/15 Introução a Java 263
Criando Exceptions• É bem comum criar uma própria classe de
exceção para controlar melhor o uso de exceções. Dessa maneira podemos passar valores específicos para ela carregar, e que sejam úteis de alguma forma. Vamos criar a nossa.
• Voltando para o exemplo das Contas, vamos criar a nossa Exceção de SaldoInsuficienteException:
public class SaldoInsuficienteException extends RuntimeException{
SaldoInsuficienteException(String message){ super(message); }}
24/04/15 Introução a Java 264
Criando Exceptions• E agora ao invés lançar um
IllegalArgumentException, vamos lançar nossa própria exception, com uma mensagem que dirá “Saldo Insuficiente”:
public void sacar(double valor){ if(this.saldo < valor){ throw new SaldoInsuficienteException("Saldo
Insuficiente, tente um valor menor"); }else{ this.saldo=valor; }}
24/04/15 Introução a Java 265
Criando Exceptions• E para testar, vamos criar uma classe que
deposite um valor e tente sacar um valor maior:
public static void main(String[] args) { Conta cc = new ContaCorrente(); cc.deposita(10); try{ cc.saca(100); }catch(SaldoInsuficienteException e){ System.out.println(e.getMessage()); }}
24/04/15 Introução a Java 266
Criando Exceptions • Podemos transformar essa
Exception de unchecked para checked, obrigando assim quem chama esse método a dar trycatch, ou throws:
public class SaldoInsuficienteException extends Exception{
SaldoInsuficienteException(String message){
super(message); }}
24/04/15 Introução a Java 267
Catch e Throws• Existe uma péssima prática de
programação em java que é a de escrever o catch e o throws diretamente com a classe Exception.
• Existem códigos que sempre usam Exception pois isso cuida de todos os possíveis erros. O maior problema disso é generalizar o erro. Se alguém joga algo do tipo Exception para quem chamou, quem recebe não sabe qual o tipo específico de erro ocorreu e não vai saber como tratar o mesmo.
24/04/15 Introução a Java 268
Finally• Os blocos try e catch podem conter uma
terceira cláusula chamada finally que indica o que deve ser feito após o término do bloco try ou de um catch qualquer.
• É interessante colocar algo que é imprescindível de ser executado, caso o que queremos fazer tenha dado certo, ou não. O caso mais comum é o de liberar um recurso, como um arquivo ou conexão com banco de dados, no finally, para que a gente possa ter a certeza de que aquele arquivo (ou conexão) vá ser fechado, mesmo que algo tenha falhado no decorrer do código.
24/04/15 Introução a Java 269
Finally • No exemplo a seguir, o bloco finally será
executado não importa se tudo ocorrer ok ou com algum problema:
try { // bloco try} catch (IOException ex) { // bloco catch 1} catch (SQLException sqlex) { // bloco catch2} finally { // bloco finally}
24/04/15 Introução a Java 270
Finally
• É possível criar um bloco try e finally, sem catch. Isso significa se não ocorrer erro algum, o bloco do finally irá ser executado. Se ocorrer algum erro, ele também será executado, e o erro irá ser jogado para quem chamou o método.
24/04/15 Introução a Java 271
Exercícios1) Na classe Conta, modifiquem o método depositar(double
x) para que ele agora retorne void. Ele deverá lançar uma exception chamada IllegalArgumentException, que já faz parte da biblioteca do java, sempre que o valor passado como argumento for inválido (por exemplo, quando for negativo).
2) Criar uma classe TestaDeposita com método main. Criar uma Conta e tente depositar valores inválidos. Executem a classe.
3) Adicionar o try/catch para tratar o erro. Executem a classe.
4) Ao lançar a IllegalArgumentException, passar via construtor uma mensagem a ser exibida. Lembrem-se que a String recebida como parâmetro é acessível depois via o método getMessage() herdado por todas as Exceptions. Alterar a classe TestaDeposita para exibir a mensagem da exceção. Executar a classe.
24/04/15 Introução a Java 272
Exercícios5) Criar a classe de exceção ValorInvalidoException que
extenda de RuntimeException. Lancem-na em vez de IllegalArgumentException.
6) Colocar um construtor na classe ValorInvalidoException que receba o quanto foi tentado sacar. Dessa maneira, na hora de dar o throw new ValorInvalidoException iremos precisar passar o valor do saque ilegal como argumento.
7) A classe Exception (na verdade Throwable) tem definida nela um método getMessage que pode ser reescrito nas suas subclasses para falar um pouco mais sobre o erro. Reescrevam-no na classe ValorInvalidoException para que imprima algo como:– "Não é possível sacar valor negativo: " + valor;
8) Declarar a classe ValorInvalidoException como filha de Exception em vez de RuntimeException. O que acontece?
24/04/15 Introução a Java 273
Anexos