Você está na página 1de 42

Revisão: Orientação a

Objetos e Java
Modelos
• Abstrações do mundo real
• Como um objeto ou mecanismo
do mundo real funciona?
– Quais são as informações
(atributos) que ele representa?
– Que ações podemos executar com
estas informações?
• Limites de modelos
Orientação a Objetos
• Paradigma de programação onde:
– Modelamos coisas do mundo real para que possam
ser processadas por programas de computador.
– Descrevemos modelos através de seus atributos
(dados) e operações.
• Criamos classes a partir destes modelos
usando uma linguagem de programação
orientada a objetos.
• Criamos instâncias destas classes para
processamento dos seus dados.
• Alguém cria as classes, alguém usa as
classes em suas aplicações.
Encapsulamento
• Oculta dados para que estes
sejam processados somente da
forma planejada.
• Uma interface existe para uso
da classe que encapsula os
dados.
• Algumas operações também
podem ser ocultadas do usuário
da classe.
UML
• Unified Modeling Language
– Esquemas para representação de classes e sua
interação Nome da
• Diagrama de classes: Classe
CartaoDePonto
Campos da
-código:int
Classe (atributos
-horasTrab:int
ou dados)
-valorHora:float

+marcaEntrada(Hora ):voi d Métodos da


+marcaSaída(Hora): void Classe
+calculaSalário(): float (operações)
Codificação em Java
CartaoDePonto /**
* Esta é a classe CartaoDePonto. Representa os dados
* de um cartão de ponto de um trabalhador em um
-código:int * determinado dia.
-horasTrab:int */
public class CartaoDePonto
-valorHora:float {
private int código;
private int horasTrabalhadas;
+marcaEntrada(Hora ):voi d private float valorHora;
+marcaSaída(Hora): void public void marcaEntrada(Hora agora)
+calculaSalário(): float {
// registra a hora de entrada
}

Esqueleto de uma public void marcaSaída(Hora agora)


classe: não contém o {
// registra a hora de saída
que os métodos fazem. }

public float calculaSalário()


{
// calcula e retorna o salário
}

}
Codificação em Java
• Nomes de classes:
– Seguem padrão UsaMaiusculasEmCadaPalavra
– Não devem ter acentos
– Nome da classe + .java = nome do arquivo
– Padrão: public class MinhaClasse
• Deve ser declarada no arquivo MinhaClasse.java
Codificação em Java
• Modificadores de acesso:
– public: permite que o campo ou método seja
acessado de outra classe.
– private: o campo ou método somente pode ser
acessado da classe que o contém
– Normalmente campos são todos private
(encapsulamento) e métodos são todos public.
Classes devem ser public.
Codificação em Java
• Tipos de dados para representação de
atributos:
– boolean, char, short, int, long, float, double:
tipos nativos
– String: classe que pode ser usada como tipo
nativo
– void: não é um tipo, usado para indicar que um
método não retorna nada
Codificação em Java
• Nomes de campos
– Seguem padrão começaEmMinúsculas
– Podem conter acentos
– Somente um tipo por campo
– Vários campos do mesmo tipo podem ser
declarados ao mesmo tempo
– Exemplos:
• private int númeroDePessoas;
• public boolean éBolsista;
• public String nomeDoAluno;
• public byte dia,mês;
• public float nota1,nota2,nota3;
Codificação em Java
• Nomes de métodos
– Seguem padrão começaEmMinúsculas
– Podem conter acentos
– Podem ter ou não argumentos (entre parênteses)
• Se não houver argumentos, usar parênteses sem nada
– Devem ter um único tipo de retorno ou void
• Se houver tipo de retorno diferente de void, deve
retornar um valor do tipo declarado
– Exemplos:
• private int calculaFatorial()
• public void setÉBolsista(boolean éBolsista)
• public boolean getÉBolsista()
• public float média(float número1,float número2)
Codificação em Java
• Assinatura de um método
– Nome do método mais argumentos
– Somente métodos com assinaturas compatíveis
podem ser executados
• int pode ser visto como long, float, double
• float pode ser visto como double
• double não pode ser visto como int, etc.
– Assinaturas incompatíveis causam erros de
compilação
• public static void main(String[] args)
– Método “mágico”, permite que uma classe seja
executada como um programa.
Escrevendo Métodos
• Todo o processamento é feito dentro de
métodos
– Declaração de variáveis locais (da mesma forma
que campos mas sem modificadores de acesso)
– Criação de instâncias se necessárias
– Laços, decisões, entrada e saída
Sobrecarga
• Podemos ter métodos com o mesmo nome
mas assinaturas diferentes
public float calculaSalárioDoDia()
{
// assume que foram trabalhadas oito horas
}

