Você está na página 1de 368

Programação Orientada a

Objetos

Java
Prof. Dr. Bruno Ferreira
Sumário
• O que é Java
• Softwares utilizados (instalação)
• O ambiente de desenvolvimento
• Processo de compilação
• Características da linguagem
• Primeiros exemplos
• A sintaxe da linguagem
O que é java?
Java é uma linguagem de programação
introduzida em 1995 pela Sun Microsystems

A história começa em 1991, em San Hill Road


empresa filiada a Sun (da qual hoje pertence a
empresa Oracle), formado pelo time de
engenheiros lliderados por Patrick Naugthon,
Sun Fellow e James Gosling.
O que é java?
O grupo criou o projeto denominado Projeto
Green, que consistia na criação de tecnologias
modernas de software para empresas
eletrônicas de consumo. A ideia principal do
Java era que os aparelhos eletrônicos se
comunicassem entre si.

Com o tempo perceberam que não poderiam ficar


presos aos sistemas operacionais, até porque
os clientes não estavam interessados no tipo de
processador que estavam utilizando
O que é java?
A linguagem de programação chamada de Oak
(carvalho) foi criada pelo chefe do projeto
James Gosling.
A explicação da origem do nome foi que enquanto
pensava numa estrutura de diretórios para a
linguagem, observava pela janela um carvalho.
Mas esse nome já estava registrado, então o
nome acabou surgindo na cafeteria local da
cidade onde tomavam café. “Java”, pois era o
nome da terra de origem do café
O que é java?

Em 1995 a Sun viu uma oportunidade na Web,


nessa época nas páginas não existia muita
interatividade, apenas conteúdos estáticos eram
exibidos. Então nesse ano a Sun anunciou o
ambiente Java, sendo um absoluto sucesso,
gerando uma aceitação aos browsers populares
como o Netscape Navigator e padrões
tridimensionais como o VRML
Características da linguagem
• Orientada a objetos – da suporte a todos os conceitos
do paradigma OO.
• Independente de plataforma – JVM.
• Sem ponteiros – A JVM tem um mecanismo automático
de gerência de memória não permitindo a manipulação
direta, e liberando espaço quando necessário.
• Performance – a linguagem é compilada e interpretada
(neste processo utiliza a tecnologia JIT)
• Segurança – a JVM controla as ações da aplicação
bloqueando possíveis ações destrutivas ou proliferações
• Multi-threading
• Free
• Case-Sentitive
Edições Java
• Standard Edition (SE) é a plataforma destinada
às aplicações em geral (desktops,
computadores pessoais);
• Micro Edition (ME) é uma plataforma destinada
aos dispositivos móveis e sistemas embarcados
(PDAs, controles remotos);
• Enterprise Edition (EE) é a plataforma que
engloba aplicações corporativas, ela possui
bibliotecas (APIs) para implementar software
distribuído, tolerante a falhas e multicamada.
Softwares utilizados (instalação)

• O que você vai instalar?

• JVM = apenas a virtual machine, esse download


não existe, ele é apenas uma especificação.
• JRE = Java Runtime Environment, ambiente de
execução Java, formado pela JVM
implementada e bibliotecas, tudo que você
precisa para executar uma aplicação Java.
• JDK = Nós, desenvolvedores, faremos o
download do JDK que contém o Java SE
(Standard Edition), EE(Enterprise Edition ),
ME(Micro Edition).
Processo de compilação
Processo de compilação (cont.)
Processo de compilação (cont.)
• JVM é um “mini Sistema Operacional”
Processo de compilação (cont.)

• Compilando um arquivo via command line no


Windows:
C:\> javac <NomeDaClasse>.java

• Interpretando o arquivo via command line no


Windows:
C:\> java <NomeDaClasse> Atenção: O caminho
de instalação do
Java deve estar no
path do sistema
O ambiente de desenvolvimento
• Bloco de notas
• Eclipse, NetBeans, JCreator, etc..
Primeiros Exemplos
• Erros comuns de programação

- Nome do arquivo deve começar com


maiúsculo
- O Nome da classe deve ter o mesmo nome
do arquivo
- Lembre-se, o Java é case-sensitive
Primeiros Exemplos cap. 2

public class BemVindo1


{
// método main de onde a aplicação começará a ser
executada
public static void main( String args[] )
{
System.out.println( "Bem vindo ao java!" );

} //fim do metodo

} // fim da classe
Primeiros Exemplos cap. 2
public class BemVindo2
{

public static void main( String args[] )


{
System.out.print( " Bem vindo ao " );
System.out.println( "Java!" );

}
Primeiros Exemplos cap. 2

public class BemVindo3


{

public static void main( String args[] )


{
System.out.println( "Bem Vindo\nao\nJava!" );

}
Primeiros Exemplos cap. 2
Seqüência Descrição
de escape
\n Nova linha. Posiciona o cursor de tela no início da nova linha.
\t Tabulação horizontal. Move o cursor de tela para a próxima
parada de tabulação.
\r Retorno de carro. Posiciona o cursor da tela no início da linha
atual – não avança para a próxima linha.
\\ Barras invertidas. Utilizadas para imprimir um caractere de
barra invertida
\” Aspas duplas. Utilizado para imprimir um caractere de aspas
duplas. Por exemplo:
System.out.println(“ \”em aspas\” ”)
“em aspas”
Primeiros Exemplos cap. 2

public class BemVindo4


{

public static void main( String args[] )


{
System.out.printf( "%s\n%s\n",
"Bem vindo ao", "Java!" );

}
Primeiros Exemplos cap. 2
• Printf – exibe dados formatados (o “ f ”
significa formatado)
Ex. %s, %d, %.2f

• Já o Print e o Println não aceitam


parâmetros de formatação
Primeiros Exemplos cap. 2
import java.util.Scanner; // importar a biblioteca para ler o teclado

public class Adicao


{
// metodo main por onde a aplicação começa a ser executada
public static void main( String args[] )
{
// cria uma variavel chamada entrada do tipo scanner que captura as teclas
Scanner entrada = new Scanner( System.in );

int num1; // primeiro numero da adição


int num2; // segundo numero da adição
int soma; // guarda a soma dos dois numeros

System.out.print( "Entre com o primeiro numero: " ); // mostra o prompt


num1 = entrada.nextInt(); // le o primeiro numero informado pelo usuario

System.out.print( "Entre com o segundo numero: " ); // prompt


num2 = entrada.nextInt(); // le o segundo numero informado pelo usuario

soma = num1 + num2; // soma os dois numeros

System.out.printf( "A soma é %d\n", soma ); // mostra soma


} // sim do metodo main
} // fim da classe
Primeiros Exemplos cap. 2
Operação Java Operador Aritmético Expressão Java
Adição + F+7
Subtração - P–C
Multiplicação * K*3
Divisão / X/Y
Resto % 7%2
Primeiros Exemplos cap. 2
import java.util.Scanner;
public class Comparacao
{
public static void main( String args[] )
{
Scanner entrada = new Scanner( System.in );
int num1, num2;

System.out.print( "Entre com o primeiro numero: " );


num1 = entrada.nextInt();
System.out.print( "Entre com o segundo numero: " );
num2 = entrada.nextInt();

if ( num1 == num2 )
System.out.printf( "%d == %d\n", num1, num2 );
if ( num1 != num2 )
System.out.printf( "%d != %d\n", num1, num2 );
if ( num1 < num2 )
System.out.printf( "%d < %d\n", num1, num2 );
if ( num1 > num2 )
System.out.printf( "%d > %d\n", num1, num2 );
if ( num1 <= num2 )
System.out.printf( "%d <= %d\n", num1, num2 );
if ( num1 >= num2 )
System.out.printf( "%d >= %d\n", num1, num2 );
} }//fim do main e depois fim da classe
Primeiros Exemplos cap. 2
Padrão Operador de Exemplo de Significado da
Algébrico Igualdade ou Condição em Condição em Java
operador de relacional Java
igualdade ou em Java
relacional
Operadores de Igualdade
= == X == Y X é igual a Y
≠ != X != Y X é diferente de Y
Operadores Relacionais
> > X>Y X é maior que Y
< < X<Y X é menor que Y
≥ >= X >= Y X é maior ou igual que Y
≤ <= X <= Y X é maior ou igual que Y
Instruções de controle – parte I cap. 4
//----------------------------------------------------------------------------------
if (nota >= 90)
System.out.println(“A”);
else if (nota >= 80)
System.out.println(“B”);
else if (nota >= 70)
System.out.println(“C”);
else if (nota >= 60)
System.out.println(“D”);
else System.out.println(“F”);
//----------------------------------------------------------------------------------
If (x>5)
if (y>5)
System.out.println(“x e y é maior que 5”);
else (“quando vai executar esta instrução?”)
//----------------------------------------------------------------------------------
if (nota >= 60)
System.out.println(“Aprovado”);
else {
System.out.println(“Reprovado”);
System.out.println(“Vai ter que repetir a disciplina”);
}
//----------------------------------------------------------------------------------
Instruções de controle – parte I cap. 4
//----------------------------------------------------------------------------------
int contador = 0;
while (contador < 10){
System.out.printf(“O valor é: %d”,contador);
contador = contador + 1; // ++contador; ou contador += 1;
}
//----------------------------------------------------------------------------------
booblean chave = true;
while (chave)
calcular_Soma(); //chama uma função;
//----------------------------------------------------------------------------------
int estudantes, aprovado, reprovavdo;
estudantes = 0;
while (estudantes < 10){

Scanner entrada = new Scanner(System.in);


nota = entrada.nextInt();

if (nota >= 60)


aprovado = aprovado + 1; //ou aprovado += 1; ou ++aprovado
else reprovado = reprovado + 1; // ou reprovado += 1; ou ++reprovado

++estudantes;
}
//----------------------------------------------------------------------------------
Instruções de controle – parte I cap. 4
Operador de Expressão de Explicação Atribuições
atribuição exemplo
Suponha: int c = 3, d = 5, e = 4, f = 6, g = 12;
+= c += 7 c=c+7 10 à variável c
-= d -= 4 d=d–4 1 à variável d
*= e *= 5 e=e*5 20 à variável e
/= f /= 3 f=f/3 2 à variável f
%= g %= 9 g=g%9 3 à variável g
Instruções de controle – parte I cap. 4
public class Incremento{

public static void (String[] args){

int c;

c = 5;
System.out.println(c);
System.out.println(c++);
System.out.println(c);

System.out.println();

c = 5;
System.out.println(c);
System.out.println(++c);
System.out.println(c);
}
}
Instruções de controle – parte I cap. 4
Operador Chamado Expressão Explicação
de
exemplo
++ pré-incremento ++a Incrementa “a” em 1 e então utiliza
o novo valor de “a” na expressão
em que “a” reside
++ pós-incremento a++ Utiliza o valor atual de “a” na
expressão em que “a” reside,
então incrementa “a” por 1
-- pré-incremento --a Decrementa “a” em 1 e então
utiliza o novo valor de “a” na
expressão em que “a” reside

-- pós-incremento a-- Utiliza o valor atual de “a” na


expressão em que “a” reside,
então decrementa “a” por 1
Instruções de controle – parte II cap. 5
//repetição controlada por contador com a instrução de repetição while

public class WhileContador


{
public static void main( String args[] )
{
int contador = 1; // declara e inicializa a variável

while ( contador <= 10 ) // condição de continuação do loop


{
System.out.printf( "%d ", counter );
++contador; // incrementa a variável de contole por 1
} // fim do while

System.out.println(); // linha em branco


} // fim do main
} // fim da classe
Instruções de controle – parte II cap. 5
//repetição controlada por contador com a instrução de repetição for

public class ForContador


{
public static void main( String args[] )
{
// cabeçalho da intrção for inclui inicialização
// condição de continuação do loop e incremento

for ( int contador = 1; contador <= 10; contador++ )


System.out.printf( "%d ", contador );

System.out.println();
}
}
Instruções de controle – parte II cap. 5
Instruções de controle – parte II cap. 5
Exemplos:

X = 2; y= 10;
for (int j = x; j <= 4 * x * y; j += y / x ) equivale a for (int j = 2; j <= 80; j += 5)

for (int i = 7; i <= 77; i +=7)


Varia a variável de 7 a 77 em incrementos de 7

for (int i = 100; i >= 1; i- -)


Varia a variável de controle de 100 a 1 em incrementos de 1

for (int i = 20; i>=2; i -= 2)


Varia a variável de controle de 20 a 2 em decrementos de 2

for (int i = 99; i >= 0; i -= 11)


Varia a variável de controle sobre na seqüência 99, 88, 77, 66, 55, 44, 33, 22, 11, 0
Instruções de controle – parte II cap. 5
//Instrução de repetição do.....while
public class DoWhile
{
public static void main( String args[] )
{
int contador = 1; // inicializa o contador

do
{
System.out.printf( "%d ", contador );
++contador;
} while ( contador <= 10 ); // fim do commando do...while

System.out.println(); // imprime uma linha em branco


} // fim do metodo main
} // fim da classe
Instruções de controle – parte II cap. 5
switch ( curso )
{
case 1: //o que acontece se não tiver o break???
++aCont;
break;

case 2:
++bCont;
break;

case 3:
case 4:
case 5:
++cCont;
break;

default:
System.out.println("Opção Inválida");
break;
} // fim do switch
Instruções de controle – parte II cap. 5
public class UsandoBreak
{
public static void main( String args[] )
{
int cont;

for ( cont = 1; cont <= 10; cont++ ) // rodas 10 vezes


{
if ( cont == 5 )
break; // termina o loop

System.out.printf( "%d ", cont );


}

System.out.printf( "%d\n", cont );


}
}
Instruções de controle – parte II cap. 5
public class UsandoContinue
{
public static void main( String args[] )
{
for ( int cont = 1; cont <= 10; cont++ ) // roda 10 vezes
{
if ( cont == 5 )
continue;

System.out.printf( "%d ", cont );


}

System.out.println( "\nNão imprime o 5" );


}
}
Instruções de controle – parte II cap. 5
Operações lógicas

• OU (OR) ||

• E (AND) &&

• NÃO (NOT) !

• OU-EXCLUSIVO (XOR) ^

Exercitando...
Crie um algoritmo para simular um “login” de banco. O usuário deve entrar com
3 letras (na seqüência correta) e caso estas letras estejam corretas, ele
deve informar uma senha com 4 letras.
Exemplo: letras: A – C – E
numero: 5674
Exercício 01
1. Leia um número e exiba seu sucessor.
2. Calcular a média final, dadas as notas das 3 provas e produzir uma saída com a
média e a situação do aluno de acordo com o seguinte critério: média >= 7,
aprovado; 5 < média < 7, recuperação; média < 5, reprovado.
3. Ler dois números inteiros, x e y, e imprimir o quociente e o resto da divisão inteira
entre eles.
4. Ler dois valores reais do teclado, calcular e imprimir na tela:
a) A soma destes valores b) O produto deles c) O quociente entre eles
5. Para ler 3 números reais do teclado e verificar se o primeiro é maior que a soma
dos outros dois.
6. Ler um nome do teclado e ver se é igual ao seu nome. Imprimir conforme o caso:
“NOME CORRETO” ou “NOME INCORRETO”.
7. Leia a velocidade máxima permitida em uma avenida e a velocidade com que o
motorista estava dirigindo nela e calcule a multa que uma pessoa vai receber,
sabendo que são pagos: a) 50 reais se o motorista estiver ultrapassar em até
10km/h a velocidade permitida (ex.: velocidade máxima: 50km/h; motorista a
60km/h ou a 56km/h); b) 100 reais, se o motorista ultrapassar de 11 a 30 km/h a
velocidade permitida. c) 200 reais, se estiver acima de 31km/h da velocidade
permitida.
Exercício 02
1. Faça um algoritmo que escreva na tela os números de 0 a 50. usando um for; de
51 a 100 usando um while e, de 101 até 150 usando um repeat.
2. Faça um algoritmo que escreva na tela os números pares de 0 a 30.
3. Faça um programa que lê “X” números e conta quantos são negativos .
Criação de Métodos cap. 5
O que é?
Métodos são trechos de código que permitem modularizar um sistemas, isto é,
são pequenos blocos que, juntos, compõem um sistema maior. Os métodos
recebem um determinado nome e podem ser chamados várias vezes
durante a execução de uma classe, ou seja, é uma sub-rotina que pode ser
invocada sempre que necessário.

Motivos?
Redução do tamanho total de código de um sistema, melhoria da
modularização do sistema ( cada trecho de código realiza uma tarefa) e a
facilitação e agilização do processo de manutenção.
Obs.:
Um bom método deve ser auto-suficiente, ou seja possui internamente todas
as definições (variáveis) necessárias para seu funcionamento.

