Orientação a Objetos Básica
Material baseado na apostila FJ-11: Java e Orientação a Objetos do curso Caelum,
Ensino e Inovação, disponível para download em http://www.caelum.com.br/apostilas/
Objetivos
• Explicar o que é e para que serve orientação a objetos; • Conceituar classes, atributos e comportamentos
Modelos de Programação
• Programação “Espaguete”• Código totalmente desorganizado, impossível de manter
• Programação estruturada
• Dividir um problema grande em problemas menores
• Ênfase em “Como resolver o problema” – funcionalidade • Agrupamento do código em módulos de acordo com a
funcionalidade
• Programação orientada a objetos
• Ênfase nos dados envolvidos no problema, depois pensa-se nas
Problemas do paradigma procedural
• Duplicação de código• Dificuldade para reaproveitar o código feito por outro
programador.
• Pouco controle sobre os dados
• Pequena mudança na forma de armazenar um dado pode ter
grande impacto em todo o programa.
• Falta de controle sobre onde os dados são modificados
(dificuldade de garantir a integridade dos dados).
• Problemas podem ser resolvidos com disciplina de programação
Motivação: Problemas do paradigma procedural
cpf = formulario->campo_cpf valida(cpf)
• Quem é responsável pela validação do CPF? Todos os programadores.
• E se a idade do usuário tiver também de ser validada? E se não houver uma função para a validação?
if (idade > 18) ...
Motivação: Problemas do paradigma procedural
• Seria interessante poder concentrar essa responsabilidades em um lugar só
• Melhor ainda seria se conseguíssemos mudar essa
validação e os outros programadores nem precisassem ficar sabendo disso
Conceitos chave de OO
• Abstração• Levantamento dos dados e de suas características essenciais
(para o problema).
• Encapsulamento
• Agrupar os dados e as operações realizadas neles.
• Ocultação de informação – restringir o acesso aos dados a um
conjunto de operações. Não permitir acesso direto.
• Herança
• Especialização e Generalização.
Criando um tipo: A conta bancária
Atributos: O que toda conta tem e é importante para nós? – número da conta
– nome do correntista – saldo
Criando um tipo: A conta bancária
Métodos: O que toda conta faz e é importante para nós? – saca uma quantidade x
– deposita uma quantidade x
– imprime o nome do dono da conta – devolve o saldo atual
– transfere uma quantidade x para uma outra conta y – devolve o tipo de conta
Classe vs Objetos
Classe
Classe vs Objetos
• Todos os objetos de uma mesma classe têm os mesmos atributos e comportamentos (métodos), mas eles não são iguais → os valores dos atributos podem ser diferentes, o que pode influir na maneira como um objeto em particular realiza o seu comportamento.
Uma classe em Java
• Vamos começar apenas com o que uma Conta tem (seus atributos) e não com o que ela faz (seus métodos)
public class Conta {
int numero; String dono; double saldo; double limite; // ... }
Criando e usando um objeto
public class Main {
public static void main(String[] args) {
Conta minhaConta = new Conta();
// ... }
Criando e usando um objeto
• Através da variável minhaConta podemos agora acessar o objeto recém criado para alterar seus atributos:
public class Main {
public static void main(String[] args) { Conta minhaConta = new Conta();
minhaConta.dono = "Duke"; minhaConta.saldo = 1000.0;
System.out.println("Saldo atual: " +
minhaConta.saldo); }
Erro comum: não Esqueça do new!
• Antes de acessar os atributos de um objeto ele deve ter sido inicializado. Variáveis objeto não incializadas tem o valor null.
public class Main {
public static void main(String[] args) {
Conta minhaConta; minhaConta.dono = "Duke"; minhaConta.saldo = 1000.0; System.out.println("Saldo atual: " + minhaConta.saldo); } }
Métodos
• Dentro da classe, também declararemos o que cada conta faz e
como isto é feito, isto é, seus comportamentos ou métodos. public class Conta {
int numero;
// outros atributos
void saca(double quantia) {
double novoSaldo = this.saldo - quantia; this.saldo = novoSaldo;
}
void deposita(double quantidade) { this.saldo += quantidade;
Enviando mensagens aos objetos
• Para pedir ao objeto para fazer algo usa-se a referência para o objeto, seguida do ponto, seguido do nome do método.
• Chamamos de “enviar uma mensagem para o objeto” ao procedimento de invocar algum dos métodos do objeto (lembre-se: os métodos são definidos na classe e são compartilhados por todos os objetos dessa classe)
Exemplo
• O código a seguir efetua um saque e um depósito na conta de Duke. public class Main {
public static void main(String[] args) { // criando a conta
Conta minhaConta = new Conta();
// alterando os valores de minhaConta minhaConta.dono = "Duke"; minhaConta.saldo = 1000; // saca 200 reais minhaConta.saca(200); // deposita 500 reais minhaConta.deposita(500); System.out.println(minhaConta.saldo);
Métodos com retorno
public class Conta {
// outros métodos e atributos
boolean saca(double valor) { if (this.saldo < valor) {
return false;
} else {
this.saldo = this.saldo - valor;
return true;
} }
Exemplo de uso
minhaConta.saldo = 1000;
if (minhaConta.saca(2000)){
System.out.println("Consegui sacar"); } else {
System.out.println("Não consegui sacar"); }
Múltiplos objetos de um mesmo tipo
• Em um programa orientado a objetos “de verdade”, vários objetos de
um mesmo tipo são mantidos em memória ao mesmo tempo. public class Main {
public static void main(String[] args) { // criando a conta
Conta conta1 = new Conta(); Conta conta2 = new Conta();
conta1.saldo = 1000;
conta2.saldo = 1500000; // ...
} }
Objetos são acessados por referências
• Variáveis cujo tipo é uma classe são, em verdade,referências para uma instância dessa classe (um objeto)
public static void main(String[] args) { int i = 4;
Conta c1 = new Conta(); Conta c2 = new Conta(); // ...
}
i C1
Outro exemplo
public class Main {
public static void main(String[] args) {
Conta c1 = new Conta();
c1.deposita(100);
Conta c2 = c1; // linha importante!
c2.deposita(200);
System.out.println(c1.saldo); System.out.println(c2.saldo); }
}
• Qual é o resultado do código acima? O que aparece ao rodar?
Representação em memória
Conta c1 = new Conta();Conta c2 = c1;
C1 C2
O operador new
• O que exatamente faz o new?
o new aloca espaço em memória para o novo objeto e devolve o endereço onde esse objeto foi armazenado.
• O endereço retornado pelo new é chamado de uma referência para o objeto.
• Quando você atribui o endereço de retorno a uma
variável, essa variável passa a referenciar o objeto recém criado.
Outro exemplo
public class Main {public static void main(String[] args) { Conta c1 = new Conta();
c1.dono = "Duke"; c1.saldo = 227;
Conta c2 = new Conta(); c2.dono = "Duke"; c2.saldo = 227; if (c1 == c2) { System.out.println("Contas iguais"); } else { System.out.println("Contas diferentes"); } } }
O que acontece em memória?
• O conteúdo de C1 (o endereço da primeira conta), é diferente do
conteúdo de C2 (o endereço da segunda conta)
C1 C2 dono dono saldo saldo Duke Duke 227 227
O método transfere()
• E se quisermos ter um método que transfere dinheiro entre duas contas?
public class Conta {
// atributos e métodos
void transfere(Conta destino, double valor) { this.saldo = this.saldo - valor;
destino.saldo = destino.saldo + valor; }
O método transfere()
• Poderíamos verificar se a conta de origem tem fundos suficientes
para a transferência.
public class Conta {
// atributos e métodos
boolean transfere(Conta destino, double valor) { if (this.saca(valor) == false) {
// não deu pra sacar! return false; } else { destino.deposita(valor); return true; } } }
Ainda atributos...
• Atributos não inicializados recebem um valor padrão.
– 0 para valores numéricos
– false para atributos booleanos
– “” (string vazia) para atributos do tipo String
• Você também pode ter valores default para os atributos, como segue:
public class Conta { int numero = 1234;
String nome = "Duke";
String sobrenome = "Ellington" String cpf = "123.456.789-10"; double saldo = 1000;
Associações entre classes
• Perceba que a classe Conta tem agora informações que não são da
conta, mas sim do Cliente.
• Os atributos de uma classe podem ser referências para outras
classes.
public class Cliente { String nome;
String sobrenome; String cpf;
}
public class Conta { int numero;
double saldo; double limite; Cliente titular; }
Criando a associação em código
public class Main {
public static void main(String[] args) { Conta minhaConta = new Conta();
Cliente c = new Cliente();
minhaConta.titular = c;
// ... }
}
• Você pode navegar pelas associações usando o ponto
O que acontece se eu navegar por uma
associação não inicializada?
public class Main {
public static void main(String[] args) { Conta minhaConta = new Conta();
minhaConta.titular.nome = "Paulo"; // ...
} }
Exception in thread "main“
O que acontece se eu navegar por uma
associação não inicializada?
• Associações não inicializadas explicitamente, são inicializadas com
null
• Consiste em erro tentar navegar por associações não inicializadas. 0
0 0
Inicialização explícita de associações
• Associações podem ser inicializadas com um valordefault
public class Conta { int numero;
double saldo; double limite;
Cliente titular = new Cliente();
// toda nova Conta criada já terá
// um novo Cliente associado.
// ...
Um outro exemplo: Uma fábrica de carros
class Carro { String cor; String modelo; double velocidadeAtual; double velocidadeMaxima; // liga o carro void liga() {System.out.println("O carro está ligado"); }
// acelera uma certa quantidade
void acelera(double quantidade) {
this.velocidadeAtual += quantidade; }
// ... }
Um outro exemplo: Uma fábrica de carros
class Carro {
// devolve a marcha do carro
int pegaMarcha() { if (this.velocidadeAtual < 0) { return -1; } if (this.velocidadeAtual >= 0 && this.velocidadeAtual < 40) { return 1; } if (this.velocidadeAtual >= 40 && this.velocidadeAtual < 80) { return 2; } return 3;
Testando a fábrica de carros
public class Main {
public static void main(String[] args) { Carro meuCarro;
meuCarro = new Carro(); meuCarro.cor = "Verde"; meuCarro.modelo = "Fusca"; meuCarro.velocidadeAtual = 0; meuCarro.velocidadeMaxima = 80; // liga o carro meuCarro.liga(); // acelera o carro meuCarro.acelera(20); System.out.println(meuCarro.velocidadeAtual); } }