public float calculaSalárioDoDia(int horas)


{
// usa o número de horas dado como argumento
}

public float calculaSalárioDoDia(int horas,int minutos)


{
// usa o número de horas e minutos dados como argumento
}

• Exemplo: System.out.println
Arrays
• Arrays de dados
– Podem ser usados como campos, argumentos,
variáveis, etc.
– Contém vários dados do mesmo tipo com um
único nome
– Índices permitem acesso a dados individuais
– Devem ser alocados

int[] idades = new int[20];


idades[6] = 23;
boolean[] bolsistas;
bolsistas = new boolean[50];
bolsistas[32] = true;
double[] salários;
salários[0] = 10000;
Instanciando Classes
• Quando precisamos de uma instância de uma
classe:
NomeDaClasse nomeDaInstância = new NomeDaClasse();

• Podemos declarar para instanciar depois:


NomeDaClasse instância1,instância2,instância3;
instância1 = new NomeDaClasse();
instância3 = new NomeDaClasse();

• Somente podemos executar métodos de


classes instanciadas (exceto static):
instância1.umMétodo(); // OK
instância2.umMétodo(); // Erro de execução
Métodos Estáticos
• São declarados com a palavra-chave static
public static int entraValor(int mínimo,int máximo)
{
// Corpo do método
}

• Funcionam como subrotinas


• Suas classes não precisam ser instanciadas
para que os métodos sejam executados
• Podem ser usadas em pequenas aplicações
onde a criação de classes não seja necessária
ou justificável
Exemplo
public class ContaBancaria
{
private String nome;
Classe que representa
private float saldo; um conceito (modelo)
public void deposita(float valor)
{
saldo = saldo + valor;
} Aplicação que usa
public void retira(float valor)
{ outras classes
if (saldo >= valor)
saldo = saldo - valor;
} public class DemoContaBancaria
public float saldo() {
{ public static void main(String[] args)
return saldo; {
} ContaBancaria exPrefeito = new ContaBancaria();
} exPrefeito.deposita(100.0f);
exPrefeito.retira(50.0f);
exPrefeito.deposita(1200.0f);
System.out.println("O saldo do ex-prefeito é "+
exPrefeito.saldo()); // 1250.0
ContaBancaria exSenador = new ContaBancaria();
exSenador.deposita(2200.0f);
exSenador.retira(120.0f);
System.out.println("O saldo do ex-senador é "+
exSenador.saldo()); // 2080.0
}
}
Construtores
• O que seria retornado com:
ContaBancaria exPrefeito = new ContaBancaria();
System.out.println("O saldo do ex-prefeito é "+
exPrefeito.saldo());
– Campos não inicializados são iguais a zero (ou
null ou false)
– Se quisermos inicializar algo antes de poder usar a
classe, devemos criar construtores
– Métodos iguais aos outros exceto que:
• Não devem retornar nada, nem mesmo null
• Devem ter exatamente o mesmo nome da classe
Construtores
public class ContaBancaria
{ O construtor é sempre o
private String nome; primeiro método a ser
private float saldo;
executado em uma classe.
public ContaBancaria(String n,float s)
{ É executado quando criamos
nome = n;
saldo = s; a instância com new
}
Garante que não podemos
public void deposita(float valor)
{ criar instâncias sem passar
saldo = saldo + valor; argumentos previstos na
}
classe
public void retira(float valor)
{
if (saldo >= valor) public class DemoContaBancaria
saldo = saldo - valor;
} {
public static void main(String[] args)
public float saldo() {
{ ContaBancaria exPrefeito = new ContaBancaria();
return saldo; ContaBancaria exSenador =
} new ContaBancaria("Senador X",1200f);
}
} }
Condicionais: if/else
• Expressões que definem caminhos de
execução nos métodos
• if(expressão booleana) comandos;
• if(expressão booleana) { comandos; }
if (saldo >= valor)
saldo = saldo - valor;
• if(expressão booleana) { comandos; }
else { comandos; }
if (saldo >= valor)
saldo = saldo - valor;
else
System.out.println("Não tem saldo.");
Expressões booleanas
• Valores booleanos: true e false
• Expressões de comparação:
– Numéricas
• a > b; a < b; a >= b; a <= b; a == b; a != b
– Booleanas
• a == true (mesmo que a); b == false (mesmo que !b)
– Comparação de Strings
• a.equals(b)
• Combinações:
– “e” lógico: &&
– “ou” lógico: ||
– “não” lógico: !
Condicionais:switch
• Seleciona uma entre várias opções e executa
comandos
– Argumento é sempre um enumerável
– case: corresponde a uma das opções
– break: evita que comandos de case seguintes
sejam executados public byte diasNoMês(int mês)
– default: será executado {
byte dias;
se nenhum case tiver a switch(mês)
{
opção correta case 2: dias = 28; break;
case 4:
case 6:
case 9:
case 11: dias = 30; break;
default: dias = 31;
}
return dias;
}
Laços: while
• while(condição booleana) { comandos; }
public static int entraValor(int mínimo,int máximo)
{
int valor = mínimo-1;
while((valor < mínimo) || (valor > máximo))
{
String input =
JOptionPane.showInputDialog("Entre um valor entre "+
mínimo+" e "+máximo);
valor = Integer.parseInt(input);
}
return valor;
}