Exemplo:
1) O programador precisa de validar a data informada pelo usuário em
diversas partes do programa.
2) O programador precisa de validar o CPF informado pelo usuário em
diversas partes do programa.
Hipótese: o dono da empresa pediu para mudar a mensagem de validação de data ou, caso o governo mude a forma
de validar um CPF, qual o trabalho para o desenvolvedor alterar o sistema com e sem métodos?
Criação de Métodos (cont.) cap. 5
Estrutura de um método em Java:
qualificador tipo-do-retorno nome-do-metodo ([Lista de argumentos])
{
códigos do corpo
}
qualificador – define a visibilidade do método (maiores detalhes nas próximas
aulas.)

tipo-de-retorno – refere-se ao tipo de dado retornado pelo método. Métodos


que não retornam valores devem possuir nesse parâmetro a palavra void.
Sempre que void for usada em uma declaração de método, nenhum valor
será retornado após sua execução, isto é, o método atuará como uma
‘procedure’ de outras linguagens de programação. Um método pode ter
como retorno qualquer tipo primitivo (int, float, etc.), um vetor ou ainda um
objeto qualquer.

nome-do-metodo – pode ser qualquer palavra ou frase, desde que ininciada


por uma letra. Se o nome for uma frase, não podem existir espaços em
branco entre as palavras. É importante dar aos métodos nomes sugestivos,
ou seja, nomes que indicam a tarefa executada pelo método.
Criação de Métodos (cont.) cap. 5
lista-de-argumento – trata-se de uma lista de variáveis opcionais, que podem
ser recebidas pelo método para tratamento interno. Quando um método é
invocado, ele pode receber valores de quem o chamou. Esses valores
podem ser manipulados internamente e devolvidos ao emissor da
solicitação. Um mesmo método pode receber diferentes tipos de variáveis,
desde tipos primitivos até objetos complexos.

código do corpo – trata-se dos códigos em Java que realizam os processos


internos e retornam os valores desejados, isto é, constituem o programa do
método.

O tipo de retorno, o nome do método e a lista de argumentos formam a


assinatura do método, algo que o identifica de maneira única. Toda vez
que um método for invocado a assinatura deverá ser obedecida.

Exemplo de métodos:
System.out.Println(“valor do parâmetro”); // método chamado Println que tem
como argumento um valor do tipo String.
Criação de Métodos (cont.) cap. 5
Exemplo de métodos sem retorno:

public void imprimeUmaLinha ()


{
System.out.Println(“====================”);
}

public void imprimeVariasLinha (int qtdeLinhas)


{
int i = 1;
while (i <= qtdeLinhas)
{
System.out.Println(“====================”);
i += 1;
}
}
Criação de Métodos (cont.) cap. 5
Exemplo de métodos com retorno:

public String nomeDoAluno ()


{
return “Tião José Silva”
}

public int areaDoQuadrado(int base, int altura)


{
float area = 0;
area = base * altura;
return area
}
Exercício 03
1. Refaça os exercícios da listagem 01 (Exercício 01) seguindo as regras abaixo:

a) Os exercícios deverão ser refeitos em uma única classe (arquivo) utilizando


métodos. Faça uso de um menu com uma estrutura CASE para que o usuário
escolha qual exercício ele deseja executar.

b) Todo o processamento deverá ser feito dentro dos métodos.

c) Os métodos não devem conter objetos Scanner e/ou System. Ou seja, a entrada e
a exibição de dados (mensagens) deverão ser feitas fora dos métodos.
Documentando os
métodos/classes
• Documentar pontos estratégicos de nossos códigos fontes, é
uma necessidade universal;

• Em Java existe um recurso do próprio JDK, que facilita todo o


trabalho de criação e manipulação dos comentários, essa
ferramenta não poderia ter um nome mais sugestivo, estamos
falando do JavaDoc;
• Seu funcionamento baseia-se na inserção de textos
explicativos em forma de um comentário especial, que
antecedem um escopo de uma classe ou método, tendo
assim, a responsabilidade de apresentar o mesmo;
• O documento é gerando em formato html.
Documentando os
métodos/classes
Primeiro passo: crie os comentários no código seguindo
exatamente a sintaxe abaixo:
Insira os comentários
antes dos métodos ou
classes
Documentando os
métodos/classes
Segundo passo: use tags especiais a fim de qualificar
melhor a informação contida nos comentários
Documentando os
métodos/classes
Tag Significado
@author Especifica o autor da classe ou do método em questão.
@deprecated Identifica classes ou métodos obsoletos
@link Possibilita a definição de um link para um outro documento
local ou remoto através de um URL.
@param Mostra um parâmetro que será passado a um método.
@return Mostra qual o tipo de retorno de um método.
@see Possibilita a definição referências de classes ou métodos, que
podem ser consultadas para melhor compreender idéia
daquilo que está sendo comentada.
@since Indica desde quando uma classe ou métodos foi adicionado
na aplicação.
@throws Indica os tipos de exceções que podem ser lançadas por um
método.
@version Informa a versão da classe.
Documentando os
métodos/classes
Terceiro passo: automatizando a geração do documento no
Eclipse acessando o menu: “Project > Generate Javadoc...”

a) Informa o caminho do
arquivo javadoc.exe

b) Escolha o projeto a
ser documentado

c) Escolha a pasta
destino da documenta e
clique em “Next”
Documentando os
métodos/classes
Quarto passo: clique no botão “Finish” e acesse os
documentos em um browser

d) Escolha o que deve


ser documentado
Introdução a Classes e Objetos cap. 3
Desde criança representamos nosso
conhecimento através de classificações e
abstrações. Ex: Carro, Pessoas.
Sendo que cada objeto pertence a um
determinado grupo possuindo as mesmas
características e comportamentos. Quando
falamos de carro, todos conseguem abstrair o
que é um carro.
Existem vários tipos de carros com características
diferentes, mas quando pegamos um carro
especifico estamos instanciando um objeto da
mesma classe.
Introdução a Classes e Objetos cap. 3
Quando estamos instanciando um objeto de uma
classe, estamos criando um novo item do
conjunto representado por esta classe.
Apesar de um objeto possuir as mesmas
propriedades que os objetos da classe, este
objeto possui valores diferentes para um objeto.
Ex: cor de um carro, número de portas do carro,
número da placa.
Introdução a Classes e Objetos cap. 3
Instanciando um objeto
Introdução a Classes e Objetos cap. 3
• Para cada necessidade importante teremos objetos que interagem entre
si e que são compostos por estado (atributos) e comportamento
(métodos), ao contrário do paradigma procedural. Quer um exemplo?
Observe como estamos representando o preço dos livros:

O valor 59.90 está fazendo isso. Ele representa o valor do livro; mas, e
quanto ao seu nome, descrição e demais informações? Todas essas
informações representam o que um livro tem e são extremamente
importantes para nosso sistema. O grande problema do paradigma
procedural é que não existe uma forma simples de conectar todos esses
elementos
Introdução a Classes e Objetos cap. 3
• A conexão dos dados fica mais intuitiva/natural se cada objeto guardar
seus próprios dados.
Introdução a Classes e Objetos cap. 3
Vantagens e objetivos da OO:
• Natural
• Confiável
• Reutilizável
• Manutenível
• Extensível
• Oportuna
Introdução a Classes e Objetos cap. 3
Natural
A POO produz software natural. Os programas naturais são mais inteligíveis.
Em vez de programar em termos de regiões de memória, você pode
programar usando a terminologia de seu problema em particular. Você não
precisa se aprofundar nos detalhes do computador enquanto projeta seu
programa. Em vez de ajustar seus programas para a linguagem do mundo
dos computadores, a OO o libera para que expresse seu programa nos
termos de seu problema.
A programação orientada a objetos permite que você modele um problema em
um nível funcional e não em nível de implementação. Você não precisa
saber como um software funciona, para usá-lo: você simplesmente se
concentra no que ele faz.
Introdução a Classes e Objetos cap. 3
Confiável
Para criar software útil, você precisa criar software que seja tão confiável
quanto outros produtos, como geladeiras e televisões. Quanto foi a última
vez que seu microondas quebrou?
Programas orientados a objetos, bem projetados e cuidadosamente escritos
são confiáveis. A natureza modular dos objetos permite que você faça
alterações em uma parte de seu programa, sem afetar outras partes. Os
objetos isolam o conhecimento e a responsabilidade de onde pertencem.
Uma maneira de aumentar a confiabilidade é através de testes completos. A
OO aprimora os testes, permitindo que você isole conhecimento e
responsabilidades em um único lugar. Tal isolamento permite que você
teste e valide cada componente independentemente. Uma vez que tenha
validado um componente, você pode reutilizá-lo com confiança.
Introdução a Classes e Objetos cap. 3
Reutilizável
Um construtor inventa um novo tipo de tijolo cada vez que constrói uma casa?
Então, por que os programadores continuam “reinventando a roda”? Uma
vez que o problema esteja resolvido, você deve reutilizar a solução.
Você pode reutilizar prontamente classes orientadas a objetos bem feitas.
Assim como os módulos, você pode reutilizar objetos em muitos programas
diferentes. Ao contrário dos módulos, a POO introduz a herança para
permitir que você estenda objetos existentes e o polimorfismo, para que
você possa escrever código genérico.
A OO não garante código genérico. Criar classes bem feitas é uma tarefa difícil
que exige concentração e atenção à abstração. Os programadores nem
sempre acham isso fácil.
Através da POO, você pode modelar idéias gerais e usar essas idéias gerais
para resolver problemas específicos. Embora você vá construir objetos
para resolver um problema específico, freqüentemente construirá esses
objetos específicos usando partes genéricas.
Introdução a Classes e Objetos cap. 3
Manutenível
O ciclo de vida de um programa não termina quando você o distribui. Em vez
disso, você deve manter sua base de código. Na verdade, entre 60% e
80% do tempo gasto trabalhando em um programa é para manutenção. O
desenvolvimento representa 20% da equação!
Um código orientando a objetos bem projetado é manutenível. Para corrigir um
erro, você simplesmente corrige o problema em um lugar. Como uma
mudança na implementação é transparente, todos os outros objetos se
beneficiarão automaticamente do aprimoramento. A linguagem natural do
código deve permitir que outros desenvolvedores também o entendam.
Introdução a Classes e Objetos cap. 3
Extensível
Assim como você deve manter um sistema. Seus usuários exigem o acréscimo
de nova funcionalidade em seu sistema. Quando você construir uma
biblioteca de objetos, também desejará estender a funcionalidade de seus
próprios objetos.
A POO trata dessas realidades. O Software não é estático. Ele deve crescer e
mudar com o passar do tempo, para permanecer útil. A POO apresenta ao
programador vários recursos para estender código. Esses recursos incluem
herança, polimorfismo, sobreposição, delegação e uma variedade de
padrões de projeto.
Introdução a Classes e Objetos cap. 3
Oportuna
O ciclo de vida do projeto de software moderno é freqüentemente medido em
semanas. A POO ajuda nesses rápidos ciclos de desenvolvimento. A POO
diminui o tempo do ciclo de desenvolvimento, fornecendo software
confiável, reutilizável e facilmente extensível
O software natural simplifica o projeto de sistemas complexos. Embora você
não possa ignorar o projeto cuidadoso, o software natural pode otimizar os
ciclos de projeto, pois você pode se concentrar no problema que está
tentando resolver.
Quando você divide um programa em vários objetos, o desenvolvimento de
cada parte pode ocorrer em paralelo. Vários desenvolvedores podem
trabalhar nas classes independentemente. Tal desenvolvimento em
paralelo leva a tempos de desenvolvimento menores.
Introdução a Classes e Objetos cap. 3
Geralmente uma determinada classe possui
não apenas suas propriedades
(características). Ela possui obrigações
(afazeres), que são conhecidos como
métodos ou mensagens.

Carro Nome da classe


REPRESENTAMOS
cor: String Propriedades
UMA CLASSE nº Portas : int

PELO SÍMBOLO: andar(); Métodos


freiar();
Introdução a Classes e Objetos cap. 3
Classe – é um tipo de dados definido pelo
usuário, que tem um estado(propriedades)
e algumas operações(procedimentos e
função)

Objeto – é uma instância de uma classe, os


objetos são entidades reais, que ocupam
espaça de memória.
Exemplo 01
public class CadernoNotas01 {

// mostra uma mensagem de boas vindas com o nome do curso


public void mostraMenssagem(String nomeCurso)
{
System.out.printf( "Bem vindo ao caderno de notas!\n%s!\n",
nomeCurso );
} // fim do método

} // fim da classe
Exemplo 01 cont.
import java.util.Scanner;
//objetivo: passar valores para os metodos por parametro
public class CadernoNotasPrincipal01 {

public static void main(String[] args) {

// Cria um scanner para entrada dos dados


Scanner entrada = new Scanner( System.in );

// cria um novo objeto da classe Caderno de Notas


CadernoNotas01 meuCaderno = new CadernoNotas01();

System.out.println( "Entre com o nome do curso:" );


String cursoNome = entrada.next();
System.out.println(); // linha em branco

// chama o metodo passando o nome do curso


meuCaderno.mostraMenssagem( cursoNome );
}
}
Exercitando...
1. Criar uma nova classe Java chamada Livro com os seguintes atributos: nome,
descrição e isbn do tipo string, valor do tipo double.
2. Criar uma instância dessa classe para receber os dados de um livro.
3. Imprima na tela os dados do livro.
4. Criar outra instância dessa classe para receber os dados de outro livro.
5. Imprima na tela os dados desse segundo livro.
6. Crie um método para Imprimir os dados dos livros dentro da classe.
7. Responda a pergunta: Qual a melhor opção para a impressão dos dados?

8. Agora crie campos para receber os dados dos autores: nome, email e CPF.
9. Insira os dados do mesmo autor para os dois livros.
10. Responda a pergunta:
Você consegue imaginar alguma solução melhor para informar esses dados?
Como?
Concluindo...

Mais uma pergunta: dois objetos da mesma classe podem ser comparados
da seguinte forma: if (livro1 == livro2) ???
Os três pilares da POO
• Para edificar seu entendimento e domínio de OO, você
deve primeiro ter uma base sólida a partir da qual possa
expandir sua compreensão. Primeiro, você precisará
identificar, definir e explorar os conceitos básicos de
OO. Tal discussão o leva naturalmente aos três
conceitos que devem estar presentes para que uma
linguagem seja considerada realmente orientada a
objetos.

• Os três pilares são:


1. Encapsulamento
2. Herança
3. Polimorfismo
Encapsulamento cap. 3
• Encapsulamento é a característica da OO de ocultar
partes independentes da implementação. O
encapsulamento permite que você construa partes
ocultas da implementação do software, que atinjam uma
funcionalidade e ocultam os detalhes de implementação
do mundo exterior.
• Uma vez encapsulado, você pode ver uma entidade de
software como uma caixa preta. Você sabe o que a
caixa preta faz, pois conhece sua interface externa.
Você não se preocupa com o que está acontecendo
dentro da caixa; você só se preocupa com o fato de que
isso aconteça.
Encapsulamento cap. 3
Uma interface lista os serviços fornecidos por um
componente (classe). A interface é um contrato com o
mundo exterior, que define exatamente o que uma
entidade externa pode fazer com o objeto. Uma interface
é o painel de controle do objeto.

Interface
Interface

Interface
Mensagem
? Mensagem

Interface
Encapsulamento – Exemplo de
interface e implementação cap. 3
A interface pública é:
public void debug( String mensagem)
public void info( String mensagem)
public void aviso( String mensagem)
public void erro( String mensagem)
public void erroGrave( String mensagem)

Atenção:
A interface diz o que deve ser feito, mas não
diz como. O responsável por isso é a
implementação (Ex.: O log poderia ser salvo
em um arquivo texto ou enviado por email).

Você notou que a interface pública não inclui o método


private void print(String tipo, String mensagem) ???
Encapsulamento cap. 3
• O que aparece e o que não aparece na interface pública
é governado por diversas palavras-chave existentes nas
linguagens de programação OO, mas fundamentalmente
essas palavras acabam tendo efeitos semelhantes:

• Público (public) – garante o acesso a todos os objetos.


• Protegido (protected) – garante o acesso à instância, ou
seja, para aquele objeto, e para todas as subclasses
(mais detalhes nas próximas aulas).
• Privado (private) – garante o acesso apenas para a
instância, ou seja para aquele objeto.
Encapsulamento – Por que
usar? cap. 3
Quando usado cuidadosamente, o encapsulamento
transforma seus objetos em componentes plugáveis.
Para que outro objeto use seu componente, ele só
precisa saber como usar a interface pública do
componente. Tal estratégia tem três vantagens:

1. Independência: significa que você pode reutilizar o


