Java Básico Programação Orientada a Objeto Marco Antonio, Arquiteto de Software – TJDF Novembro/2005 Classes em java Uma aplicação Java é formada de centenas classes. Não é raro esse número chegar a milhares Exemplo de classe public class Lampada { String estado = "desligada"; public void ligar(){ estado = "ligada"; } public void desligar(){ estado = "desligada"; } } Identifique cada elemento dessa classe: estado ligar desligar Criação de objetos Objetos são criados apenas através da palavra-chave new A sintaxe é: MeuObjeto m = new MeuObjeto(); MeuObjeto: nome da classe m: nome do objeto new MeuObjeto(): aloca espaço na memória Fábrica de lâmpadas public class FabricaDeLampadas { public static void main(String[] args) { Lampada lampada1 = new Lampada(); Lampada lampada2 = new Lampada(); System.out.println(lampada1.estado); System.out.println(lampada2.estado); lampada1.ligar(); System.out.println(lampada1.estado); System.out.println(lampada2.estado); lampada1.desligar(); System.out.println(lampada1.estado); System.out.println(lampada2.estado); } } Assinatura do Método A assinatura do método é definida pelo nome, pela quantidade e pelo tipo dos seus parâmetros. O método andar() sem parâmetros é diferente de andar(String x) com um parâmetro. Atenção, pois o nome do parâmetro não faz diferença. O método andar(String y) e o método andar(String abc) são iguais e não podem estar na mesma classe. PessoaNormal v1.0 public class PessoaNormal { public void andar() { System.out.println("Eu vou apenas andar."); } } Teste da PessoaNormal v1.0 public class TesteDePessoaNormal { public static void main(String[] args) { PessoaNormal p = new PessoaNormal(); p.andar(); } } Mais métodos Vamos acrescentar outros métodos mais específicos para a PessoaNormal. Tente abstrair a complexidade dos métodos. São vários métodos, várias linhas de código, mas todas representam a mesma idéia. PessoaNormal v1.1 public class PessoaNormal { public void andar() { System.out.println("Eu vou apenas andar."); } public void andar(int quantidadeDeMetros) { System.out.println("Eu vou andar " + quantidadeDeMetros + " metros."); } public void andar(String nomeDaCancao){ System.out.println("Eu vou andar e cantar " + nomeDaCancao); } public void andar(int quantidadeDeMetros, String nomeDaCancao) { System.out.println("Eu vou andar " + quantidadeDeMetros + " metros e cantar " + nomeDaCancao); } } Notação UML: PessoaNormal Teste da PessoaNormal v1.1 public class TesteDePessoaNormal { public static void main(String[] args) { PessoaNormal p = new PessoaNormal(); p.andar(); p.andar(50); p.andar("Faroeste Caboclo"); p.andar(50, "Faroeste Caboclo"); } } Desafio Crie a classe Televisao com o método desligar() Crie a classe de teste para a Televisao Quando o método desligar() for chamado na classe de teste, imprima na tela “A televisão foi desligada” Atualize a Televisao com um método que imprima na tela “A televisão vai ser desligada em xxx minutos” Televisao public class Televisao { public void desligar() { System.out.println("A televisão foi desligada."); } public void desligar(int tempoEmMinutos) { System.out.println("A televisão será desligada em " + tempoEmMinutos + " minutos."); } } Teste da Televisao public class TesteDaTelevisao { public static void main(String[] args) { Televisao televisao = new Televisao(); televisao.desligar(); televisao.desligar(10); } } Método com retorno É muito comum que um objeto retorne alguma informação para o objeto chamador Em um sistema bancário, para uma funcionalidade como o saque não é necessário que exista um retorno, pois o cliente saca o dinheiro e o sistema subtrai essa importância da conta do sacado Quando o cliente deseja consultar o seu saldo, o sistema deve retornar essa informação para o terminal bancário que, por sua vez, irá mostrá-la na tela ContaCorrente public class ContaCorrente { double saldo; String numero; public void deposita(double valorDepositado){ saldo = saldo + valorDepositado; } public void saca(double valorSacado){ saldo = saldo - valorSacado; } public double consultaSaldo(){ return saldo; } } TerminalBancario public class TerminalBancario { public static void main(String[] args) { ContaCorrente conta = new ContaCorrente(); conta.deposita(1500.5); System.out.println("Saldo atual: " + conta.consultaSaldo()); conta.saca(453.3); System.out.println("Saldo depois do saque: " + conta.consultaSaldo()); } } conta.consultaSaldo(): essa expressão representa o valor do atributo saldo (1047.2) Método de Acesso Uma técnica bastante utilizada para construir as classes é utilizar o modificador private para todos os atributos definidos na classe, e criar os métodos de acesso getters e setters. O método get é utilizado para recuperar algum atributo. O método set é utilizado para atribuir valor a algum atributo. Pessoa public class Pessoa { private String nome; private String endereco; private String telefone; } public String getEndereco() { return endereco; } public void setEndereco(String endereco) { this.endereco = endereco; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getTelefone() { return telefone; } public void setTelefone(String telefone) { this.telefone = telefone; } Notação UML: Pessoa Teste da Pessoa public class TesteDePessoa { public static void main(String[] args) { Pessoa p = new Pessoa(); System.out.println("Atribuindo valores..."); p.setNome("Marco Antonio"); p.setEndereco("Taguatinga"); p.setTelefone("33521134"); System.out.println("Imprimindo valores..."); System.out.println("Nome: " + p.getNome()); System.out.println("Endereço: " + p.getEndereco()); System.out.println("Telefone: " + p.getTelefone()); } } Herança Podemos ter uma classe Pessoa com todos os seus atributos principais (nome, endereco, etc) PessoaFisica seria sub-classe (ou classe-filha) de Pessoa Dessa forma, Pessoa seria a super-classe de PessoaFisica PessoaFisica seria especialização de Pessoa e o inverso seria uma generalização (Pessoa é uma generalização de PessoaFisica) Notação UML: PessoaFisica Outro exemplo Um Bebe é uma PessoaNormal, dessa forma: Bebe tem os mesmos métodos/atributos públicos que PessoaNormal Bebe public class Bebe extends PessoaNormal { public void andar(){ System.out.println("Eu vou apenas engatinhar."); } public void andar(int quantidadeDeMetros) { System.out.println("Eu vou engatinhar " + quantidadeDeMetros + " metros."); } public void andar(String nomeDaMusica, int quantidadeDeMetros) { System.out.println("Eu vou engatinhar " + quantidadeDeMetros + " e cantar " + nomeDaMusica); } } Notação UML: Bebe Teste da Pessoa e do Bebe 1. public class TesteDePessoaNormal { 2. public static void main(String[] args) { 3. PessoaNormal pessoa = new PessoaNormal(); 4. pessoa.andar(); 5. pessoa.andar(50); 6. pessoa.andar("Faroeste Caboclo"); 7. pessoa.andar(50, "Faroeste Caboclo"); 8. 9. Bebe bebe = new Bebe(); 10. bebe.andar(); 11. bebe.andar(2); 12. bebe.andar("Dorme neném"); 13. bebe.andar("Dorme neném", 2); 14. 15.} } Sobreposição de métodos Linha 10: andar() está definido na classe Bebe. Linha 11: andar(2) está definido na classe Bebe. Linha 12: andar(“Dorme neném”) não está definido em Bebe, mas está na superclasse. O código será desviado para PessoaNormal, depois continua em Bebe normalmente. Linha 13: andar(“Dorme neném”, 2) está definido em Bebe. Dúvidas? Exercício Crie a classe Funcionario com os atributos matricula, nome, endereco, ramal e lotacao. Crie o diagrama dessa classe usando a UML. Implemente os métodos de acesso. Crie uma classe para testar todos os métodos. Funcionario public class Funcionario { private String matricula; private String nome; private String endereco; private String ramal; private String lotacao; public String getEndereco() { return endereco; } public void setEndereco(String endereco) { this.endereco = endereco; } public String getLotacao() { return lotacao; } public void setLotacao(String lotacao) { this.lotacao = lotacao; } Funcionario public String getMatricula() { return matricula; } public void setMatricula(String matricula) { this.matricula = matricula; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getRamal() { return ramal; } public void setRamal(String ramal) { this.ramal = ramal; } } Teste do Funcionario public class TesteDoFuncionario { public static void main(String[] args) { Funcionario f = new Funcionario(); f.setEndereco("CNB 14 LOTE 10"); f.setLotacao("Informática"); f.setMatricula("313120"); f.setNome("Marco Antonio"); f.setRamal("6849"); System.out.println("Nome: " + f.getNome()); System.out.println("Lotação: " + f.getLotacao()); System.out.println("Endereço: " + f.getEndereco()); System.out.println("Ramal: " + f.getRamal()); System.out.println("Matrícula: " + f.getMatricula()); } } Exercício Crie uma classe Processo com os atributos numero, nomeDoReu e telefoneDeContatoDoReu, nomeDoAdvogado, descricaoDoCrime. Crie o diagrama dessa classe usando a UML. Implemente os métodos de acesso. Crie uma classe para testar todos os métodos. Processo public class Processo { private String numero; private String nomeDoReu; private String telefoneDeContatoDoReu; private String nomeDoAdvogado; private String descricaoDoCrime; public String getDescricaoDoCrime() { return descricaoDoCrime; } public void setDescricaoDoCrime(String descricaoDoCrime) { this.descricaoDoCrime = descricaoDoCrime; } public String getNomeDoAdvogado() { return nomeDoAdvogado; } public void setNomeDoAdvogado(String nomeDoAdvogado) { this.nomeDoAdvogado = nomeDoAdvogado; } Processo public String getNomeDoReu() { return nomeDoReu; } public void setNomeDoReu(String nomeDoReu) { this.nomeDoReu = nomeDoReu; } public String getNumero() { return numero; } public void setNumero(String numero) { this.numero = numero; } public String getTelefoneDeContatoDoReu() { return telefoneDeContatoDoReu; } public void setTelefoneDeContatoDoReu(String telefoneDeContatoDoReu) { this.telefoneDeContatoDoReu = telefoneDeContatoDoReu; } } Teste do Processo public class TesteDoProcesso { public static void main(String[] args) { //Atribuindo os valores Processo p = new Processo(); p.setDescricaoDoCrime("Ofensa Moral"); p.setNomeDoAdvogado("Jose Carlos"); p.setNomeDoReu("Diego Lucas"); p.setNumero("123456/2005"); p.setTelefoneDeContatoDoReu("43254654"); //Recuperando os valores System.out.println("Crime: " + p.getDescricaoDoCrime()); System.out.println("Advogado: " + p.getNomeDoAdvogado()); System.out.println("Réu: " + p.getNomeDoReu()); System.out.println("Número do processo: " + p.getNumero()); System.out.println("Telefone do réu: " + p.getTelefoneDeContatoDoReu()); } } Exercício Crie a subclasse PessoaFisica para a classe Pessoa com o atributo cpf. Crie uma classe TesteDePessoaFisica e utilize todos os métodos da nova classe. Observe o comportamento da subclasse. PessoaFisica public class PessoaFisica extends Pessoa { private String cpf; public String getCpf() { return cpf; } public void setCpf(String cpf) { this.cpf = cpf; } } TesteDaPessoaFisica public class TesteDaPessoaFisica { public static void main(String[] args) { PessoaFisica p = new PessoaFisica(); //Atribuindo //Você pode utilizar esses métodos por causa da herança p.setNome("Marco Antonio"); p.setEndereco("CNB 14"); p.setTelefone("33521134"); //Único método da subclasse p.setCpf("832869"); //Recuperando //Métodos da superclasse System.out.println("Nome: " + p.getNome()); System.out.println("Endereço: " + p.getEndereco()); System.out.println("Telefone: " + p.getTelefone()); //Método da subclasse System.out.println("Cpf: " + p.getCpf()); } } Exercício Crie a classe Retangulo com os atributos comprimento e largura (int). Crie o diagrama dessa classe usando a UML. Crie a classe ProcessaRetangulo para calcular e imprimir na tela a área e perímetro dos retângulos. Retangulo public class Retangulo { int comprimento; int largura; public int calculaArea() { return comprimento * largura; } public int calculaPerimetro() { int perimetro = (largura * 2) + (comprimento * 2); return perimetro; } } ProcessaRetangulo public class ProcessaRetangulo { public static void main(String[] args) { Retangulo r = new Retangulo(); r.comprimento = 5; r.largura = 6; System.out.println("Área: " + r.calculaArea()); System.out.println("Perímetro: " + r.calculaPerimetro()); } } Desafio Atualize a classe Calculadora, criando um método para cada operação. Exemplo: o método 'soma' recebe dois parâmetros e imprime o resultado de sua adição. Crie todos os métodos que forem necessários. Calculadora.java public class Calculadora { public static void main(String[] args) { //Cria o objeto c - Calculadora Calculadora c = new Calculadora(); //Recupera os valores informados pelo usuário int primeiroValor = Integer.parseInt(args[0]); String operador = args[1]; int segundoValor = Integer.parseInt(args[2]); //Decide qual operação a classe vai executar if (operador.equals("+")) { c.soma(primeiroValor, segundoValor); } else if (operador.equals("-")) { c.subtracao(primeiroValor, segundoValor); } else if (operador.equals("/")) { c.divisao(primeiroValor, segundoValor); } else if (operador.equals("*")) { c.multiplicacao(primeiroValor, segundoValor); } } Calculadora.java public void multiplicacao(int primeiroValor, int segundoValor) { int resultado = primeiroValor * segundoValor; System.out.println("Resultado: " + resultado); } public void divisao(int primeiroValor, int segundoValor) { int resultado = primeiroValor / segundoValor; System.out.println("Resultado: " + resultado); } public void subtracao(int primeiroValor, int segundoValor) { int resultado = primeiroValor - segundoValor; System.out.println("Resultado: " + resultado); } public void soma(int primeiroValor, int segundoValor) { int resultado = primeiroValor + segundoValor; System.out.println("Resultado: " + resultado); } }