public static void main(String[] args)


{
int valor = entraValor(10,20);
System.out.println(valor);
}
Laços: for
• for(inicialização;verificação;atualização)
{ comandos; }
• Muito útil para contadores
public static long fatorial(int valor)
{
long resultado = 1;
for(int contador=1;contador<=valor;contador++)
{
resultado = resultado * contador;
}
return resultado;
}

public static void main(String[] args)


{
long valor = fatorial(15); // 1307674368000
System.out.println(valor);
}
Associação, Agregação e Composição
• Representam relações entre objetos
– Associação: um objeto é associado a outro e
pode mandar mensagens para este.
– Agregação: representa relações parte/todo, onde
uma parte não pode conter um todo. A parte pode
existir independentemente do todo.
– Composição: representa relações parte/todo
onde a parte é geralmente controlada pelo todo.
• Nem sempre a distinção é clara !

Referência: http://ootips.org/uml-hasa.html
Exemplo: Relação 1 para 1

public class Motor


{
private float potência;
private String combustível;
public Motor(float pot,String comb)
{
potência = pot;
combustível = comb;
}
public void imprimeDados()
{
System.out.println("Motor: com "+potência+" cavalos, "+
"movido a "+combustível);
}
}
Exemplo: Relação 1 para 1

public class Automovel


{
private String modelo;
private short ano;
private Motor motor;
public Automovel(String mod,short a,Motor mot)
{
modelo = mod;
ano = a;
motor = mot;
}
public void imprimeDados()
{
System.out.println("Modelo:"+modelo);
System.out.println("Ano:"+ano);
motor.imprimeDados();
}
}
Exemplo: Relação 1 para 1

public class TesteAutomovel


{
public static void main(String[] args)
{
Motor motFusca = new Motor(47f,"gasolina");
Automovel fusca66 = new Automovel("Fusca",(short)1966,motFusca);
fusca66.imprimeDados();

Automovel beetle2002 =
new Automovel("New Beetle",(short)2002,
new Motor(150f,"gasolina"));
beetle2002.imprimeDados();
}
}
Exemplo: Relação 1 para N (1..*)

• Para cada pedido podemos ter N instâncias de Item


• Podemos declarar N instâncias da classe Item na
classe Pedido
– Como saber o valor de N quando escrevemos a classe
Pedido?
• Podemos usar arrays
• Podemos usar a classe Vector
Usando a classe Vector
import java.util.Vector;
...
Vector v = new Vector();
String nome1 = "Bigus";
String nome2 = "Petchel";
String nome3 = "Buckland";
v.add(nome1);
v.add(nome2);
v.add(nome3);
v.add("Witten");
System.out.println(v); // [Bigus, Petchel, Buckland, Witten]
System.out.println(v.size()); // 4
String segundo = (String)v.elementAt(1); // Petchel
v.removeElementAt(1);
String terceiro = (String)v.elementAt(2); // Witten
for(int elemento=0;elemento<v.size();elemento++)
{
System.out.println((elemento+1)+" -> "+v.elementAt(elemento));
}
String último = (String)v.elementAt(v.size()); // Exceção !
Exemplo: Relação 1 para N (1..*)

public class Data


{
private byte dia,mês;
private short ano;

public Data(byte d,byte m,short a)


{
dia = d; mês = m; ano = a;
}

public void imprime()


{
System.out.println("Data: "+dia+"/"+mês+"/"+ano);
}
}
Exemplo: Relação 1 para N (1..*)
public class Item
{
private int código;
private int quantidade;
private float preçoUnitário;

public Item(int cod,int quant,float preço)


{
código = cod; quantidade = quant; preçoUnitário = preço;
}
public void imprime()
{
System.out.println("Item: código "+código+", "+
quantidade+" unidades a "+
preçoUnitário+" cada.");
}
public float custoTotal()
{
return quantidade*preçoUnitário;
}
}
Exemplo: Relação 1 para N (1..*)