objeto em qualquer parte. Quando você encapsular
corretamente seus objetos, eles não estarão vinculados
a nenhum programa em particular. Em vez disso, você
pode usá-los sempre que seu uso fizer sentido. Para
usar o objeto em qualquer lugar, você simplesmente
exerce sua interface
Encapsulamento – Por que
usar? cap. 3
2. O encapsulamento permite que você torne transparente
as alterações em seu objeto. Desde que você não
altere sua interface, todas as alterações permanecerão
transparentes para aqueles que estiverem usando o
objeto. O encapsulamento permite que você atualize
seu componente, forneça uma implementação mais
eficiente ou corrija erros. Os usuários de seu objeto se
beneficiarão automaticamente de todas as alterações.

3. Usar um objeto encapsulado não causará efeitos


colaterais inesperados entre o objeto e o restante do
programa. Como o objeto tem implementação
independente, ele não terá nenhuma outra interação
com o restante do programa, além da interface.
Encapsulamento – Abstração
cap. 3
Abstração é o processo de simplificar um problema difícil.
Quando começa a resolver um problema, você não se
preocupa com cada detalhe. Em vez disso, você
simplifica , tratando apenas dos detalhes pertinentes a
uma solução (ex. simulador de tráfego).

A Abstração tem duas vantagens:


1. Ela permite que você resolva um problema facilmente.
2. Mais importante, a abstração o ajuda a obter
reutilização. Quando possível, você deve se esforçar
para criar objetos que possam resolver um domínio
inteiro de problema. Ex. Um software para um fila de
banco e um software de fabricação de sanduíches.
Entrada Saída
Encapsulamento – Ocultação da
Implementação cap. 3
Duas vantagens:
1. Protege seu objeto de seus usuários.

O que aconteceria se o usuário atribuísse um valor negativo para o


campo preço unitário?
Encapsulamento – Ocultação da
Implementação cap. 3
Duas vantagens:
2. Protege os usuários de seu próprio projeto

A ocultação da implementação leva a um projeto mais


flexível, pois ela impede que os usuários de seus
objetos se tornem fortemente acoplados à
implementação subjacente dos objetos. Então, não
apenas a ocultação da implementação projete seus
objetos, como também protege aqueles que usam seus
objetos, estimulando um código fracamente acoplado

• O código fracamente acoplado é independente da


implementação de outros componentes
• O código fortemente acoplado é fortemente vinculado à
implementação de outros componentes.
Encap. -Responsabilidade cap. 3
Divisão da responsabilidade correta significa que cada objeto
deve executar uma função – sua responsabilidade – e
executá-la bem.

Ter de chamar várias variáveis para calcular o total ajustado,


retira a responsabilidade da classe “NaoEncapsulado” e a
coloca nas mãos do programador. O código pode ter
responsabilidade duplicada.
Exemplo 02
//Objetivo:entendimento de private e public, o uso de métodos set e get
public class CadernoNotas02 {

private String cursoNome; // variável de instancia

// metodo para setar o valor de nomeCurso


public void setCursoNome( String nome )
{// armazena o valor passando
cursoNome = nome; }

// recupera o valor armazenado


public String getCursoNome()
{
return cursoNome; }

// mostra a mensagem para o usuario


public void mostraMenssagem()
{
// mostra a mensagem e usa o metodo getNomeCurso para buscar o valor
System.out.printf( "Bem vindo ao caderno de notas\n%s!\n", getCursoNome() );
} }
Exemplo 02 cont.
import java.util.Scanner;
public class CadernoNotasPrincipal02 {

public static void main(String[] args) {

// Cria um scanner para entrada dos dados


Scanner entrada = new Scanner( System.in );

// cria um novo objeto da classe Caderno de Notas


CadernoNotas02 meuCaderno = new CadernoNotas02();

System.out.println( "Valor inicial do curso:" );


System.out.println( meuCaderno.getCursoNome() );

System.out.println( "Entre com o nome do curso:" );


String cursoNome = entrada.next();
//chama o método para setar o valor da variavel cursoNome da classe
meuCaderno.setCursoNome(cursoNome);

meuCaderno.mostraMenssagem(); // chama o metodo passando o nome do curso


} }
Exercitando...
Vamos continuar nosso exemplo de livro
1. O usuário pode receber descontos nos livros, mas esses descontos não
podem ultrapassar os 30%. Implemente uma solução para essa regra de
negócio.
2. O nome dos livros não podem ser menor que dois caracteres. Assim,
implemente a regra de negócio para isso também.
3. Responda a pergunta: Você usou algum conceito de OO na sua
solução? Qual? Existem vantagens?
Construtores cap. 3
• Um construtor é um método que serve
para inicializar variáveis, instanciar objetos
ou dar uma ação inicial ao objeto.
• Toda classe tem seu construtor, pois o
compilador fornece este construtor sem
parâmetros.
• O construtor mais a palavra reservada
“new” aloca espaço de memória para o
novo objeto.
Exemplo
//Objetivo: uso de construtores
03
public class CadernoNotas3 {

private String cursoNome; // variavel de instância

// construtor, para inicializar variável e alocar espaço de memoria


public CadernoNotas3( String nome )
{
cursoNome = nome; }

public void setCursoNome( String nome )


{//metodo para setar a varavel de instancia
cursoNome = nome; }

public String getCursoNome()


{// metodo para buscar o valor da variavel de instancia
return cursoNome; }

public void mostraMenssagem()


{
System.out.printf( "Bem vindo ao caderno de notas\n%s!\n", getCursoNome());
} }
Exemplo 03 cont.
public class CadernoNotas3Principal {

public static void main(String[] args) {

// cria dois objetos CadernoNotas3


CadernoNotas3 caderno1 = new CadernoNotas3(
"Introduçaõ a java" );
CadernoNotas3 caderno2 = new CadernoNotas3(
"Matematica" );

// mostra o nomes dos dois curso (2 obejtos)


System.out.printf( "O nome do primeiro curso: %s\n",
caderno1.getCursoNome());
System.out.printf( "O nome do segundo curso: %s\n",
caderno2.getCursoNome());

}
Exercício
Crie a estrutura abaixo. Logo em seguida, em uma classe com o método “main”, crie 2
objetos do tipo Piloto e 2 objetos do tipo CoPiloto. Preencha todas as informações
para estes objetos e chame o método imprimir de cada objeto mostrando os dados no
console.

Atenção:
Na criação dos
dois objetos, crie
o primeiro com o
construtor sem
parâmetro e o
segundo com o
construtor com
parâmetros.
Uso de caixas de diálogo cap. 3
• A linguagem java tem uma grande capacidade
para desenvolvimento de aplicativos com
interface gráfica (GUIs – graphical user
interfaces).
• Nosso primeiro contato com os GUIs serão
feitos pelas caixas de diálogo para exiber a
saída e recuperar informações de entrada dos
usuários.
• A classe JOptionPane fornece caixas de
diálogos pré-empacotadas que permitem aos
programas exibir janelas para os usuários.
Uso de caixas de diálogo cap. 3
Uso de caixas de diálogo cap. 3
Uso de caixas de diálogo cap. 3
Exemplo 01
//Objetivo: CAIXAS DE DIÁLOGO
// importa a classe JOptionPane
import javax.swing.JOptionPane;

public class Dialogo01 {

public static void main( String args[] )


{
String str;
str = "Bem vindo\n ao\n programa";

JOptionPane.showMessageDialog(null, str );

//termina o aplicativo de forma correta


//passando como parâmetro 0, se outro
//valor for passado indica erro.
//OBS: todo software em java com GUI deve
//ser terminado com esta linha.
System.exit( 0 );
}
}
Uso de caixas de diálogo cap. 3
Exemplo
import javax.swing.JOptionPane;
02
public class Dialogo02 {
public static void main( String args[] )
{ String sNum1,sNum2;
int num1,num2,soma;

// pede ao usuario o primeiro numero


sNum1 = JOptionPane.showInputDialog( "Primeiro Número" );
// pede ao usuario o primeiro numero
sNum2 = JOptionPane.showInputDialog( "Segundo Número" );

// converte de string para inteiro


num1 = Integer.parseInt( sNum1 );
num2 = Integer.parseInt( sNum2 );

// soma as variáveis inteiras


soma = num1 + num2;

// mostra o resultado
JOptionPane.showMessageDialog(null, "A soma é " + soma);
System.exit( 0 );
} }
Exemplo 03
import javax.swing.JOptionPane;
public class Dialogo03 {
public static void main( String args[] )
{ String sNum1,sNum2;
int num1,num2,subtracao;

// pede ao usuario o primeiro e segundo múmero


sNum1 = JOptionPane.showInputDialog( "Primeiro Número" );
sNum2 = JOptionPane.showInputDialog( "Segundo Número" );

// converte de string para inteiro


num1 = Integer.parseInt( sNum1 );
num2 = Integer.parseInt( sNum2 );

// soma as variáveis inteiras


subtracao = num1 - num2;

// mostra o resultado
JOptionPane.showMessageDialog(null, "A diferença é " + subtracao,
"Subtração",JOptionPane.WARNING_MESSAGE);

System.exit( 0 );
} }
Uso de caixas de diálogo cap. 3
Tipos de mensagens
Uso de caixas de diálogo cap. 3
Uso de caixas de diálogo cap. 3
Uso de caixas de diálogo cap. 3
Uso de caixas de diálogo cap. 3
Uso de caixas de diálogo cap. 3
Métodos um exame mais profundo
cap. 6

Sobrecarga de método – Overload

Os métodos com o mesmo nome podem ser declarados na


mesma classe, contanto que tenham diferentes
conjuntos de parâmetros (determinados pelo numero,
tipos e ordem dos parâmetros).
Quando um método sobrecarregado é chamado, o
compilador Java seleciona o método adequado
examinando o número, os tipos e a ordem dos
argumentos na chamada.
A sobrecarga de métodos é comumente utilizada para criar
vários métodos com o mesmo nome que realizam as
mesmas tarefas. Ex: println(int ou double ou boolean)
Exemplo 01
public class QuadradoComSobrecarga {

public void testaSobrecarga(){

//chama o metodo sobrecarregado com inteiro e com double


System.out.println("O quadrado de 7 é " +numeroAoQuadrado(7));
System.out.println("O quadrado de 7.5 é " +numeroAoQuadrado(7.5));
}

public int numeroAoQuadrado(int numero){

return numero*numero;
}

public double numeroAoQuadrado(double numero){

return numero*numero;
}

}
Exemplo 01 continuação
//a classe principal chama(executa) a classe QuadradoComOverload
public class QuadradoComOverloadPrincipal {

public static void main(String[] args) {

QuadradoComSobrecarga q = new QuadradoComSobrecarga();


q.testaSobrecarga();
}

}
Arrays(vetor) cap. 7
Array é um grupo de variáveis que contém valores que são
todos do mesmo tipo
Para referenciarmos um elemento particular em um array,
especificamos o nome da referência para o array e o
número da posição do elemento no array.

O array começa da posição zero e vai até


N-1 com N sendo o tamanho do array
Arrays(vetor) cap. 7
Declarando e criando array
Os arrays são objetos que ocupam espaço de memória,
logo devem ser criados(new)
Array de inteiros Array de string
int c[] = new int[12]; String c[] = new String[12];
ou ou
int c[]; String c[];
c = new int[12]; c = new String [12];
Mais de um array pode ser declarado em uma linha da
seguinte forma:
Ex. double[] array1, array2; que é igual a: double array1[];
double array2[];
Arrays(vetor) cap. 7
Declarando e criando array (cont.)
Um programa pode criar um array e inicializar seus elementos com um
inicializador de array

int n[] = {10, 20, 65, 5, 99}

Neste caso o array foi criado com tamanho 5 e seus valores podem ser
acessados pelos seus indices. Por exempo:
o valor 10 pode ser acessado com: n[0]
o valor 20 pode ser acessado com: n[1]
o valor 65 pode ser acessado com: n[2]
o valor 5 pode ser acessado com: n[3]
o valor 99 pode ser acessado com: n[4]
public class Array {
Exemplo 01
public static void main(String[] args) {

int vetorA[]; //declara um vetor de inteiros


String vetorB[] = new String[5]; //declara e cria um vetor de string
double[] vetorC, vetorD; //decaração de 2 vetores em uma linha
int vetorE[] = {11, 28, 9, 55, 6};//lista de iniciadores especificando os valores e tamanho;
//------------------------------------------------
//cria o vetor declarado com 3 posições de 0 a 2.
vetorA = new int[3];

for (int i = 0; i<=2; i++){


vetorA[i] = i+5;
System.out.printf("vetorA[%d] é igual a %d\n",i,vetorA[i]);
}
System.out.println();
//------------------------------------------------
//usa o vetor que ja estava criado
vetorB[0] = "B";
vetorB[1] = "R";
vetorB[2] = "U";
vetorB[3] = "N";
vetorB[4] = "O FERREIRA";
Exemplo 01 continuação
System.out.print("vetorB: ");
for (int i = 0; i<=4; i++)
System.out.print(vetorB[i]);
System.out.println();
System.out.println();
//------------------------------------------------
//cria os dois vetores declarados em uma linha
vetorC = new double[3];
vetorD = new double[3];

double soma=0;
for (int i=0; i<=2; i++){
vetorC[i] = i*0.25;
vetorD[i] = i*0.5;
soma += vetorC[i]+vetorD[i];
}
System.out.println("A soma dos elementos de vetorC + vetorD é: "+soma);
System.out.println();
//------------------------------------------------
//usa o vetor ja inicializado com os indices de zero a length
for (int i=0; i < vetorE.length; i++)
System.out.printf("vetorE %5d%8d\n",i,vetorE[i]);
} }
Exercitando......

Crie em uma classe chamada “ExercitandoArray”, esta classe terá o método main() e
deverá ter um array de tamanho 20 que suporte dados do tipo inteiro.
O usuário deverá entrar com os 20 números inteiros e o programa informará:

1) A soma dos 20 elementos.


2) O maior elemento informado.
3) O menor elemento informado.
4) A média dos números informados. (Somar os números e dividir por 20)
5) Imprimir os 20 elementos.
6) Imprima os 20 elementos em ordem numérica.
Arrays(matriz) cap. 7
A linguagem Java não fornece vetores multidimensionais, mas como um
vetor pode ser declarado e ter qualquer tipo de base, é possível criar vetores
de vetores (de vetores etc.), alcançando assim o mesmo efeito.

A declaração de um vetor bidimensional para inteiros, de nome "m" em Java:

int m[][] = new int[2][4]; // matriz com 2 linhas X 4 colunas


Arrays(matriz) cap. 7
Declarando vetores bidimensionais:

1) Com expressões de criação de vetores:


int m[][] = new int[3][3]; // matriz quadrada: 3 linhas X 3 colunas

2) Com expressões de criação de vetores:


int m[][] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };

3) Com linhas de diferentes tamanhos:


int m[][] = new int[2][]; // cria 2 linhas

m[0] = new int[5]; // cria 5 colunas para a linha 0


m[1] = new int[3]; // cria 3 colunas para a linha 1

4) Declarando e inicializando linhas de diferentes tamanhos:


int m[][] = { {1, 2}, {4, 5, 6, 7, 8}, {9, 10, 11} };
Arrays(matriz) cap. 7
Percorrendo vetores bidimensionais com linhas de diferentes tamanhos:
Leia mais em:
int m1[][] = { {1, 2, 3, 4}, {5, 6} };
int m2[][] = { {1, 2}, {3}, {4, 5, 6} };

m.length >>>> determina o número de linhas


m[i].length >>>> determina o número de colunas da i-ésima linha
Leia mais em:

int i, j;
for (i=0; i<m.length; i++) {
System.out.printf("%da. linha: ", (i+1));
for (j=0; j<m[i].length; j++) {
System.out.printf("%d ", m[i][j]);
}
System.out.printf("\n");
}
Arrays(matriz) cap. 7
Exemplos de aplicações Java utilizando vetores bidimensionais/matrizes:
....
Scanner ler = new Scanner(System.in);
int i, j, m[][] = new int[2][4];

for (i=0; i<2; i++) {


System.out.printf("Informe os elementos %da. linha:\n", (i+1));
for (j=0; j<4; j++) {
System.out.printf("m[%d][%d] = ", i, j);
m[i][j] = ler.nextInt();
}
System.out.printf("\n"); }

System.out.printf("\n");
for (i=0; i<2; i++) {
System.out.printf("%da. linha: ", (i+1));
for (j=0; j<4; j++) {
System.out.printf("%d ", m[i][j]);
}
System.out.printf("\n"); }
....
Classe e Objetos um exame mais
profundo cap. 8
Depois de introduzirmos muitos conceitos básicos e terminologias
relacionadas a POO, vamos nos concentrar em mais alguns
conceitos como: Composição, Membros de classe static, variáveis
de instâncias final e criação de pacotes.
Referenciando membros do objeto atual com a
referência this (exitem três usos)
Cada objeto pode acessar uma referência a si próprio com a palavra-
chave this. Usos: 1) Você pode usar this para diferenciar parâmetro
e variáveis com o mesmo nome em um método; 2) Chamar
explicitamente uma variável ou método da classe, mas isto é feito
implicitamente; 3) e por ultimo, usar this para chamar um construtor
quando existe sobrercarga. Veja o exemplo....
Classe e Objetos um exame mais
profundo cap. 8
A classe Date
A manipulação de data e hora é interessante, pois como a linguagem Java é
voltada à Internet e dispositivos móveis, os recursos de data e hora devem ser
suficientemente flexíveis para permitir sua manipulação em qualquer tipo de
cultura nas mais diversas regiões do globo.
Por este fato a manipulação de datas exige muitos detalhes e para cobrir todos
eles, existem onze classes destinadas à manipulação de data e hora.
Pacote Classes
java.util Date, Calendar, GregorianCalendar, TimeZone, SimpleTimeZone
java.text DateFormat, SimpleDateFormat, FormatSymbols.
java.sql Date, Time, Timestamp
A classe Date (do pacote util) representa um instante no tempo, sem levar em
consideração sua representação ou localização geográfica, com precisão de
milissegundos.
A classe DateFormat representa uma data com formato String de acordo com um
determinado fuso horário e calendário.
A classe SimpleDateFormat permite a especificação de diferentes formatos para a
data
A classe Calendar representa um instante no tempo de acordo com um sistema
particular de calendário e fuso horário.
A classe Date Quando um Date é
criado, o número de
milissegundos
desde 1970 é
armazenado no
objeto e pode ser
retornado pelo
método getTime().
A execução do código acima vai gerar o resultado

O objeto “data” é criado com a data do sistema operacional.

Date representa um instante de tempo. Para marcar o tempo, Java considera o


número de milissegundos decorridos desde 1º de janeiro de 1970. Cada
segundo possui 1.000 milissegundos, cada minuto possui 60 segundos, cada
hora possui 60 minutos e cada dia possui 24 horas, ou seja, cada dia
corresponde a 86.400.000 milissegundos.
1.000 x 60 x 60 x 24 = 86.400.000
System.out.println:
A classe Date •Milissegundos na
criação de data1.
•Milissegundos na
criação de data2.
•Número de dias,
meses e anos
decorridos de 1970,
até a data da criação
do objeto.
•Somou-se 10 dias
depois da criação do
objeto.
A classe Date
Método Função Retorno

after(Date d) Verifica se a data é posterior à data presente em d. boolean

before(Date d) Verifica se a data é anterior à data presente em d. boolean

equals(Date d) Verifica se a data é igual à data presente em d. boolean

getTime() Fornece o número de milissegundos decorridos long


desde 1º de janeiro de 1970, 00:00:00.
setTime() Define no objeto Date o número de milissegundos void
armazenados em t.
toString() Converte o objeto Date em tipo String String

A classe Date, não fornece um mecanismo de controle sobre a formatação de


uma data e não permite converter uma string contendo informações sobre uma
data em um objeto Date. Essas funções são executadas pela classe DateFormat
A classe DateFormat
Diferentes países e usuários preferem visualizar a data com formatos diferentes. Ao
criar um objeto a partir da classe DateFormat, ele conterá informação a respeito
de um formato particular no qual será apresentada

Console:
A classe DateFormat
Outro exemplo:
A classe DateFormat
Método Função Retorno

format(Date d) Formata a data em uma string de acordo com o String


estilo utilizado.
getInstance() Retorna uma data e hora de acordo com o DateFormat
estilo SHORT.
getDateInstance() Retorna uma data de acordo com o estilo de DateFormat
formatação local.
getTimeInstance() Retorna um horário de acordo com o estilo de Date
formatação local.
parse(String s) Converte a string em tipo Date. Date

A classe SimpleDateFormat, permite criar formatos alternativos para a


formatação de datas e horas, dependendo das necessidades do desenvolvedor,
ou seja, esta classe expande a capacidade da classe DateFormat.
Caractere Descrição Formato Ex.
G designador de era Texto AD
y ano Ano 1996; 06
M mês do ano Mês Jul; 07
d dia do mês Número 10
h hora em am/pm (1-12) Número 12
A classe
H hora do dia (0-23) Número 0
SimpleDateFormat
m minutos da hora Número 30
s segundos do minuto Número 55
As principais letras
usadas para a criação S milissegundos Número 978
de patterns estão E dias da semana Texto Terça-feira
listadas ao lado: D dia do ano Número 189
F dia da semana no mês Número 2 (2ª Qua
em Julho)
w semana do ano Número 27
W Semana do mês Número 2
a marcadores am/pm Texto PM
k hora do dia (1-24) Número 24
K hora em am/pm (0-11) Número 0
A classe SimpleDateFormat
A classe SimpleDateFormat
A classe SimpleDateFormat, herda os métodos da classe DateFormat e adiciona
os métodos abaixo:

Método Função Retorno

applyPattern(String p) Aplica um pattern à data conforme definido na void


String p.
getPattern() Fornece o pattern que está sendo usado no String
formato da data.
A classe Calendar
A classe Calendar, oferece mecanismos adequados para realização de cálculos
com datas ou para identificação das propriedades de um data, como, por
exemplo, para identificar o dia da semana, o dia do mês em relação ao ano. Para
isso a classe Calendar converte um tipo Date em uma série de campos:

Campo Descrição

DAY_OF_MONTH Dia do mês (1 a 31)

DAY_OF_WEEK Dia da semana(0=domingo, 6=sábado)

DAY_OF_WEEK_IN_MONTH Semana do mês (1 a 5) corrente. Diferente em


relação a WEEK_OF_MONTH porque considera
apenas a semana cheia.
DAY_OF_YEAR Dias decorridos no ano corrente

HOUR Hora do dia (manhã ou tarde) (0 a 11)


A classe Calendar
Campo Descrição

HOUR_OF_DAY Hora do dia (0 a 23).

MILLISECOND Milissegundos em relação ao segundo corrente.

MINUTE Minutos em relação à hora corrente.

MONTH Mês em relação ao ano corrente.

SECOND Segundos em relação ao minuto corrente.

WEEK_OF_MONTH Semana em relação ao mês corrente (1 a 5).

WEED_OF_YEAR Semana em relação ao ano corrente.

YEAR Ano corrente

JANARY,....,DECEMBER Mês correspondente ao ano.

MONDAY,....,SUNDAY Dia correspondente à semana.


A classe Calendar
A classe Calendar
Os métodos mais utilizados de Calendar são:
Método Função Retorno
add(int field, int valor) Função aritmética para objetos Date que adiciona o void
valor inteiro ao campo(Field) determinado
after(Object x) Verifica se o tempo (data e hora) do objeto x (pode boolean
ser Calendar ou outro tipo) é superior ao
armazenado no objeto Calendar
before(Object x) Idem anterior, porém verifica se o tempo é anterior boolean
ao objeto
clear() Zera o conteúdo de data e hora armazenando em void
1º de janeiro de 1970.
getFirstDayOfWeek() Fornece o primeiro dia da semana, dependendo da int
localidade
getTime() Fornece o tempo corrente Date
getTimeMillis() Fornece o tempo corrente em milissegundos. long
rolls() Função aritmética para objetos Date aplicando o void
efeito de rolagem de datas. Realiza cálculos sem
considerar os campos de maior grandeza. Ex. O
ano de uma data.
toString() Fornece uma representação em string para a data String
Cálculos com Calendar
Cálculos com Calendar

A função roll adiciona


um valor sem alterar as
maiores grandezas
Exercício
Crie uma classe como mostra a figura abaixo.

No primeiro método deve ser retornado uma String com a informação das
parcelas de acordo com a data da compra de um item, seu valor e em quantas
prestações o produto vai ser pago. O segundo método retorna true ou false de
acordo com a conversão da String em data. O terceiro método imprime uma data
com dia, mês e ano em linhas diferentes. O quarto método recebe uma data de
nascimento e retorna quantos dias a pessoa viveu até a data presente. O quinto
método retorna a data atual em um formato especial (veja próximo slide). O
ultimo método mostra uma promoção em um supermercado de acordo com o dia
da semana.
Exercício
Crie uma classe principal que usa a classe “ExercicioData” como mostra a figura
abaixo:

Atenção:
1) Os dados em verde
devem ser informados
pelo usuário.
2) Cada exercício
Chama um método
da classe
“ExercicioData”
Formatando valores numéricos
Classe e Objetos um exame mais
profundo cap. 8
Composição
Um classe pode ter referências a objetos de outras classes como membros
(propriedades). E é conhecido como um relacionamento tem um

Exemplo:
public class Carro{
private Porta portas;
private Volante volante;
\\continua........
}
Classe e Objetos um exame mais
profundo cap. 8
Composição
Classe e Objetos um exame mais
profundo cap. 8
Composição x Agregação
Classe e Objetos um exame mais
profundo cap. 8
Composição x Agregação
Porém, os comportamentos semânticos das associações devem estar
presentes quanto a existência. Para composição, por exemplo,
poderíamos forçar que toda vez que uma nota seja criada, uma nova
lista de ItemNotaFiscal deve ser criado. E toda vez que a nota fiscal
for apagada, os itens devem ser destruídos.
Classe e Objetos um exame mais
profundo cap. 8
Membros e variáveis Static
Cada objeto tem sua própria cópia de todas variáveis
de instância da classe. Em certos casos, apenas
uma cópia de uma variável particular deve ser
compartilhada por todos os objetos de uma classe.
Um campo static - chamado variável de classe é
utilizado nestes casos. Uma variável static
representa informações de escopo de classe – todos
os objetos da classe compartilham os mesmos
dados.

Exemplo: um jogo de computador....


Declaração: private static int contador;
Classe e Objetos um exame mais
profundo cap. 8
Classe e Objetos um exame mais
profundo cap. 8
Pacotes cap. 8
Por enquanto nossas classes estão todas em um mesmo diretório, dentro da
pasta src. Conforme o projeto vai evoluindo, mais e mais classes são
criadas e fica cada vez mais difícil manter a organização de nosso projeto.
Com o passar do tempo, trabalharemos com classes de terceiros
(bibliotecas) e classes da própria API da linguagem, o que torna ainda
maior o risco de criarmos uma classe como nome igual a outra existente
em alguma dessas bibliotecas. Ex: criar uma classe Date
Como diferenciar a sua classe da implementação oferecida pela
Oracle?
Usamos o nome completo da classe, ou fully qualified name como é
comumente chamado. Ele é composto pelo nome do pacote . (ponto)
nome da classe.
Pacotes cap. 8
Nomenclatura padrão dos pacotes Java

Por padrão, um pacote em Java sempre:

• é escrito em letra minúscula (lowercase);


• deve ser um nome de domínio, iniciado com com, edu, gov etc.
• É muito natural que o pacote seja o seu domínio (ou da empresa), como
br.edu.ifmg

Exemplo de código (uso das palavras package e import)


Tipos Enum
• São tipos de campos que consistem em um conjunto fixo de
constantes (static final) - lista de valores pré-definidos.
• Para criar um enum no Eclipse escolha: File > New > Others:
Tipos Enum - propriedades
• As instâncias dos tipos enum são criadas e nomeadas junto
com a declaração da classe, sendo fixas e imutáveis;
• Não é permitido criar novas instâncias com a palavra chave
new;
• O construtor é declarado private, embora não precise de
modificador private explícito;
• Os nomes declarados recebem todas as letras em
MAIÚSCULAS;
Tipos Enum - Inicializando
valores
• Para iniciar os valores declarados dentro das variáveis
Enum, é preciso declarar um construtor para iniciar os seus
atributos que são declarados;
Tipos Enum - exemplo
Tipos Enum - imprimindo valor
Tipos Enum - percorrendo valor
Tipos Enum - comparando valores
Tipos Enum – métodos úteis
Nos tipos Enum também existem outros métodos descritos
abaixo:

• String toString() - retorna uma String com o nome da


instância (em maiúsculas).
• valueOf(String nome) – retorna o objeto da classe enum
cujo nome é a string do argumento.
• int ordinal() - retorna o número de ordem do objeto na
enumeração.
Exercício 01
Implemente o diagrama abaixo:

*
______
*

* nome papelaria
Exercício 01
Na classe principal entre com os dados necessários para cadastrar:
1. Uma papelaria com cinco produtos
2. Uma papelaria com três produtos
3. Mostre a quantidade de produtos cadastrados no sistema.
4. Mostre os produtos vendidos por caixa
5. Mostre o produto mais caro de uma papelaria
6. Mostre o último produto cadastrado de uma papelaria
Exercício 02
Implemente o diagrama abaixo:
Exercício 02
Na classe principal entre com os dados necessários para cadastrar:

1. Uma empresa com dois funcionários contendo 3 dependentes;


2. Uma empresa com três funcionários contendo número de
dependentes diferentes;
3. Mostre os dados do funcionário mais velho;
4. Mostre os dados dos funcionários com mais de 60 anos;
5. Mostre os dados dos funcionários que tem dependentes maiores
de 18 anos.
Herança cap. 9
Herança é uma forma de reutilização de software na
qual uma nova classe é criada, absorvendo membros de
uma classe existente e aprimorada com capacidades
novas ou modificadas.
Com a herança, os programadores economizam tempo
durante o desenvolvimento de programas reutililzando
softwares de alta qualidade testados e depurados.
Ao criar uma classe, em vez de declarar membros
completamente novos, o programador pode designar
que a nova classe deverá herdar membros de uma
classe existente. Esta classe é chamada de
superclasse, e a nova classe, de subclasse
Herança (um dos principais recurso da POO) cap. 9 cont.

Uma subclasse normalmente adiciona seus próprios campos e métodos.


Portanto uma subclasse é mais especifica que sua superclasse e
representa um grupo mais especializado de objetos. Em geral, a subclasse
exibe os comportamentos de sua superclasse e comportamentos adicionais
que são específicos à subclasse
Já conhecemos o relacionamento do tipo “tem um”, a Herança é representa
pela expressão “é um”. Em um relacionamento “é um”, um objeto de uma
subclasse também pode ser tratado como um objeto de sua superclasse.
Por exemplo, um carro é um veículo.
Exemplos de superclasse e subclasse
Herança (subclasse e superclasse) cap. 9 cont.
Os relacionamentos de Herança formam estruturas hierárquicas do tipo árvore.
também chamada de hierarquia de herança. Veja um exemplo abaixo:
Especialização

Generalização
Herança (encapsulamento) cap. 9 cont.
Protected
Os membros public de uma classe são acessíveis onde quer que o programa
tenha uma referência a um objeto dessa classe ou uma de suas
subclasses. Os membros private de uma classe só são acessíveis por
dentro da própria classe. O modificador de acesso protected oferece um
nível intermediário de acesso entre public e private. Os membros
protected de uma superclasse podem ser acessados por membros dessa
superclasse, por membros de suas subclasses e por membros de outras
classes no mesmo pacote.
É importante ressaltar que membros public da superclasse tornam-se
membros public da subclasse, e membros protected da superclasse
tornam-se membros protected da subclasse. Já os menbros private de
uma superclasse não pode ser acessado pelas subclasses

Membros de uma classe = propriedades(variáveis) e métodos(funções)


Herança (encapsulamento) cap. 9 cont.
Herança (implementando) cap. 9 cont.
Imagine que temos que implementar uma classe chamada “MembroDaComunidade” e outra
chamada “Aluno” Elas são quase idênticas, ou seja, elas têm os atributos: Nome, Login e
Senha do tipo String, a diferença é que a classe “Aluno” tem um atributo a mais do tipo
String chamado Curso.
Herança (implementando) cap. 9 cont.
Possíveis soluções para “MembroDaComunidade” e “Aluno”:

1. Reescrever todo o código duas vezes. Entretanto terá que manter duas bases de código
separadas.

2. Dentro de “Aluno” poderia existir um variável do tipo “MenbroDaComunidade” e delegar


todas as mensagens, como getLogin( ), getSenha( ), à instância de “Aluno”. A delegação
ainda o obriga a redefinir todos os métodos encontrados na interface de
“MenbroDaComunidade”
Delegação é o processo de um objeto passar uma mensagem para outro objeto, para
atender algum pedido.

3. Usar herança
Herança (implementando) cap. 9 cont.
Implementando as duas classes usando Herança temos:
Obs: Em java conseguimos implementar Herança através da palavra reservada
extends
Herança (quando usar) cap. 9 cont.
“É um” versus “tem um”: aprendendo quando usar herança