import java.util.Vector;

public class Pedido


{
private int número;
private int vendedor;
private Data dia;
private Vector lista;

public Pedido(int n,int v,Data d,Item primeiro)


{
número = n;
vendedor = v;
dia = d;
lista = new Vector();
adicionaItem(primeiro);
}
Exemplo: Relação 1 para N (1..*)
public void adicionaItem(Item i)
{
lista.add(i);
}

public float calculaTotal()


{
float total = 0f;
for(int qual=0;qual<lista.size();qual++)
{
Item umItem = (Item)lista.elementAt(qual);
total = total + umItem.custoTotal();
}
return total;
}
Exemplo: Relação 1 para N (1..*)
public void imprime()
{
System.out.println("Pedido #"+número+" do vendedor “
+vendedor);
dia.imprime();
System.out.println("Itens:");
for(int qual=0;qual<lista.size();qual++)
{
Item umItem = (Item)lista.elementAt(qual);
System.out.print(" * ");
umItem.imprime();
}
System.out.println("Total do pedido: "+calculaTotal());
}

}
Exemplo: Relação 1 para N (1..*)
public class TestePedido
{
public static void main(String[] args)
{
Data hoje = new Data((byte)19,(byte)10,(short)2003);

Item i1 = new Item(1215,10, 9.45f);


Item i2 = new Item(1217, 1,21.00f);
Item i3 = new Item(1223, 1,22.05f);
Item i4 = new Item(1249, 3,50.95f);

Pedido p = new Pedido(1,3,hoje,i1);

p.adicionaItem(i2);
p.adicionaItem(i3);
p.adicionaItem(i4);
Pedido #1 do vendedor 3
p.imprime(); Data: 19/10/2003
} Itens:
} * Item: código 1215, 10 unidades a 9.45 cada.
* Item: código 1217, 1 unidades a 21.0 cada.
* Item: código 1223, 1 unidades a 22.05 cada.
* Item: código 1249, 3 unidades a 50.95 cada.
Total do pedido:290.40002
Herança
• Agregação, associação e composição:
relações usa ou contém
• Herança: relações é-um-tipo-de
– Reutilizamos classes já existentes e descrevemos
as diferenças
– Também conhecida como relação de
especialização/generalização
– Classe herdeira herda todos os campos e métodos
mas só pode acessar os públicos
ClasseAncestral ClasseHerdeira
Herança: Exemplo
ContaBancaria ContaEspecial
- n omeCo rrentista: String - l imite: double
- s aldo: double + C ontaEspecial(String,doubl e,double)
+ C ontaB ancaria(String,double) + g etSaldo():double
+ d eposi ta(double):void
+ r etira (double):void
+ g etSal do():double
+ g etNom e():String

• Classe ContaEspecial herdará todos os métodos de


ContaBancaria menos o construtor
• Conta especial simulada como tendo saldo adicional
(limite)
• Problema: método getSaldo() de ContaBancaria não
serviria para ContaEspecial!
• Solução: sobreposição do método.
Herança: Exemplo
public class ContaBancaria
{
private String nomeCorrentista;
private double saldo;
public ContaBancaria(String n,double s)
{
nomeCorrentista = n;
saldo = s;
}

public double getSaldo() public void deposita(double quantia)


{ {
return saldo; saldo = saldo + quantia;
} }

public String getNome() public void retira(double quantia)


{ {
return nomeCorrentista; if (quantia < saldo)
} saldo = saldo - quantia;
}

}
Herança: Exemplo
public class ContaEspecial extends ContaBancaria
{
private double limite;
public ContaEspecial(String n,double s,double l)
{
super(n,s);
limite = l;
deposita(limite); // simula dinheiro a mais !
}
public double getSaldo()
{
return super.getSaldo()-limite; // saldo verdadeiro
}
}

• Palavra-chave super: permite a chamada de


método da classe ancestral
– Somente construtores podem executar construtores
Herança: Exemplo
public class TesteContaEspecial
{
public static void main(String[] args)
{
ContaBancaria minha = new ContaBancaria("Eu",200);
minha.retira(120);
minha.retira(100);
System.out.println(minha.getSaldo()); // 80
ContaEspecial gugu =
new ContaEspecial("Gugu",10000,2000);
gugu.retira(5000);
gugu.retira(6000);
System.out.println(gugu.getSaldo()); // -1000
}
}