A herança de implementação permite que suas classes herdem a implementação


de outras classes. Entretanto, somente porque uma classe pode herdar de
outra não significa que isso deve ser feito!

Então, como você sabe quando deve usar herança? Felizmente, existe uma regra
geral a ser seguida, para evitar uma herança incorreta.

Quando você está considerando a herança para reutilização ou por qualquer outro
motivo, precisa primeiro perguntar-se a classe que está herdando é do mesmo
tipo que a classe que está sendo herdada. O fato de pensar em termos de tipo
enquanto se herda é freqüentemente referido como teste “é um”.
Ex: Aluno “é um” MembroDaComunidade?

Caso contrário é mais indicado usar a composição (“tem um”).


Herança (mecânica da herança) cap. 9 cont.
Uma classe construída através de herança pode ter três tipos importantes de
métodos ou atributos:

Sobrepostos: a nova classe herda o método ou atributo da progenitora, mas


fornece uma nova definição.

Novo: a nova classe adiciona um método ou atributo completamente novo.

Recursivo: a nova classe simplesmente herda um método ou atributo da


progenitora.

Exemplo...
Herança (mecânica da herança) cap. 9 cont.

Novos métodos

Método sobrescrito
Uso recursivo
Herança (tipos de herença) cap. 9 cont.
Ao todo existem três tipos de herança:

1. Para reutilização de implementação.


Até aqui, a herança de implementação parece excelente. Cuidado, contudo – o
que parece uma técnica útil na superfície se mostra perigosa no uso. Na
verdade, a herança de implementação é a forma mais deficiente de herança e
normalmente você deve evitá-la (Problema: pode-se herdar métodos que nunca
serão usados ou que não tem ligação com o domínio do problema a ser
resolvido).
Uma herança pobre é o monstro de Frankenstein da programação. Quando você
usa herança unicamente para reutilização de implementação, sem quaisquer
outras considerações, freqüentemente pode acabar com um monstro
construído a partir de partes que não se encaixam.

A classe “TocaCD” tem os botões “Play”, “Stop”


e “Pause” que podem ser aproveitados na nova
classe “Dvd”.
Problema:
O que será feito com os botões “Sintonizar” e
“Estação (Am, Fm)”?
Herança (tipos de herença) cap. 9 cont.
Ao todo existem três tipos de herança:

2. Para a diferença.
Você viu a herança para diferença no exemplo de “PontosDimensionais” e
“PontosTridimencionais”. A programação pela diferença permite que você
programe especificando apenas como uma classe filha difere de sua classe
progenitora.
A programação por diferença é um conceito poderoso. Ela permite que você
adicione apenas o código necessário o suficiente para descrever a diferença
entre a classe progenitora e a classe filha. Isso permite que você programa por
incrementos.

Ponto

PontoBidimencional

PontoTridimencional

PontoQuatroDimensões
Herança (tipos de herença) cap. 9 cont.
Ao todo existem três tipos de herança:

3. Para substituição de tipo.


Permite que você descreva relacionamentos com capacidade de substituição

O que é capacidade de substituição?

Linha recebe dois objetos


“PontoBiDimencional”
como argumentos e
fornece alguns métodos
para recuperar os valores,
um método para calcular
a distância entre dois
pontos e um método para
calcular o ponto médio.
Herança (tipos de herança) cap. 9 cont.
Um relacionamento com capacidade de substituição significa que você pode
passar para o construtor de “Linha” qualquer objeto que herde de
“PontoBiDimencional”.

Lembre-se de que, quando uma filha herda de sua progenitora, você diz que a filha
‘é uma’ progenitora. Assim, como um objeto “PontoTriDimencional” é um
“PontoBiDimencional”, você pode passar um objeto “PontoTriDimencional” para
o construtor.

No método principal temos um objeto bidimensional e outro tridimensional no


construtor de Linha
Herança (Hora de escrever algum código) cap. 9 cont.
A classe “ObjetoHumor” define um método publico chamado “consultaHumor”, que
imprime o humor do objeto e, um método protegido “getHumor”, que é usado
internamente para consultar o humor do objeto. As subclasses podem
simplesmente sobrescrever o método “getHumor” para especializar o humor.

Crie duas subclasses a partir de “ObjetoHumor” chamadas “ObjetoTriste” e


“ObjetoFeliz”. As duas subclasses devem simplesmente sobrepor “getHumor”
para fornecer seu próprio humor especialmente especializado. Nas classes
adicione os seguintes métodos próprios:
Classe ObjetoTriste => Método “chorar()” que deve imprimir “rurururururu”
Classe ObjetoFelis => Método “rir()” que deve imprimir “hahahaha...heheheh”
Herança (Classes Abstratas) cap. 9 cont.
Existirão ocasiões em que você desejará desenvolver uma classe especificamente
para que outros possam herdar dela. Ou seja, não faz sentido instanciar a
classe base diretamente. Embora a classe base contenha código comum, que
é muito valioso para subclasses, ela pode não ter nenhum valor para
instanciação e uso direto. Considere a classe empregado:
Podemos usar “Empregado”
como base para implementar
as classes
“EmpregadoComissionado” ,
“EmpregadoHoristas”,
“EmpregadoSalariado”.
Onde cada subclasse sabe
calcular seu salário.

Neste caso cada subclasse


define seu próprio método. Mas
há um pequeno problema:
“Empregado” não tem nenhuma
regra para pagamento!
Herança (Classes Abstratas) cap. 9 cont.
Uma solução é não definir o método “calculaSalario”. Entretanto não definir o
método na classe base seria uma decisão infeliz. Isso não modela um
funcionário muito bem.
Outra solução é deixar o método retornando um valor fixo para que ele seja
sobrescrito. Mas como garantir que o desenvolvedor sobrescreva este método?

Felizmente, a POO oferece um tipo especial de classe, destinada especificamente


à herança planejada: a classe abstrata

Uma classe abstrata é muito parecida com qualquer outra definição de classe. A
definição da classe pode definir comportamentos e atributos, exatamente como
uma classe normal. Entretanto, você não pode instanciar diretamente uma
classe abstrata, pois uma classe abstrata pode deixar alguns métodos
indefinidos.

Um método declarado, mas não implementado, é chamado de método abstrato.


Somente classes abstratas podem ter métodos abstratos.
Herança (Classes Abstratas) cap. 9 cont.
Exercício - Herança
A palavra final cap. 10
Proibindo mudanças (3 usos dessa palavra reservada)
1) Se for utilizada na definição de uma classe, isso indica que ela não poderá ser
estendida: public final class MyClass {}
// o código abaixo não é permitido
public class MyOtherClass extends MyClass {}

2) Se a palavra final for utilizada na definição de um método, indica que ele não
poderá ser sobrescrito:
public final class MyClass { public final void foo() {} }
// o código abaixo não é permitido
public class MyOtherClass extends MyClass { public void foo() {} }

3) Se a palavra final for usada em uma variável, isso indica que ela é na verdade
uma constante, pois não será permitido que se modifique o valor da mesma uma
vez que um valor seja atribuído:

public class MyClass { public final void foo() {final int teste = 0;} }
// o código abaixo não é permitido
public class MyClass1 { public void foo() {final int teste = 0; teste++;} }
Polimorfismo cap. 10
Aprendendo a prever o futuro

Como você sabe o encapsulamento permite construir


componentes independentes e a herança permite
reutilizar e estender esses componentes. Entretanto,
ainda falta algo.
O software está em constante mudança (erros
aparecem ou novas funcionalidades são exigidas).

Felizmente, a POO entende que o software de sucesso


não é estático. Assim, a programação orientada a
objetos usa o conceito de polimorfismo, que é o terceiro
pilar da POO
Polimorfismo cap. 10
Aprendendo a prever o futuro

Polimorfismo significa muitas formas. Em termos de


programação, muitas formas significa que um único
nome pode representar um código diferente,
selecionado por algum mecanismo automático. Assim,
um nome pode assumir muitas formas e como pode
representar código diferente, o mesmo nome pode
representar muitos comportamentos diferentes.

Pense no termo abrir. Você pode abrir uma porta, uma caixa, uma janela e uma conta no
banco. A palavra abrir pode ser aplicada a muitos objetos diferentes no mundo real.
Cada objeto interpreta ‘abrir’ de sua própria maneira. Entretanto, em cada caso, você
pode simplesmente dizer ‘abrir’. Para descrever a ação.

A Herança fornece o aparato necessário para tornar certos tipos de polimorfismo


possível. Vamos ver o código a seguir....
Polimorfismo cap. 10
Exemplo 01
Polimorfismo cap. 10
Exemplo 01
Polimorfismo cap. 10
Exemplo 01 - resultado

Com base na saída, parece que o método “falar” de “ObjetoPersonalizável”


tem muitos comportamentos diferentes. Mesmo que o array supostamente
contenha instâncias de “ObjetoPersonalizável”.
Polimorfismo cap. 10
O exemplo anterior explica o mecanismo, mas ele poderia não representar
adequadamente o espírito do polimorfismo. Afinal, você sabe exatamente o
que o array contém.
Em vez disso, imagine que você tenha um objeto cujo o método recebe um
objeto “ObjetoPersonalizável” como parâmetro:

Os relacionamentos com capacidade de substituição permitem que você


passe uma instância do objeto “ObjetoPersonalizável” ou qualquer
descendente dessa classe.
O polimorfismo entra em ação quando o método “façaFalar” é chamado.
Logo, ele garante que o método correto seja chamado.
Polimorfismo cap. 10
Escrevendo algum código
1) Cria a estrutura de classes mostradas abaixo:
Polimorfismo cap. 10
Escrevendo algum código
2) Cria uma classe com o método “main” e execute os seguintes passos:

a) Crie um objeto da classe FolhaDePagamento.


b) Crie dois objetos da classe “EmpregadoComissionado” e informe seus
dados.
c) Informe as unidades vendidas para os dois empregados comissionados.
d) Crie dois objetos da classe “EmpregadoHorista” e informe seus dados.
e) Informe as horas trabalhadas para os dois empregados horistas.
f) Registre as informações dos quatro empregados na classe
“FolhaDePagamento” usando o método “registraInfoDoEmpregado”.
g) Crie um array de 4 posições do tipo Empregado e preencha-o com os
funcionários criados.
h) Use o método “fazerPagamentos” da classe “FolhaDePagamento”.
i) Use o método “imprimirRelatorio” da classe “FolhaDePagamento”
Polimorfismo cap. 10
Escrevendo algum código

3) Responda as perguntas:

a) Você pode instanciar um objeto do tipo “Empregado”? Justifique


b) Identifique no código as linhas responsáveis por indicar herança.
c) Identifique no código as linhas responsáveis por indicar herança por
substituição.
d) Identifique no código as linhas responsáveis por indicar sobrecarga
e) Identifique no código as linhas responsáveis por indicar polimorfismo.
Interface
•Uma interface é uma construção similar a uma classe abstrata que contém
apenas métodos abstratos;

•Da mesma forma que uma classe abstrata, uma interface não pode ser
instanciada;

•Seu objetivo é declarar alguns métodos que serão implementados por


uma ou mais classes;

•Diferentemente de uma classe abstrata, uma interface não possui


implementação, apenas declarações de métodos (cabeçalhos) e
constantes.
Interface
Exemplo 1

•A classe java.util.Arrays possui um método, chamado sort, que ordena um


array de objetos;

•Para usá-lo é preciso, entretanto, que a classe dos elementos do array


implemente a interface Comparable:

•Isto é, uma classe deve implementar o método compareTo para implementar


Comparable e, por conseguinte, usar o método sort.
Interface
Exemplo 1 (cont.)
Interface
Exemplo 1 (cont.)
Interface
Problema

Seja a hierarquia de veículos mostrada a seguir:


Interface
Problema (cont.)

•Todos os meios de transporte listados na hierarquia possuem pneus;

•Por isso, o método calibrarPneus() foi declarado no topo da hierarquia,


sendo, dessa forma, herdado pelas demais subclasses;

•Apenas os aviões aterrissam. Logo, o método aterrissar() foi declarado


na subclasse Aviao.

•Quase todos os veículos da hierarquia anterior podem ser abastecidos


com combustível;

•Entretanto, se fosse definida uma implementação para tal na classe


Veiculo, ela seria herdada por Bicicleta, que não pode ser abastecida;

•Por outro lado, definir métodos distintos para abastecimento nas classes
Aviao e Carro introduziria uma redundância indesejável.

Como resolver este problema?


Interface
Solução – Herança Múltipla

•A linguagem C++ resolveria o problema com herança


múltipla:

•A herança múltipla resolve alguns problemas, mas introduz outros. Por


isso, Java implementa apenas herança simples.
Interface
Solução - Um método para cada veículo
Interface
Solução – A interface IUsaCombustivel
Interface
Um método para todos os veículos
Interface
A classe Aviao implementa a interface
Interface
A classe Carro implementa a interface
Interface
Exemplo de reabastecimento
Interface
Considerações Finais
• Uma interface não pode ser instanciada, embora possa-se declarar variáveis
que se comportam como tal;

• Todas as operações definidas em um interface são públicas;

• Uma interface não possui variáveis de instância nem implementação de


métodos;

• Todas as variáveis definidas em uma interface são tratadas como constantes


estáticas (public static final);

• Uma classe pode implementar múltiplas interfaces.

• Para que uma classe implemente uma interface deve-se fazer o seguinte:
-Declarar que a classe implementa (implements) a interface;
-Fornecer uma implementação para cada operação declarada na
interface.
Interface e polimorfismo
Um exemplo prático
Vamos imaginar que somos responsáveis por implementar um sistema que
controla a fabricação e venda de um simples restaurante de pizza de calabresa.
Dado o contexto, poderíamos então escrever um projeto bem modesto de
automatização.

Versão 1
Interface e polimorfismo
Um exemplo prático

Versão 1 (continuação)
Interface e polimorfismo
Um exemplo prático
Vamos imaginar que o programa esta funcionando com sucesso até que o
proprietário do restaurante decide aumentar o cardápio acrescentando uma nova
pizza. Consequentemente fomos requisitados para alterar o programa que suporte
o controle agora de pizza sabor napolitana.

Versão 2
Interface e polimorfismo
Um exemplo prático

Versão 2 (continuação)
E consequentemente alteramos o programa para executar a pizza com o novo
sabor e deixar tudo funcionando com a nova pizza agora. Ao tentar executar
novamente o sistema, notaremos um erro de compilação no momento de fabricar
a pizza de napolitana.
Interface e polimorfismo
Um exemplo prático

Versão 2 (continuação) - Primeira solução

O passo mais
lógico é fazer
uma sobrecarga
de método,
acrescentando
outro que
fabrica o sabor
da nova pizza
proposta.

Será uma
boa
solução?
Interface e polimorfismo
Um exemplo prático
O primeiro passo é definir uma hierarquia “paternal” com o intuito de gerar
comportamento genérico para todas as supostas pizzas do projeto. No exemplo
decidi usar uma interface ao invés de uma classe abstrata ou concreta.

Versão 3 – Solução mais correta


Interface e polimorfismo
Um exemplo prático

Versão 3 (continuação...)
Interface e polimorfismo
Um exemplo prático

Versão 3 (continuação...)

Repare que essa solução não é novidade, ela funciona igual a herança por substituição de
tipo, mas trabalhando com interfaces poderíamos dar um nome mais genérico e
estaríamos prontos para trabalhar com outros pratos, como por exemplo lasanha.
Collections
Array
• Vantagens
•Tem seus tipos bem definidos e podem ser verificados pelo compilador;
•Conhece o seu tamanho;
•Aceita tipos primitivos facilmente;

Desvantagens
•não podemos redimensionar um array;
•é impossível buscar diretamente por um determinado elemento cujo
índice não se sabe;
•não conseguimos saber quantas posições do array já foram populadas
sem criar, para isso, métodos auxiliares.
Collections
• O comitê responsável pelo Java criou um conjunto de classes e interfaces
conhecido como Collections Framework
•São dinâmicas
•Aceitam tipos de dados heterogênicos
•Interfaces são utilizadas para dar mais flexibilidade
•Suporta iteradores
Collections
List
• Uma lista é uma coleção que permite elementos duplicados e mantém uma
ordenação específica entre os elementos.
Usa a interface java.util.List

A implementação mais utilizada da interface List é a ArrayList que trabalha


com um array interno para gerar uma lista. Portanto, ela é mais rápida na
pesquisa do que sua concorrente, a LinkedList, que é mais rápida na inserção
e remoção de itens nas pontas.
Collections
List
Assim, é possível criar, por exemplo, uma lista de Contas Correntes:
Collections
List
A interface List e algumas classes que a implementam podem ser vistas no
diagrama a seguir:
Collections
List - Generics
Para evitar que mais de um tipo de objeto seja inserido usamos Generics:

OBS: O uso de Generics elimina a necessidade de casting.

A partir do Java 7, se você instanciar um tipo genérico na mesma linha de sua


declaração, não é necessário passar os tipos novamente, basta usar new
ArrayList<>(). É conhecido como operador diamante:
Collections
List - Generics

SEM os tipos genéricos: COM os tipos genéricos:


Os elementos entram como Os elementos ENTRAM
Bola, Peixe, Guitarra e Carro somente como referência do
objeto Peixe

e SAEM como uma referência e SAEM como uma referência


do tipo Object. do tipo Peixe.
Collections
List - Generics
A programação genérica é um estilo de programação na qual os algoritmos
são escritos com tipos a serem especificados posteriormente, ou seja, são
instanciados posteriormente para um tipo específico fornecido como
parâmetro.

Este tipo de programação permite que um método opere sobre objetos de


vários tipos, fornecendo “type safety” em tempo de compilação e promovendo
a eliminação da necessidade de casts.
Collections
List – importancia da interface
Sempre refira a interface List, ao invés das implementações específicas:

Faça isso para parâmetros de


entrada também.
Collections
List – Ordenação
A classe Collections traz um método estático sort que recebe um List como
argumento e o ordena por ordem crescente. Por exemplo:

OBS: não esqueça de assinar a interface Comparable e implementar o método


compareTo. Ex: com generics
Collections
List – Importante
Para ordenar um list com seus objeto utilizando o método sort, não esqueça de
implementar a interface Comparable em suas classes

Para usar o método contain de um list com seus objeto, não esqueça de
implementar o método equals – é através dele que o objeto é encontrado.

Uma ajuda para escolher qual implementação da interface list usar:


Collections
Set
Um conjunto (Set) funciona de forma análoga aos conjuntos da matemática, ele
é uma coleção que não permite elementos duplicados.

A ordem em que os elementos são armazenados pode não ser a ordem na qual
eles foram inseridos no conjunto.
Collections
Set
Um conjunto é representado pela interface Set e tem como suas principais
implementações as classes HashSet, LinkedHashSet e TreeSet.

HashSet
-Implementado usando hash table
-Elementos não ordenados
-Adição e remoção são constantes O(1)

TreeSet
-Implementado usando árvores
-Garante a ordem dos elementos
-Adição e remoção tem complexidade
logarítmica
Collections
Set
O código a seguir cria um conjunto e adiciona diversos elementos, e alguns
repetidos:

Algumas operações com conjuntos:


Collections
Set
As coleções têm como base a interface Collection, que define métodos para
adicionar e remover um elemento, e verificar se ele está na coleção, entre outras
operações, como mostra a tabela a seguir:

A busca em um Set pode ser mais rápida do que em um objeto do tipo List, pois
diversas implementações utilizam-se de tabelas de espalhamento (hash tables),
realizando a busca para tempo linear (O(1)).
Collections
List e Set - Iterator
Collections
List e Set - Iterator
Collections
Exercício

-Crie uma classe para representar um estudante. Nessa classe é importante armazenar
qual curso ele está frequentando. Imagine que os cursos são os mesmo do IFMG
Campus Formiga

-Crie 10 estudantes em um método main e informe seus dados.

-Crie uma estrutura de dados para cada curso e insira esses estudantes em suas
respectivas estruturas.

-Crie uma outra estrutura com os dados dos alunos da área de exatas (somente alunos
que pertencem ao curso de eng. elétrica e ciência da computação e matématica)

- Crie uma outra estrutura com os dados dos alunos da área de exatas que não são da
engenharia elétrica.
Collections
Map
Um mapa é composto por um conjunto de associações entre um objeto chave a
um objeto valor.

O método put(Object, Object) da interface Map recebe a chave e o valor de uma


nova associação.
Collections
Map - exemplo
Observe o exemplo: criamos duas contas correntes e as colocamos em um
mapa associando-as aos seus donos.
Collections
Map - exemplo
Apesar do mapa fazer parte do framework, ele não estende a interface Collection

Suas principais implementações são o HashMap, o TreeMap e o Hashtable.


Collections
Map – Diferença entre HashMap e HashTable
Hashmap
•Não é sincronizada
•Aceita valores nulos e uma chave nula
•É possível varrer toda estrutura com um iterador de forma simples
•Possui containsValue() e containsKey()
•É mais rápida
•Consome menos memória
•Mais moderna
•Mãe: AbstractMap

Hashtable
•Sincronizada e pode ser facilmente usada em ambiente concorrente
•Não aceita nulos
•Iterar é mais complicado
•Possui contains()
•Tem overhead pela sincronização
•Ocupa mais memória
•Considerada obsoleta
•Mãe Dictionary
Collections
Map - tamanho
Duas propriedades muito
importantes no HashMap são:
A capacidade inicial (initial
size) e o fator de
carregamento/refresh (load
factor).

O load factor é um atributo que


mensura em que momento o
HashMap deve dobrar seu
tamanho, ou seja, antes que
você possa preencher as 16
posições, em algum momento o
tamanho do HashMap irá dobrar
de 16 para 32
Collections
Map – métodos comuns
Collections
Map – métodos comuns
Collections
Map – métodos comuns
Collections
Map – métodos comuns
Collections
Map – métodos comuns
Collections
Conclusões
Collections
Exercício
Collections
Exercício

Testes também os métodos estáticos reverse, shuffle e rotate


da classe Collections e descubra o que eles executam.
Collections
Exercício
Transmissão do jogo

O Galvão Bueno tem a memória fraca e precisa lembrar dos


nomes dos jogadores constantemente. Ele geralmente sabe a
posição das pessoas em campo, mas não lembra o nome
delas.

Crie uma estrutura de dados que irá informar quais são os


jogadores que serão titulares de acordo com cada posição de
um time de futebol.

As buscas pelo nome desses jogadores devem ser rápidas,


pois a transmissão do jogo é ao vivo.

Crie a estrutura e mostra um exemplo em um método main.


Tratamento de Exceção cap. 13
Uma exceção é uma indicação de um problema que ocorre durante a
execução de um programa. O nome ‘exceção’ dá a entender que o
problema ocorre raramente – se a ‘regra’ é que uma instrução execute
geralmente de modo correto, então a ‘exceção à regra’ é que um problema
ocorra.

Visão geral de tratamento de erro

Realize uma tarefa


Se a tarefa anterior não tiver sido executada corretamente
Realize processamento de erro
Realize a próxima tarefa
Se a tarefa anterior não tiver sido executada corretamente
Realize processamento de erro
......

Se os problemas potenciais ocorrem raramente, mesclar o programa e a


lógica do tratamento de erro pode degradar o desempenho de um
programa, porque o programa deve realizar testes (potencialmente)
freqüentes para determinar se a tarefa foi executada corretamente.
Tratamento de Exceção cap. 13

Execução esperada
do programa =>
Tratamento de Exceção cap. 13
Usuário informou o valor zero para o denominador

Usuário informou uma string, ao invés, de um número


Tratamento de Exceção cap. 13
Tratamento de Exceção cap. 13
Usuário informou o valor zero para o denominador

Exercício:

Melhore o
programa para
que o sistema
fique lendo os
Usuário informou uma string, ao invés, de um número valores inteiros
até que
estejam certos
Tratamento de Exceção cap. 13
Características

Características do tratamento de exceção


-As linhas de código do bloco catch são executadas somente se ocorrer um
erro
-A execução do programa continua depois da “}” do bloco catch. Ocorrendo
erro ou não.
-Quando um bloco Try termina, as variáveis locais declaradas no bloco saem
de escopo (são destruídas).
Tratamento de Exceção cap. 13
bloco finally
Os programadores que obtêm certos tipos de recursos devem
retorná-los ao sistema explicitamente para evitar supostos “vazamentos de
recursos”.
Por exemplo:
Arquivos, conexões com banco de dados, conexões de rede que não
são fechadas adequadamente talvez não estejam disponíveis para uso em
outros programas.

Para resolver este tipo de problema o bloco Finally fica responsável por fazer
a liberação de recurso e será executado quando:
-Não ocorrer erros durante o bloco try
-Ocorrer erros durante o bloco try. Neste caso, ele será executado depois
do bloco catch
-Mesmo que exista um comando return, break ou continue.
E ele não será executado se:
-O comando System.exit, que é responsável por encerrar o programa for
executado
Tratamento de Exceção cap. 13
bloco finally
try
{
instruções
instruções de aquisição de recurso
} A partir da versão 1.6, podemos usar o operador
Catch (UmTipoDeExcecao excecao1) “or” ( | ) para tratar mais de uma exceção.
{ Exemplo:
instruções de tratamento de erro ....
} } catch (InputMismatchException |
.
.
ArithmeticException e) {
. System.out.println("Erro: entre com números");
Catch (OutroTipoDeExcecao excecao2) }
{
instruções de tratamento de erro
}
finally
{
instruções
instruções de liberação de recurso
}
Tratamento de Exceção cap. 13
throw

Obs.:
Throw – captura, lança* e relança*
uma exceção.

* Pode ser lançado qualquer objeto que herde da classe


Throwable

Saída do Console
Tratamento de Exceção cap. 13
Pilha de execução

Saída do Console
Tratamento de Exceção cap. 13
Declarando novos tipos de exceção
Os programadores podem achar útil criar suas próprias classes de
exceção que são específicas aos problemas que podem ocorrer quando outro
programador utilizar suas classes. Para isso a classe deve:
- Estender uma classe de exceção
- Geralmente contém somente dois construtores – um que não aceita
nenhum argumento e passa uma mensagem de exceção padrão para o
construtor da superclasse, e um que recebe uma mensagem de exceção
personalizada como uma string para passar para o construtor da
superclasse.
Tratamento de Exceção cap. 13
Declarando novos tipos de exceção
Java possui dois tipos de exceções:

– Checked Exceptions são exceções que ocorrem por falhas


externas como erro ao abrir um arquivo ou ao se conectar com um servidor.
Elas devem sempre ser declaradas pelos métodos que as lançam e precisam
ser tratadas (a menos que explicitamente são passadas adiante). Herdam da
classe “Exception”

– Unchecked Exceptions são exceções que provavelmente poderiam


ser evitadas pelo programador (ArrayIndexOutOfBoundsException,
NullPointerException). Não precisam ser declaradas e nem tratadas. Herdam
da classe “Error “ou “RunTimeException”
Tratamento de Exceção cap. 13
Declarando novos tipos de exceção
Você também pode criar sua própria exceção:
Tratamento de Exceção cap. 13
Declarando novos tipos de exceção
A classe “Exercicio2” usa a exceção “DivisaoPorZeroException”.
Tratamento de Exceção cap. 13
Declarando novos tipos de exceção
A classe “DivisaoPorZeroException” é uma exceção criada pelo
desenvolvedor.
Tratamento de Exceção cap. 13
Exercício
1) Crie um programa que faça uma divisão por zero, e faça o
tratamento da exceção imprimindo na tela “DIVISÃO POR ZERO
INVÁLIDA”.

2) Criar uma modelagem OO para uma Conta, de acordo com as


seguintes requisitos:
- Deve guardar um saldo.
- Deve possuir um método de depósito.
- Deve possuir um método de retirada, que caso não haja saldo
levantará uma exceção do tipo SaldoInsuficienteException. Esta
exceção será criada por você.
JDBC cap. 25
Acesso a Banco de Dados - Introdução

• Java DataBase Connectivity (JDBC) é um conjunto de


classes e interfaces (API) escritas em Java que faz o
envio de instruções SQL para qualquer banco de dados
relacional.

• Amplia o que você pode fazer com Java.

• Possibilita o uso de bancos de dados já instalados.

• Para cada banco de dados há um driver JDBC.


JDBC cap. 25
Acesso a Banco de Dados - Arquitetura
JDBC cap. 25
Acesso a Banco de Dados – Pré-requisitos

• O pacote JDBC (padrão na distribuição da plataforma de


desenvolvimento Java desde sua versão 1.1);

• Acesso a um servidor de banco de dados relacional, ou


seja, um sistema gerenciador de banco de dados que
entende SQL;

• Um driver JDBC adequado ao SGBD que será utilizado.


JDBC cap. 25
Acesso a Banco de Dados – Configurando o ambiente
JDBC cap. 25
Acesso a Banco de Dados – Configurando o ambiente
JDBC cap. 25
Acesso a Banco de Dados – Primeiro Exemplo

• Neste material iremos utilizar como exemplo a


seguinte tabela:

create table CONTATO(


CPF bigint not null primary key,
NOME varchar(60) not null unique,
SEXO char(1) not null,
TELEFONE varchar(10) not null
)

• Por didática, assumiremos todos os campos como


não-nulos (not null).
JDBC cap. 25
Acesso a Banco de Dados

• Principais classe do pacote java.sql

– java.sql.DriverManager
– java.sql.Connection
– java.sql.Statement e java.sql.PreparedStatement
– java.sql.ResultSet
JDBC cap. 25
Acesso a Banco de Dados - java.sql.DriverManager

• registerDriver(driver: Driver) : void


– Utilizado para o registro de um driver. Primeira coisa a ser feita quando
vamos trabalhar com acesso a um SGBD.
– Ex.:
– DriverManager.registerDriver(new com.mysql.jdbc.Driver());

• getConnection(url: String, user : String, pword: String) :


java.sql.Connection
– Utilizado para criar uma conexão a um SGDB. Deve ser passado a url
de acesso ao SGBD, o nome e a senha do usuário.
– Ex.:
– Connection conn =
– DriverManager.getConnection("jdbc:mysql://professor:3306/faminas",
"faminas", "faminas");
JDBC cap. 25
Acesso a Banco de Dados - java.sql.Connection

• setAutoCommit(autoCommit: boolean) : void


– Configura se a conexão será “auto-comitada” ou não.
– Ex.:
conn.setAutoCommit(false);

• commit() : void
– Realiza o commit da conexão.
– Ex.:
conn.commit();
JDBC cap. 25
Acesso a Banco de Dados - java.sql.Connection

• rollback() : void
– Realiza o rollback da conexão.
– Ex.:
conn.rollback();

• close() : void Realiza o encerramento da conexão.


Sempre ao abrir uma conexão, a mesma deverá ser
encerrada.
– Ex.:
conn.close();
JDBC cap. 25
Acesso a Banco de Dados

java.sql.Statement e java.sql.PreparedStatement

• Classe responsável pela criação de instruções de


acesso ao banco.

• executeUpdate() : int
– Realiza a execução de um insert, update, delete ou
qualquer instrução sql que não retorne nada, por
exemplo, instruções DDL.
– Ex.:
st.executeUpdate(“delete from CONTATO where
SEXO='M'”)
JDBC cap. 25
Acesso a Banco de Dados

java.sql.Statement e java.sql.PreparedStatement

• executeQuery() : java.sql.ResultSet
– Realiza a execução de um select.
– Ex.:
ResultSet rs = st.executeQuery(“select * from
CONTATO”);

• close() : void
– Realiza o encerramento da instrução. Sempre ao abr ir
uma instrução, a mesma deverá ser encerrada.
– Ex.:
st.close();
JDBC cap. 25
Acesso a Banco de Dados - java.sql.ResultSet

• next() : boolean
– Move o cursor para a próxima posição do result set
retornando um booleano dizendo se a próxima posição é
válida ou não.
– Ex.:
rs.next();
JDBC cap. 25
Acesso a Banco de Dados - java.sql.ResultSet

• Métodos de busca de resultados. Pode ser inserido o nome


da coluna ou a posição em que a coluna se encontra no
resultado.
– getLong(columnName: String) ou getLong(columnIndex: int)
– Ex.:
rs.getLong(“CPF”); ou rs.getLong(1);

• Existem diversos métodos com os mesmos propósitos:


– getInt(...) : int
– getString(...) : String
– getDate(...) : java.sql.Date somente data
– getTimestamp(...) : java.sql.Date data e hora
JDBC cap. 25
Acesso a Banco de Dados - java.sql.ResultSet

• close() : void
– Realiza o encerramento do conjunto de resultados (result
set).
– Sempre ao manipular um result set, o mesmo deverá ser
encerrado.
– Ex.:
rs.close();
JDBC cap. 25
Acesso a Banco de Dados – Usando JDBC

1. Adicionar o connector do SGBD como biblioteca do


projeto
2. Registrar o driver de conexão
3. Abrir uma conexão usando a classe
DriverManager.
4. Criar um statement ou prepareStatement a partir da
conexão (java.sql.Connection)
5. Executar um executeQuery() ou um executeUpdate()
6. Fechar a conexão.
JDBC cap. 25
Acesso a Banco de Dados - Importante

• Lembrar de fechar (close) tudo que tiver sido


aberto.

• Cuidado ao manipular exceções.

• Transação é muito importante e deve ser


utilizado.
JDBC cap. 25
Acesso a Banco de Dados – Exemplo 1
JDBC cap. 25
Acesso a Banco de Dados – Estrutura Genérica
JDBC cap. 25
Acesso a Banco de Dados – Estrutura Genérica
JDBC cap. 25
Acesso a Banco de Dados – Estrutura Genérica
JDBC cap. 25
Acesso a Banco de Dados – Transação
Threads
Arquitetura multicore
Consiste em uma CPU que possui mais de um núcleo de
processamento. Este tipo de hardware permite a execução
de mais de uma tarefa simultaneamente, ao contrário das
CPUs singlecore, que eram constituídas por apenas um
núcleo, o que significa, na prática, que nada era executado
efetivamente em paralelo.
Threads
Arquitetura multitask
É a capacidade de executar várias tarefas ou processos ao
mesmo tempo, compartilhando recursos de processamento
como a CPU. Esta habilidade permite ao SO intercalar
rapidamente os processos ativos para ocuparem a CPU,
dando a impressão de que estão sendo executados
simultaneamente
Threads
Arquitetura multhread
Multitasking em nível de processo. Ele permite ao software
subdividir suas tarefas em trechos de código independentes e
capazes de executar em paralelo, chamados de threads. Com
isto, cada uma destas tarefas pode ser executada em paralelo
caso haja vários núcleos.
Threads
Trechos de código que operam independentemente da
seqüência de execução principal.

Como diferencial, enquanto os processos de software não


dividem um mesmo espaço de memória, as threads, sim, e
isso lhes permite compartilhar dados e informações dentro
do contexto do software.

Cada objeto de thread possui um identificador único e


inalterável, um nome, uma prioridade, um estado, um
gerenciador de exceções, um espaço para armazenamento
local e uma série d
Threads
Na JVM, as threads são escalonadas de forma preemptiva
seguindo a metodologia “round-robin”. Isso quer dizer que o
escalonador pode pausá-las e dar espaço e tempo para
outra thread ser executada, o que é feito conforme a
prioridade que ela possui.
Threads
Em um ambiente multicore temos um cenário bem diferente,
com várias threads executando paralelamente e otimizando
o uso da CPU
Threads
Programação paralela em Java
Threads
Programação paralela em Java
• toda aplicação Java possui, no mínimo, uma thread.
Esta é criada e iniciada pela JVM para executar o
main().
• Em Java, existem basicamente duas maneiras de criar
threads:
1. Estender a classe Thread (java.lang.Thread); ou
2. Implementar a interface Runnable (java
.lang.Runnable).
• Nos dois casos
1. Sobreponha o método run().
2. O run() deve conter um loop que irá rodar pelo
tempo de vida do thread. Quando o run(), terminar,
o thread morre.
Threads (herança)
Exemplo:
….
public static void main(String[] args) {

boolean fim = false;

while (! fim ){
System.out.println("Eu bebo chocolate quente.");
}

while (! fim ){
System.out.println("Eu bebo café.");
}
}
…. Essa linha será executada?
Como faço para executá-la?
Threads (herança)
Usando threads:
public class ChocolateThread extends Thread {

public void run() {

while (true)
System.out.println("Eu bebo chocolate");
}
}

public class CafeThread extends Thread {

public void run() {

while (true)
System.out.println("Eu bebo café");
}
}
Threads (herança)

….
public static void main(String[] args) {

ChocolateThread co = new ChocolateThread();


co.start();

CafeThread ca = new CafeThread();


ca.start();
Executando as
while ( true ){
threads
System.out.println(“ocioso...");
}
}
….
Threads (herança)
Configurando a prioridade:
Threads (herança)
Configurando a prioridade:
….
public static void main(String[] args) {

ChocolateThread co = new ChocolateThread();


co.setPriority(5);
co.start();

CafeThread ca = new CafeThread();


co.setPriority(1);
ca.start();

while ( true ){
System.out.println(“ocioso...");
}
}
….
Threads (herança)
Pausando uma thread:
public class CafeThread extends Thread {

public void run() {

while (true){
System.out.println("Eu bebo café");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Threads (herança)
Esperando uma thread finalizar:
public static void main(String[] args) {
....
co.start();
ca.start();

try {
//espera 3s ou o fim da thread
//para continuar a execução do programa.
co.join(3000);
ca.join(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("=====chegou ao final.=====");
Threads (interface)
public class ChocolateThread implements Runnable {

public void run() {

while (true)
System.out.println("Eu bebo chocolate");
}
}

public class CafeThread implements Runnable {

public void run() {

while (true)
System.out.println("Eu bebo café");
}
}
Threads (interface)

….
public static void main(String[] args) {

Thread t1 = new Thread(new ChocolateThread1());


t1.start();

Thread t2 = new Thread(new CafeThread1());


t2.start();

while ( true ){
System.out.println(“ocioso..."); Executando as
} threads
}
….
Threads
(Compartilhamento de recursos limitados)
Threads
(Corrompendo os dados)
Threads
(Comunicação entre as threads)
Threads
(Exemplo)
Threads
(Exemplo - Produtor)
Threads
(Exemplo - Consumidor)
Threads
(Monitor com wait() e notify() )
Threads
(Problemas de sincronização)
Threads
(Exemplo de deadlock)
Threads
(Exemplo de deadlock)
Threads
(alguns métodos importantes)
Threads (interface)
Exemplo implementando a interface Runnable.
….
public static void main(String[] args) {

new Thread(new Runnable() {


@Override
public void run() {
//código para executar em paralelo
System.out.println(“ID: “ + Thread.currentThread().getId());
System.out.println(“Nome: “ + Thread.currentThread().getName());
System.out.println(“Prioridade: “ + Thread.currentThread().getPriority());
System.out.println(“Estado: “ + Thread.currentThread().getState());
}
}).start();
}
….
Threads (exemplo)
public class Principal extends Frame {

private Canvas canvas;

public Bola() throws InterruptedException {


setSize(700, 600);
setLocationRelativeTo(null);
setTitle("Criando Threads");

addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
} });
setVisible(true);

canvas = new Canvas();


add(canvas);

\\ continua no próximo slide....


Threads (exemplo)
Bolinha b1 = new Bolinha(canvas, Color.green);
//b1.setPriority(1);
b1.start();
Thread.sleep(1300);

\\ ....Crie seis “bolinhas”: duas verdes, duas azuis e duas vermelhas....

Bolinha b6 = new Bolinha(canvas, Color.red);


//b6.setPriority(10);
b6.start();
Thread.sleep(1300);

\\Hora h = new Hora(this);


\\h.start();
}
public static void main(String[] args) throws InterruptedException {

Bola b = new Bola();


}
}
Threads (exemplo)
public class Bolinha extends Thread {

private Canvas caixa;


private Color cor;
private int x = 0;
private int y = 0;
private int dx = 2; //velocidade
private int dy = 2;
private static final int XSIZE = 80;
private static final int YSIZE = 80;

public Bolinha(Canvas c, Color cor) {


caixa = c;
this.cor = cor; }

public void desenha() {


Graphics g = caixa.getGraphics();
g.setColor(cor);
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose(); } \\ continua no próximo slide....
Threads (exemplo)
public void move() { if (y < 0) {
y = 0;
if (!caixa.isValid()) return; dy = -dy;
}
Graphics g = caixa.getGraphics(); if (y + YSIZE >= d.height) {
g.setColor(Color.white); y = d.height - YSIZE;
g.fillOval(x, y, XSIZE, YSIZE); dy = -dy;
x += dx; }
y += dy;
g.setColor(cor);
Dimension d = caixa.getSize(); g.fillOval(x, y, XSIZE, YSIZE);
if (x < 0) { g.dispose();
x = 0; }
dx = -dx;
} \\ continua no próximo slide....
if (x + XSIZE >= d.width) {
x = d.width - XSIZE;
dx = -dx;
} \\ continua ao lado....
Threads (exemplo)
public void run() {
desenha();
for (int i = 0; i <= 100000; i++) {
move();
try {
this.sleep(15);
} catch (InterruptedException e) {
System.out.println(“Erro”);
}
}
}
}
Threads (exemplo)
public class Hora extends Thread {

public Frame frame;

public Hora(Frame frame) {


this.frame = frame;
}

@Override
public void run() {

while (true) {
Calendar c = Calendar.getInstance();
String hora = "Criando Threads - " +
c.get(Calendar.HOUR) + ":" +
c.get(Calendar.MINUTE) + ":" +
c.get(Calendar.SECOND);
\\ continua no próximo slide....
Threads (exemplo)
System.out.println(hora);
frame.setTitle(hora);

try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

}
Threads (exercício)
1) Faça um programa que imprima os números pares de 0 a 1000. Para isso
Utilize threads, para cada faixa de 100 números dispare uma thread.

2) Implemente um simulador para uma fila de banco. Existem vários caixas


que atendem (demoram um tempo aleatório para atender um cliente)

Implemente duas situações


a) Uma fila para cada caixa
b) Uma fila para todos os caixas

Compare o número de pessoas atendidas em cada situação


Threads (Exercício 01 - solução)
public class Tread1 extends Thread {

private int ini;


private int fim;

public Tread1(int ini, int fim) {


this.ini = ini;
this.fim = fim;
}

@Override
public void run() {

for (int i = ini; i<fim; i++)


System.out.println(
Thread.currentThread().getName()+" "+i);
}
}
Threads (Exercício 01 - solução)

public class Principal {

public static void main(String[] args) {

new Tread1(0,49).start();
new Tread1(50,99).start();
new Tread1(100,150).start();
}

}
Threads (Exercício 02 a - solução)
public class Fila {
private ArrayList<String> fila = new ArrayList<>();
public void entra(String pessoa){
fila.add(pessoa); Cada caixa tem sua própria fila.
}

public String sai(){


if (fila.size() > 0)
return fila.remove(0);
else
return null;
}

public int tamanho(){


return fila.size();
}
}
public class Caixa extends Thread {
private Fila fila;
private String nome;
Threads
(Exercício 02 a - solução)
public Caixa(String nome) {
this.fila = new Fila();
this.nome = nome;}
@Override
public void run() {
while (true) {
if (fila.tamanho() > 0) {
System.out.println(nome + "->" + fila.sai());
try {
sleep((int) (Math.random() * 3000));
} catch (InterruptedException e) { O caixa consome e dorme
aleatoriamente
e.printStackTrace();
}
} else {
int qtde = (int) (Math.random()*10);
for (int i = 0; i < qtde; i++)
fila.entra(String.valueOf(i));
} O caixa produz aleatoriamente
}
}
}
Threads (Exercício 02 a - solução)

public class Principal {

public static void main(String[] args) {

new Caixa("Cx 1").start();


new Caixa("Cx 2").start();

}
}
Threads (Exercício 02 b - solução)
public class Fila {
private ArrayList<String> fila = new ArrayList<>();

public synchronized void entra(String pessoa){


fila.add(pessoa); Como foi adicionado uma pessoa, a
this.notify(); thread notifica possíveis thread em
} estado de espera, isso é um aviso
aos consumidores para consumir.
public synchronized String sai(){
if (fila.size() <= 0)
try { Se não tem nada para consumir
a thread deve dormir.
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
return fila.remove(0); } Nenhuma outra thread poderá
acessar as variáveis que estão
public synchronized int tamanho(){ dentro de um bloco sincronizado
quando outra thread está
return fila.size(); } executando esse trecho
}
Threads (Exercício 02 b - solução)
public class Caixa extends Thread {
private Fila fila;
private String nome;
public Caixa(Fila fila, String nome) {
this.fila = fila;
this.nome = nome; }
@Override
public void run() {
O caixa consome uma pessoa
while (true){
System.out.println(nome+"->"+fila.sai());
try {
sleep( (int) (Math.random()*3000));
} catch (InterruptedException e) {
e.printStackTrace(); O caixa dorme aleatoriamente
}
}
}
}
Threads (Exercício 02 solução)
public class RecebiCliente extends Thread {
private Fila fila;
public RecebiCliente(Fila fila) {
this.fila = fila; }
@Override
public void run() {
double senha = 1;
while (true){
System.out.println("Emitiu senha "+senha);
fila.entra("Cliente " + senha++);
try { Essa classe representa a
produção de pessoas, ou a
sleep( (int) (Math.random()*1000)); porta de entrada do banco
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Threads (Exercício 02 b - solução)

public class Principal {

public static void main(String[] args) { Cria o objeto compartilhado

Fila fila = new Fila();


new RecebiCliente(fila).start();
new Caixa(fila, "Cx 1").start(); Cria o produtor
new Caixa(fila, "Cx 2").start();
}
}
Cria dois consumidores
Theads (sockets)
Socket é um mecanismo de comunicação, usado normalmente
para implementar um modelo cliente/servidor, que permite a
troca de mensagens entre os processos de uma
máquina/aplicação servidor e de uma máquina/aplicação cliente.
Theads (sockets)
A API em java que trata Sockets está no pacote java.net
.

Através do TCP, é possível criar um fluxo entre dois computadores, esse


protocolo vai garantir a entrega dos pacotes que transferirmos - como é
mostrado no diagrama abaixo:

Existe o IP para identificar uma máquina, e a porta é a solução para identificar


diversas aplicações em uma máquina. Esta porta é um número de 2 bytes,
varia de 0 a 65535.
Theads (sockets)
Mas se um cliente se conecta a um programa rodando na porta 80 de um
servidor, enquanto ele não se desconectar dessa porta, será impossível que
outra pessoa se conecte?

Acontece que, ao efetuar e aceitar a conexão, o servidor redireciona o cliente


de uma porta para outra, liberando novamente sua porta inicial e permitindo
que outros clientes se conectem novamente

Em Java, isso deve ser feito através de threads e o processo de aceitar a


conexão deve ser rodado o mais rápido possível.
Theads (sockets)
Troca de informações entre cliente e servidor:

A socket do cliente tem um InputStream, que é enviado pelo OutputStream do


servidor, por sua vez, a socket do cliente também tem um OutputStream, que
transfere tudo para o servidor, essa saída é acessada da mesma forma, via
InputStream .
Theads (sockets)

Teremos dois projetos em Java, o cliente e o servidor. Você pode


implementar os dois no seu próprio computador, mas lembre-se de executar
primeiro o servidor e somente depois o cliente.

Para exemplificar, iremos implementar uma aplicação que simula um chat.

Será implementada algumas versões até chegarmos em algo satisfatório


Theads (sockets)
public class Servidor {
private int porta; Servidor (versão 1)

public Servidor(int porta) {


this.porta = porta;
}

public void executa() throws IOException {

ServerSocket servidor = new ServerSocket(porta);


System.out.println("Server: Porta " + porta + " aberta!");
O servidor
fica parado
esperando Socket cliente = servidor.accept();
uma
conexão.
System.out.println("Server: Nova conexão com um cliente " +
cliente.getInetAddress().getHostAddress());

Scanner s = new Scanner(cliente.getInputStream());


Imprime o while (s.hasNextLine()) {
que está System.out.println("Server: " + s.nextLine());
dentro do
inputSteam
}
s.close();
servidor.close();
cliente.close();
}
}
Theads (sockets)
Classe
Servidor (versão 1)
responsável
por
instanciar o
servidor.

public class PrincipalServer {

public static void main(String[] args) throws IOException {


new Servidor(12345).executa();
}

O grande problema na implementação da classe Servidor é que apenas um


computador consegue conectar nessa porta e nesse ip.
Theads (sockets)
public class Cliente {
Cliente (versão 1)
private String host;
private int porta;

public Cliente(String host, int porta) {


this.host = host;
this.porta = porta;
}

public void executa() throws UnknownHostException, IOException {


Objeto
Estabelece Socket cliente = new Socket(this.host, this.porta); responsável,
por fornecer
a conexão
a saída para
com o
servidor
Scanner teclado = new Scanner(System.in); o servidor.

PrintStream saida = new PrintStream(cliente.getOutputStream());


System.out.println("Client: O cliente se conectou ao servidor!");

while (teclado.hasNextLine()) {
saida.println(teclado.nextLine());
}
Looping para saída de
cliente.close(); dados para o servidor.
teclado.close();
}
}
Theads (sockets)
Cliente (versão 1)

public class PrincipalClient {

public static void main(String[] args) throws UnknownHostException, IOException {

new Cliente("127.0.0.1",12345).executa();
}

Classe
}
responsável por
instanciar o
cliente.

O grande problema na implementação da classe Cliente é que não


recebemos informações do servidor, somente enviamos.
Theads (sockets)
public class Servidor {
private int porta;
Servidor (versão 2)
private List<Socket> clientes = new ArrayList<>();

public Servidor(int porta) { Agora temos uma lista


this.porta = porta; com todas as conexões

public void executa() throws IOException {

ServerSocket servidor = new ServerSocket(porta);


System.out.println("Server: Porta " + porta + " aberta!");
O servidor
está sempre
esperando while (true) {
uma Socket cliente = servidor.accept();
conexão

System.out.println("Server: Nova conexão com o cliente " +


cliente.getInetAddress().getHostAddress());
Cria uma thread
para tratar a
mensagem e this.clientes.add(cliente);
libera o servidor
para receber
novas TratadorDeMensagemDoCliente tc = new
requisições TratadorDeMensagemDoCliente(cliente, this);
new Thread(tc).start();
}
} //continua no próximo slide...
Theads (sockets)
Método Servidor (versão 2)
responsável por
enviar mensagem
a todas as outras
conexões, exceto a
conexão atual.

public void distribuiMensagem(Socket clienteQueEnviou, String msg) {


for (Socket cliente : this.clientes) {
if (!cliente.equals(clienteQueEnviou)) {
try {
PrintStream ps = new
PrintStream(cliente.getOutputStream());
ps.println(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

}
Theads (sockets)
Cliente (versão 2)

public void executa() throws UnknownHostException, IOException {

Socket cliente = new Socket(this.host, this.porta);

Scanner teclado = new Scanner(System.in);

PrintStream saida = new PrintStream(cliente.getOutputStream());


System.out.println("Client: O cliente se conectou ao servidor!");

RecebedorDeMensagemDoServidor r = new
RecebedorDeMensagemDoServidor(cliente.getInputStream());
new Thread(r).start();

while (teclado.hasNextLine()) { Inserimos apenas


saida.println(teclado.nextLine()); essa thread para
ler o “echo” do
} servidor.

cliente.close();
teclado.close();

}
Theads (sockets)
Cliente (versão 2)
Thread que fica
imprimindo o tempo
todo o inputStream
fornecido pelo
Servidor.

public class RecebedorDeMensagemDoServidor implements Runnable {

private InputStream servidor;

public RecebedorDeMensagemDoServidor(InputStream servidor) {


this.servidor = servidor;
}

public void run() {


try(Scanner s = new Scanner(this.servidor)){
while (s.hasNextLine()) {
System.out.println(s.nextLine());
}
}
}

}
Theads (sockets)
Resumindo

Lembre que você precisará de no mínimo 2 threads para o cliente e 2 para o servidor
Teclas de atalho no Eclipse
Tecla Ação
Ctrl + Space Comando usado para pedir para o Eclipse terminar
de completar o código pra você.
Ctrl + N Para criar algo novo, como uma classe, interface,
enumeração, etc. É útil para você não ter que pegar o
mouse e ir em File -> New.
Ctrl + Shift + F Usado para indentar seu código corretamente,
alinhando os espaços dentro dos métodos, if, for, etc
Ctrl + Shift + O Organiza os imports, ou seja, retira as declarações
que não são mais usados, i inseri as que estão
faltando.
Alt + Shift + R Renomear refatorando, assim, você pode renomear
uma classe, atributo, método ou variável alterando
também as referências para esse nome ao longo do
código
Teclas de atalho no Eclipse
Tecla Ação
Ctrl + W Usando quando você quer fechar um arquivo que já
terminou a edição
Ctrl + Shift + W Fechar todas as janelas de edição, Se tiver muitos
arquivos abertos e você quiser fechar todos, esse é o
comando.
Ctrl + D Comando serve para apagar uma linha inteira de
código
Ctrl + M Abrir a janela de código em tela cheia

Ctrl + 1 Ele é o atalho para o quick fix, ou seja, sempre que


seu código estiver com algum erro de compilação ou
aviso (warning), você pode tentar usar esse atalho
para o Eclipse te sugerir o que você pode fazer para
resolver o problema.
Teclas de atalho no Eclipse
Tecla Ação
Ctrl + Shift + T Esse atalho é útil para abrir o código de um tipo
(classe, interface, enumeração ou anotação), fazendo
a pesquisa pelo nome.
Ctrl + Shift + R Já este atalho serve para abrir um recurso no seu
projeto, como um arquivo texto, XML ou até mesmo de
um tipo Java.
Ctrl + E Pesquisar e navegar em arquivos abertos
Ctrl + F6 Navegar entre arquivos abertos
Ctrl + 3 Acesso rápido, por exemplo, para gerar os getters e
setters, basta digitar: ggas
Ctrl + Shift + L Listar todos os atalhos do Eclipse
Componentes GUI cap. 11
Interface Gráfica com o usuário

Os Componentes estão
agrupadas em dois
grandes pacotes:
1. java.awt
(pacote do núcleo)
2. javax.swing
(pacote de extensão).
Componentes GUI cap. 11
AWT - Abstract Windowing Toolkit

•Origem na versão 1.0 da plataforma Java 2.


•Estão diretamente associados com os recursos da
interface gráfica da plataforma do usuário.
•Aparência difere nos sistemas operacionais Microsoft
Windows e no Apple Macintosh.
•Componentes pesos-pesados, “herdam” a aparência
definida pela plataforma.
•Os componentes AWT estão desatualizados e foi
substituído pelo projeto Swing.
Componentes GUI cap. 11
Swing – componente padrão

•Foi criado em 1997 e se tornaram padrão a partir da


versão 1.2 da plataforma Java 2.
•Escritos, manipulados e exibidos completamente em Java,
sendo conhecidos como componentes Java puros.
•Maior nível de portabilidade e flexibilidade.
•Recebem um “J”, como, por exemplo: JLabel, JButton,
JFrame, JPanel, etc.
•São considerados peso-leve e fornecem funcionalidade e
aparência uniforme em todas as plataforma
Componentes GUI cap. 11
Hierarquia das Classes dos Componentes
•Os componentes AWT e Swing são
definidos na classe “Component”
•A classe “Container” dá suporte à
adição e posicionamento dos
componentes ao painel de conteúdo.
•“JComponent” define os tributos e
comportamentos específicos dos
componentes Swing.
Componentes GUI cap. 11
Conteiners – Base de estruturação dos GUI’s

•Dão suporte a exibição e agrupamento de outros


componentes, inclusive outros conteiners.
•Eles constituem a base onde os outros elementos são
anexados.
•Objeto da classe Container denominado contêiner, a qual,
atribuímos uma chamada ao método getContentPane( ).
•O painel de conteúdo compreende a área imediatamente
inferior a barra de título de uma janela, extendendo-se até
os limites da mesma.
•A classe Container define o método add(Component),
para adicionar elementos, e setLayout (LayoutManager).
Componentes GUI cap. 11
Conteiners – Base de estruturação dos GUI’s

•Qualquer programa que ofereça uma interface vai possuir


pelo menos um conteiner, que pode ser:
•JFrame - janela principal do programa;
•JDialog - janela para diálogos;
•JApplet - janela para Applets.
Componentes GUI cap. 11
Conteiners – JFrame

•Eles consistem em uma janela com barra de título e uma


borda e fornecem o espaço para a GUI do aplicativo ser
construída.
•Um dos poucos componentes GUI do Swing que não são
considerados de peso-leve, pois não são escritos
completamente em Java.
Componentes GUI cap. 11
Conteiners – JDialog

•Exemplo: JOptionPane.
•As caixa de diálogo podem ser configuradas como modais
ou não-modais, valendo-se do método setModal(boolean).
•As modais não permitem que qualquer outra janela do
aplicativo seja acessada até que seja tratada a solicitação
ou intervenção da caixa de diálogo. O comportamento
oposto se observa nas não-modais.
Componentes GUI cap. 11
Conteiners – JApplet

•Applet são programas Java que podem ser embutidos em


documentos HTML.
•Quando um navegador carrega uma página da Web que
contém um applet, ele baixa esse applet e o executa (o
navegador é chamado de contêiner de applets).
Componentes GUI cap. 11
Gerenciadores de layout
•Organizam os componentes GUI de um contêiner e, para
tal, devem ser configurados antes que qualquer membro
seja anexado ao painel de conteúdo.
•Distribuem os elementos no espaço que foi incumbido a
eles. Sua utilização poupa o programador da preocupação
de posicionar precisamente cada componente.
•Permitido apenas um gerenciador de leiaute por contêiner.
O que pode ser contornado fazendo uso de diversos
painéis (JPanel).
•Os layouts são:
(1) FlowLayout, (2) BorderLayout, (3) GridLayout
(4) BoxLayout, (5) CardLayout, (6) GridBagLayout.
Componentes GUI cap. 11
Gerenciadores de layout - FlowLayout
•É o gerenciador mais elementar (gerenciador padrão).
•Distribui os componentes pelo contêiner
•Seqüencialmente, da esquerda para a direita e na ordem
em que foram adicionados.
•Seu comportamento assemelha-se a um editor de texto, já
que quando se alcança a borda do contêiner, os membros
são alocados na próxima linha.
Componentes GUI cap. 11
Gerenciadores de layout - BorderLayout
•Organizar os componentes GUI em cinco regiões:
NORTH, SOUTH, EAST, WEST e CENTER.
•Até cinco componentes podem ser adicionados (em
qualquer ordem) a um contêiner ou painel, sendo que cada
um deverá ocupar uma região.
•Acarreta-se que, no caso de mais de um elemento ser
adicionado à mesma área, somente o último anexado será
visível.
Componentes GUI cap. 11
Gerenciadores de layout - GridLayout
•O contêiner é dividido em linhas e colunas convenientes,
formando uma grade, que, à medida que os componentes
são anexados, é preenchida da célula superior esquerda
em direção à direita.
•Após preenchida a linha, o processo continua na linha
imediatamente inferior.
•Cada membro em um GridLayout tem a mesma largura e
comprimento.
Componentes GUI cap. 11
Gerenciadores de layout - BoxLayout
•Permite que os componentes GUI sejam organizados da
esquerda para direita (ao longo do eixo x) ou de cima para
baixo (ao longo do eixo y) em um contêiner ou painel.
•A classe Box fornece métodos estáticos para criarmos
caixas horizontais ou verticais que podem ser usadas para
acomodar componentes.
Componentes GUI cap. 11
Gerenciadores de layout - BoxLayout
createVerticalStrut(int), createHorizontalStrut(int):
Adicionam um componente invisível e tem uma altura fixa
em pixels (que é passada no argumento). É utilizado para
garantir uma quantidade fixa de espaço entre os
componentes GUI, caso a janela seja redimensionada.
createVerticalGlue(), createHorizontalGlue():
Adicionam cola vertical ou horizontal ao contêiner. A cola é
um componente invisível, sendo utilizada em componentes
GUI de tamanho fixo. Ela mantém uniforme o espaçamento
entre membros de um contêiner.
Componentes GUI cap. 11
Gerenciadores de layout - CardLayout
•A serventia desse gerenciador é que ele organiza os
componentes como se fossem cartas de um baralho.
Qualquer “carta” pode ser exibida na parte superior da
pilha, a qualquer momento, valendo-se dos métodos da
classe CardLayout. Cada “carta” é um contêiner.
•Na figurara abaixo a “Primeira e a Terceira Carta” foram
configuradas com o gerenciador BorderLayout e as
“Segunda e Quarta Cartas” foram criadas com o
gerenciador FlowLayout.
Componentes GUI cap. 11
Gerenciadores de layout - CardLayout
// cria um JPanel
monte = new JPanel();
// e o configura com CardLayout
gerenciadorDeCartas = new CardLayout();
monte.setLayout( gerenciadorDeCartas );

// configura a "carta1" e a adiciona ao JPanel "monte"


JPanel carta1 = new JPanel();
carta1.setLayout(new BorderLayout());
monte.add( carta1, label1.getText() ); // adicionando ao "monte“

// configura a "carta2" e a adiciona ao JPanel "monte"


JPanel carta2 = new JPanel();
carta2.setLayout(new FlowLayout());
monte.add( carta2, label2.getText() ); // adicionando ao "monte"

//buscando as cartas (este código podem ser acionados por botões)


gerenciadorDeCartas.first( monte );
gerenciadorDeCartas.next( monte );
gerenciadorDeCartas.previous( monte );
gerenciadorDeCartas.last( monte );
Componentes GUI cap. 11
Gerenciadores de layout - GridBagLayout
Este é o mais poderoso dos gerenciadores de leiaute. Ele é
semelhante ao GridLayout, já que ambos utilizam uma grade
para dispor os componentes GUI.

No entanto, o GridBagLayout é muito mais flexível e admite


variações no tamanho dos elementos, tanto no número de
linhas, como no de colunas, isto é, os componentes podem
ocupar múltiplas linhas ou colunas.

Para utilizarmos esse gerenciador, devemos instanciar um


objeto GridBagConstraints, que vai fazer o trabalho de
distribuir os componentes.
Componentes GUI cap. 11
Gerenciadores de layout - GridBagLayout
•Inicialmente, propomos que o leitor esboce um rascunho da
GUI em um papel e depois trace linhas e colunas sobre ele,
respeitando as extremidades dos componentes que deseja criar,
de modo que cada elemento fique incluso em uma ou mais
células resultante da interseção entre linhas e colunas.
• Posteriormente, deve-se numerar as linhas e colunas,
iniciando a contagem pelo zero. Isso é válido para definirmos os
“endereços” nos quais os membros serão alocados. Veja um
esboço do que foi anteriormente descrito:
Componentes GUI cap. 11
Gerenciadores de layout - GridBagLayout
Os GUIs são inseridos, baseando-se em restrições das
seguintes variáveis de instância da classe GridBagConstraints:
•gridx define a coluna em que o canto superior esquerdo do
componente será colocado.
•gridy define a linha em que o canto superior esquerdo do
componente será colocado.
•gridwidth determina o número de colunas que o componente
ocupa.
•gridheight define o número de linhas que o componente
ocupa.
Componentes GUI cap. 11
Gerenciadores de layout - GridBagLayout
• fill especifica quanto da área destinada ao componente (o
número de linhas e colunas) é ocupada. A essa variável
atribui-se uma das seguintes constantes de
GridBagConstraints:
NONE indica que o elemento não crescerá em nenhuma
direção. É o valor default.
VERTICAL sinaliza que o elemento crescerá verticalmente.
HORIZONTAL informa que o elemento crescerá
horizontalmente.
BOTH indica que o elemento crescerá em ambas as
direções.
Componentes GUI cap. 11
Gerenciadores de layout - GridBagLayout
•anchor especifica a localização do elemento na área a ele
destinada quando este não preencher a área inteira. A essa
variável atribui-se uma das seguintes constantes de
GridBagConstraints:
NORTH, NORTHEAST;
EAST, SOUTHEAST;
SOUTH, SOUTHWEAST;
WEST, NORTHWEST;
CENTER, que é o valor default
Componentes GUI cap. 11
Gerenciadores de layout - GridBagLayout
•weightx define se o componente irá ocupar espaço extra
horizontal, caso a janela seja redimensionada. O valor zero indica
que o elemento não se expande horizontalmente. Porém, se um
membro da mesma coluna possuir a weightx configurada com um
valor maior que zero, nosso elemento crescerá horizontalmente na
mesma proporção que os outros membros dessa coluna. Isso
ocorre porque cada componente deve ser mantido na mesma linha
e coluna que foi endereçado originalmente.

•weighty define se o componente irá ocupar o espaço extra vertical,


oriundo do redimensionamento da janela. O valor zero indica que o
elemento não se expande verticalmente. Porém, se um membro da
mesma linha possuir a weighty configurada com um valor maior que
zero, nosso elemento crescerá verticalmente na mesma proporção
que os outros membros dessa linha.
Componentes GUI cap. 11
Gerenciadores de layout - GridBagLayout
// método que ativa as restrições e distribui os componentes
private void adicionarComponente( Component componente,
int linha, int coluna, int largura, int altura )
{
// configura gridx e gridy
restricoes.gridx = coluna;
restricoes.gridy = linha;

// configura gridwidth e gridheight


restricoes.gridwidth = largura;
restricoes.gridheight = altura;

// configura restricoes e anexa cada componente


layout.setConstraints( componente, restricoes );
container.add( componente );
}
Componentes GUI cap. 11
Gerenciadores de layout – Null-Layout

Uma outra maneira de gerenciar o layout de um


contêiner é atribuir ao método setLayout(LayoutManager) um
argumento null e depois ajustar o posicionamento em x, y,
bem como a largura e altura de cada componente com o
método algumComponente.setBounds(int, int, int, int). Os
argumentos obedecem a ordem citada acima. Esta talvez seja
a maneira mais árdua de gerenciarmos a disposição dos
elementos GUI.

Você também pode gostar