SlideShare uma empresa Scribd logo
1 de 44
Baixar para ler offline
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br
Sumário
1 ORIENTAÇÃO AO ALUNO.............................................................................................3
2 CLASSES E OBJETOS ..................................................................................................3
2.1 Propriedades............................................................................................................3
2.2 Métodos ...................................................................................................................4
3 MÉTODOS GETTERS E SETTERS ...............................................................................5
4 RELACIONAMENTOS ENTRE OBJETOS DO TIPO “TEM UM”.....................................5
5 HERANÇA - RELACIONAMENTO DE OBJETOS DO TIPO “É UM” .............................10
5.1 Instanciando Polimorficamente ..............................................................................17
5.2 Fazendo Conversões (Casting)..............................................................................18
5.3 Sistema de Cadastro de Pessoas ..........................................................................19
6 MÉTODOS E PROPRIEDADES ESTÁTICAS...............................................................20
7 SOBRECARGA E SOBRESCRITA DE MÉTODOS ......................................................22
7.1 Sobrescrevendo o Método toString()......................................................................23
7.2 Sobrescrevendo o Método equals(Object obj)........................................................24
7.3 Utilizando a IDE para Gerar o Método Equals e Hashcode ....................................24
7.4 HashCode..............................................................................................................25
7.5 A Palavra Reservada This......................................................................................25
8 CONSTRUTORES........................................................................................................26
8.1 Construtor Sobrecarregado....................................................................................26
8.2 Sobrecarregando o Construtor de Cidade..............................................................28
8.3 Lembrando dos Estáticos.......................................................................................28
9 SOBRECARGA DE CONSTRUTORES ........................................................................29
10 MÉTODOS SOBRECARREGADOS .............................................................................29
11 CLASSES ABSTRATAS ...............................................................................................30
12 INTERFACES ...............................................................................................................31
12.1 Implementando as Interfaces .................................................................................32
13 GENÉRICOS - UM GERENCIADOR DE REGISTROS GENÉRICO .............................37
14 TRABALHANDO COM COLEÇÕES .............................................................................38
14.1 List .........................................................................................................................39
14.2 Exemplo de Uso da Interface List com ArrayList ....................................................39
14.3 Set .........................................................................................................................40
14.4 Map........................................................................................................................41
15 EXCEPTIONS...............................................................................................................41
15.1 Lançando uma Exception Unchecked (Não verificadas).........................................42
15.2 Lançando uma Exception Checked (Verificadas) ...................................................43
Versão: 2.0
2ª Edição
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 3
1 ORIENTAÇÃO AO ALUNO
Este material é continuação do módulo 1 do projeto Fábrica de Programador, nosso foco é
ensinar os conceitos práticos de Orientação a Objetos de modo didático, com uma linguagem
menos formal para auxiliar os desenvolvedores iniciantes a darem seus primeiros passos de
modo prático e rápido, sem a necessidade de um embasamento teórico aprofundado. Logo,
este material não foca os conceitos teóricos da computação. Para você se aprofundar na
teoria da computação recomendamos que leia livros voltados para esse fim.
2 CLASSES E OBJETOS
No modulo 1 (Java e Algoritmos) vimos os conceitos básicos de classe como sendo a estrutura
básica dos objetos. Se você ainda tem dúvidas sobre o que são classe e objetos
recomendamos a leitura da matéria do módulo 1.
O que precisamos entender, é que um sistema é composto por vários objetos. Um objeto é
uma instância da classe e cada objeto ocupa um espaço na memória podendo ser acessado
por meio das variáveis de referência. As variáveis de referência guardam o endereço do objeto
e funciona com um controle remoto onde podemos acessar seus métodos e propriedades de
acordo de suas visibilidades.
2.1 Propriedades
Os objetos possuem propriedades que servem para definir ou armazenar as características,
campos ou atributos do objeto. No caso de um cliente, por exemplo, temos as propriedades:
nome, CPF e RG.
Exemplo de classe Cliente em Java
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 4
Neste exemplo criamos a classe Cliente e instanciamos dois objetos com o comando new, no
qual, cada objeto é uma cópia da classe na memória, com a mesma estrutura da classe. Os
dados dos objetos são definidos no objeto. O objeto que possui nome “Jão da Silva” é
totalmente independente do objeto que possui o nome “Maria da Silva”, embora os dois
objetos vieram da mesma classe, eles não se conhecem por que estão em posições de
memória diferentes.
2.2 Métodos
Os métodos como já vimos no modulo 1, são as funções que o objeto realiza. Um objeto
Calculadora pode possuir os métodos: somar(), multiplicar(), subtrair (), e dividir().
Exemplo de criação de método
class Calculadora{
public double somar(double n1, double n2){
return n1+n2;
}
}
Exemplo de invocação por meio de um objeto instanciado
public class ProgramaPrincipalMetodos {
public static void main(String[] args) {
Calculadora c = new Calculadora();
System.out.println(c.somar(10, 20));
}
}
Representação gráfica da classe (UML)
O diagrama de classes é um dos diagramas da UML (Unified Modeling Language ou
Linguagem de Modelagem Unificada) que é uma linguagem visual utilizada para modelar
softwares que utilizam o padrão orientação a objetos.
Voltando a classe Cliente podemos fazer sua representação gráfica utilizando o diagrama
como abaixo.
Diagrama de Classe Código Java
public class Cliente {
private String nome;
private String cpf;
private String rg;
}
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 5
3 MÉTODOS GETTERS E SETTERS
No módulo 1 estudamos sobre os métodos encapsuladores getters e setters. Estes métodos
são encapsuladores de propriedades e servem para atribuição (set) e acesso (get) às
mesmas.
Exemplo
public class Cliente {
private String nome;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}
Normalmente utilizamos os métodos getters e setters com modificadores de acesso público e
das propriedades privadas. O modificador de acesso público permite a variável de instância a
acessar o método e o modificador de acesso privado proíbe o acesso da propriedade pela
instância. Para acessar uma propriedade privada somente um método da própria classe pode
fazê-lo.
Cliente cliente = new Cliente();
//Atribuindo o nome
cliente.setNome("Jão da Silva");
//Acessando o nome
System.out.println(cliente.getNome());
4 RELACIONAMENTOS ENTRE OBJETOS DO TIPO “TEM UM”
É muito comum termos que relacionar os objetos de um sistema. Um sistema em
funcionamento nada mais é que um conjunto de objetos trocando mensagens entre si. Em um
corpo humano os órgãos se comunicam entre si, onde cada um faz a sua função. Um software
não é diferente, pois precisamos arquitetar e estruturar nossos objetos de modo que eles se
comuniquem e sirvam uns aos outros.
Pensemos em um caso: Para definirmos uma cidade para um cliente como faríamos? Fácil,
basta acrescentarmos um campo ou propriedade chamado Cidade na classe Cliente do tipo
String. Certo? Sim, pode ser, mas na maioria dos casos uma cidade será um objeto a parte e
independente do cliente, então, neste caso, ao invés de colocarmos um atributo ou
propriedade do tipo String em nosso Cliente nós colocaremos uma propriedade do tipo cidade
que ainda iremos construir. Podemos dizer que o cliente “tem uma” cidade vinculada a ele.
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 6
Classe Cliente sem Relacionamento com Classe Cliente tem Relacionamento com
Classe Cidade Classe Cidade
public class Cliente {
private String nome;
private String cpf;
private String rg;
}
private String cidade;
public class Cidade {
private String nome;
private String uf;
}
public class Cliente {
private String nome;
private String cpf;
private String rg;
//getters and Setters
}
private Cidade cidade;
No primeiro caso, não teríamos o reaproveitamento das cidades e necessitaríamos sempre
repetir o nome de uma mesma cidade várias vezes para clientes diferentes.
Exemplo
Cliente jao = new Cliente();
jao.setNome("Jão");
jao.setCidade("Campo Grande");
Cliente maria = new Cliente();
maria.setNome("Maria");
maria.setCidade("Campo Grande");
No segundo caso podemos construir apenas um objeto Cidade e reutilizá-lo em vários
clientes. Na verdade, quem se relaciona são os objetos, porém, é na classe que escrevemos
isso. Basicamente, o que devemos fazer é “setar” uma instância de Cidade na propriedade
cidade do Cliente.
Cidade cg = new Cidade();
cg.setNome("Campo Grande");
cg.setUf("MS");
Cliente jao = new Cliente();
jao.setNome("Jão");
jao.setCidade(cg);//Relacionamento com objeto Cidade
Cliente maria = new Cliente();
maria.setNome("Maria");
maria.setCidade(cg);//Relacionamento com objeto Cidade
Diagrama de Classe da UML
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 7
No mundo real, vários clientes do sistema podem ter nascido em uma cidade. Na memória
podemos imaginar vários objetos do tipo Cliente e vários objetos do tipo Cidade onde uma ou
mais instâncias de clientes podem estar vinculados a uma mesma instância de cidade.
Ao acessar um objeto tipo Cidade que está relacionado com um objeto tipo Cliente podemos,
a partir da instância do Cliente, navegar no objeto Cidade porque a propriedade cidade nada
mais é que uma referência para um objeto do tipo Cidade. Com o método getCidade()
acessamos esta referência que foi “setada” para o cliente da instância jao.
//Imprimindo dados da cidade do jao
System.out.println(jao.getCidade().getNome() + " " +
jao.getCidade().getUf());
Podemos, ainda, pensar na possibilidade de representarmos os estados de uma cidade como
sendo objetos a parte. Ao invés de termos uma propriedade String uf, poderíamos ter uma
propriedade do tipo Estado vinculado ao tipo Cidade, no qual, teríamos uma classe para
representá-lo como no diagrama de classe abaixo:
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 8
Na memória, agora temos um objeto do tipo Estado relacionado ao objeto do tipo Cidade.
Criação Classe Estado Alteração da Classe Cidade
public class Estado {
private String nome;
private String uf;
//getters and setters
}
public class Cidade {
private String nome;
private Estado estado;
//getters and setters
}
Agora nosso programa principal deve ser alterado para que possamos utilizar a propriedade
UF em um objeto do tipo Estado e não mais diretamente na cidade como estava. Assim, já
iremos corrigir o erro gerado: The method setUf(String) is undefined for the type Cidade,
dizendo que não existe mais o método setUf(String) na cidade.
Com uma instância de estado basta “setarmos” ele na cidade em sua nova propriedade de
relacionamento estado. Para imprimir o estado da cidade do cliente, utilizamos a navegação
por meio do método get. Primeiro acessamos o cliente, depois a cidade do cliente e por fim o
estado da cidade conforme o código abaixo:
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 9
1. public class ProgramaPrincipal {
2.
3. public static void main( String[] args ) {
4. //Construção do Objeto Estado
5. Estado ms = new Estado();
6. ms.setNome("Mato Grosso do Sul");
7. ms.setUf("MS");
8.
9. //Construção do Objeto Cidade
10. Cidade cg = new Cidade();
11. cg.setNome("Campo Grande");
12. //Relacionamento com o objeto Estado
13. cg.setEstado(ms);
14.
15. Cliente jao = new Cliente();
16. jao.setNome("Jão da Silva");
17. jao.setCpf("999999999-99");
18. //Relacionamento com objeto Cidade
19. jao.setCidade(cg);
20.
21. //Imprimindo dados da cidade do jao
22. System.out.println(jao.getCidade().getNome()+ " " +
jao.getCidade().getEstado().getUf() +
23. " "+ jao.getCidade().getEstado().getNome());
24. }
25. }
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 10
5 HERANÇA - RELACIONAMENTO DE OBJETOS DO TIPO “É UM”
Em muitos casos, podemos ter
a necessidade de trabalhar
com classes mais genéricas e
classes mais específicas.
Vamos pensar na seguinte
situação:
Uma empresa necessita de
um sistema de cadastros que
possa ter o cadastro de várias
pessoas, tais como Clientes,
Fornecedores e Funcionários.
Estes três tipos de cadastros
possuem campos em comum
(mais genéricos) e campos
específicos que fazem parte
exclusivamente daquele
cadastro. Nós ainda não
estamos trabalhando com tela
em Java neste ponto do
estudo, mas fizemos um
rascunho (protótipo) quando
estávamos conversando com
o cliente, levantando suas
necessidades (levantamento
de requisitos) e pudemos
observar que o cliente deseja
algo semelhante às telinhas ao
lado.
O que vemos em comum
nestes cadastros solicitados
por nosso cliente?
Primeiramente, que todos os
cadastros, podemos
considerar, são de uma
mesma família mais genérica de objetos que podemos chamar de Pessoa. Podemos ver que
todos, por se tratarem de pessoa, possuem um campo (propriedade) nome e também cidade,
independente se é Cliente, Fornecedor ou Funcionário. Entre os cadastros temos uma
variação de campos, em que cada formulário, além dos campos em comum, possui campos
específicos, como no caso do funcionário que possui praticamente os mesmos campos de
cliente, exceto um novo campo chamado cargo.
Nesta situação vamos trabalhar com um tipo de relacionamento chamado de Herança ou
relacionamento “É um”. Neste tipo de relacionamento nós criamos classes que conterão
propriedades e métodos mais genéricos. Essas classes servem de “superclasse” ou classe
base, para que outras possam estender, ou seja, esta classe contém propriedades e métodos
que podem ser herdados.
As classes mais específicas ou classes filhas possuem a palavra reservada extends para
especificar qual será sua classe base. Em outras palavras, as classes filhas que estendem as
superclasses “esticam” a classe base por meio do extends.
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 11
A classe base ou superclasse tem suas características e a classe filha herda suas
características e também adiciona novas propriedades e métodos específicos dela. Na
instância do objeto da classe filha podemos ver os métodos e propriedades que foram
estendidos. Senão existisse herança, nós teríamos que criar vários campos ou propriedades
repetidas em cada classe.
Classes sem Herança – Tentativa 1
Desta forma, criamos uma classe individual para cada Cadastro sem herança e sem a
reutilização de campos.
public class Cliente{
private String nome;
private String cpf;
private String rg;
private Cidade cidade;
}
public class Fornecedor{
private String nome;
private String
razaSocial; private
String cnpj; private
Cidade cidade;
}
Public class Funcionario{
private String nome;
private String cpf;
private String rg;
private String cargo;
private Cidade cidade;
}
Classes com Herança sendo 1 classe Genérica e 3 Específicas – Tentativa 2
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 12
Desta forma, criamos uma classe Pessoa contendo os campos
comuns para todos dos cadastros. Mas ainda parece que
ficaram campos repetidos em Cliente e Funcionario. Não
poderíamos colocar RG e CPF em Pessoa, senão
comprometeríamos o Fornecedor que é Pessoa Jurídica.
public class Pessoa {
private String nome;
private Cidade cidade;
//getters e setters
}
public class Cliente
extends Pessoa{
private String cpf;
private String rg;
}
public class Fornecedor
extends Pessoa {
private String razaSocial;
private String cnpj;
}
public class Funcionario
extends Pessoa{
private String cpf;
private String rg;
private String cargo;
}
Classes com Herança com mais classes Genéricas e Específicas – Tentativa 3
Deste jeito, pensamos de forma mais genérica ainda, criando uma classe Pessoa e classes
filhas Pessoa Física e Pessoa Jurídica. Agora as classes Cliente e Funcionário estendem
da classe PessoaFisica e a classe Fornecedor estende da classe PessoaJuridica. Assim,
até se precisarmos em outras partes do sistema futuramente representar clientes do tipo
PessoaJuridica com este modelo teremos mais suporte para isso.
Classe mais Genérica Classes Filhas mais Específicas, mas ainda são Genéricas
para suas filhas
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 13
public class Pessoa {
private String nome;
private Cidade cidade;
//getters e setters
}
public class
PessoaFisica extends
Pessoa {
private String cpf;
private String rg;
//getters e setters
}
public class PessoaJuridica
extends Pessoa {
private String cnpj;
private String razaSocial;
//getters e setters
}
Classes Filhas das Filhas ainda mais Específicas
public class Cliente
extends PessoaFisica{
//Todos campos comuns
//Foram herdados
}
public class Fornecedor
extends PessoaJuridica {
//Todos campos comuns foram
//herdados
}
public class Funcionario
extends PessoaFisica {
//Todos campos comuns
//Foram herdados
private String cargo;
}
Programa Principal
Crie um programa principal para testar o acesso à propriedade nome a partir da instância de
Cliente.
public class ProgramaPrincipalCliente {
public static void main(String[] args) {
Cliente cli = new Cliente();
cli. ??? // O que será que vai aparecer depois do ponto?
}
}
Observe a diferença entre o ponto de vista do objeto e da classe.
Do ponto de Vista do Objeto
Acessando os métodos Get e Set do ponto de vista do objeto, ou seja, da instância em um
Programa Principal, por exemplo, a IDE deve mostrar os métodos herdados e acessíveis.
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 14
Do ponto de Vista da Classe
Se tentarmos acessar as propriedades privadas da classe base pela classe filha, acreditando
que ela estará acessível, então nos deparamos com a situação de que isso não é possível. A
Herança respeita os modificadores de acesso das propriedades, e isso só seria possível se
nossa propriedade não fosse private e sim protected. Ao deixarmos uma propriedade
protected estamos permitindo que a mesma seja acessível diretamente pelas classes filhas,
livres de ter que acessar pelos métodos encapsuladores, como se a propriedade tivesse sido
declara dentro da própria classe filha.
A figura abaixo ilustra os métodos acessíveis pela classe Cliente. Vemos que possuem
métodos getters e setters de Object, Pessoa e PessoaFisica.
Tudo estende de java.lang.Object
A classe java.lang.Object é a classe base padrão do Java, tudo estende de Object mesmo se
não colocarmos o comando extends Object. Só podemos herdar uma classe por vez, não
havendo herança múltipla como em outras linguagens, ou seja, cada classe filha só pode ter
uma classe base e essa classe base também pode ter outra classe base e assim por diante
até chegar no topo da hierarquia que é a classe Object.
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 15
Protected do ponto de vista da classe
Se colocarmos na propriedade nome da classe Pessoa o modificador protected, podemos
acessá-lo diretamente pela classe filha. Faça a seguinte experiência, na classe Cliente,
adicione um método calcularPontuacao para tentarmos acessar de dentro do método a
propriedade nome da classe Pessoa.
public class Pessoa {
protected String nome;
}
public class Cliente extends
PessoaFisica{
public void calculaPontuacao(){
}
}
Na IDE (Eclipse ou Netbeans) você já pode ver que isso é possível utilizando o recurso de
auto complete (ctrl+ espaço) como na imagem abaixo.
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 16
Assim, podemos acessar essa propriedade de forma direta para atribuirmos um valor ou para
recuperarmos seu valor para impressão. Uma forma utilizada também é por meio do comando
this ficando this.nome.
Protected do ponto de vista da instância
Podemos acessar da instância uma propriedade protected diretamente? Resposta: Vai
depender dos pacotes. Se a classe que possui a instância de Cliente como o
ProgramaPrincipal estiver no mesmo pacote que a classe Cliente então sim, a propriedade
fica de livre acesso, podendo ser acessada diretamente como se ela fosse do modificador
default. E as classes estiverem em pacotes diferentes então não é possível acessar a
propriedade protected, precisando, assim, utilizar os métodos encapsuladores getters e
setters.
Instância em classe no mesmo pacote Instância em classe em pacote diferente
Neste exemplo, podemos ver claramente a
possibilidade de acesso da propriedade nome
pela instância de cliente no programa principal.
Para ficar fácil de entender pense que do ponto
de vista da instância a regra é a mesma do
modificador default.
Mova a classe Pessoa que possui a
propriedade protected para um pacote
diferente, “temp”, por exemplo.
package br.com.fabricadeprogramador
.temp;
//imports aqui
public class Pessoa {
protected String nome;
//restante da classe aqui
}
Na instância tente acessar
Veja que aparecem os métodos, mas não a
propriedade nome.
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 17
5.1 Instanciando Polimorficamente
É possível declarar uma variável do tipo mais genérico apontando para um objeto de uma
classe filha bem mais específico? Sim, a isso chamamos de atribuições polimórficas. Veja no
exemplo abaixo.
package br.com.fabricadeprogramador.sistemacadastro;
import br.com.fabricadeprogramador.temp.Pessoa;
public class ProgramaPrincipalPolimorfismo {
public static void main(String[] args) {
Object objeto = new Funcionario();
Pessoa pessoa = new Funcionario();
PessoaFisica pessoaFisica = new Funcionario();
Funcionario funcionario = new Funcionario();
}
}
Quando uma classe filha estende uma classe base, dizemos que um objeto da classe filha “é
um (a)” do objeto classe base.
Exemplo
Podemos declarar variáveis de um tipo mais genérico para armazenar referências a objetos
mais específicos. Uma variável do tipo Object pode apontar para um objeto do tipo Funcionario
porque o mesmo passa no teste “é um”, ou seja, um funcionário “é um” Object, mesmo que
não herda diretamente, mas no topo da hierarquia sabemos que tudo herda de Object. Uma
variável do tipo Pessoa pode apontar para um objeto Funcionario porque funcionário “é uma”
Pessoa. Uma variável do tipo PessoaFisica pode apontar para um objeto do tipo Funcionario
porque funcionário “é uma” PessoaFisica. Uma variável do tipo Funcionario pode apontar
para um objeto Funcionario porque funcionário “é um” Funcionario.
A figura abaixo mostra que todos podem apontar para um Funcionário, porém, os que estão
mais abaixo ou específicos podem ver mais detalhes do objeto, porque a variável de
referência limita o acesso as propriedades e métodos do objeto de acordo com seu tipo.
Um tipo Object embora aponte para um objeto Funcionario não pode ter acesso a tudo do
funcionário, podendo acessar apenas o que corresponde ao tipo Object. Um objeto funcionário
é constituído de várias partes, sendo a parte de Object, a parte de Pessoa, a parte de
PessoaFisica e a parte de Funcionario. A soma destas heranças é o funcionário completo,
mas quem pode ter acesso completo é apenas uma referência do tipo Funcionario. A variável
do tipo Object é a mais limitada quanto ao acesso ao objeto Funcionário e a variável do tipo
Funcionário é a mais completa.
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 18
5.2 Fazendo Conversões (Casting)
É possível fazermos conversões de tipos desde que os objetos sejam da mesma família. Em
nosso exemplo anterior temos uma instância de funcionário sobre uma referência do tipo
Object. O Objeto instanciado e do tipo Funcionário, mas a referência declarada foi do tipo
Object, então essa variável de referência mesmo podendo acessar o objeto, está limitada pelo
seu tipo declarado não podendo acessar tudo de um objeto Funcionario.
Mas será possível a variável do tipo Object invocar o método setCargo(String)? Sim, se
fizermos uma conversão ou casting. Fazer um casting na variável Object objeto para o tipo
Funcionário é como “esticar” a capacidade dela para que ela possa acessar o objeto completo.
O que estamos fazendo é tornando a visão de variável que é mais genérica em uma “lupa”
para ver os detalhes de um objeto mais específico. Veja:
“Setando” um cargo no funcionário fazendo casting
((Funcionario)objeto).setCargo("Motorista");
“Getando” o cargo do funcionário
objeto.getCargo();
Se tentarmos acessar diretamente o método getCargo na variável que fizemos o casting, não
teremos acesso e receberemos a seguinte mensagem:
The method getCargo() is undefined for the type Object
Isso porque o casting não altera o tipo original da variável mantendo como sendo do tipo
Object. Para acessarmos o método getCargo temos que fazer novamente um casting da
seguinte forma:
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 19
((Funcionario)objeto).getCargo();
Assim como podemos “esticar” a visibilidade também podemos “encolher”. Para um objeto do
tipo Funcionário podemos fazer um casting para torná-lo de o tipo mais Genérico como:
Funcionario funcionario = new Funcionario();
((PessoaFisica) funcionario).setCpf("99009");
5.3 Sistema de Cadastro de Pessoas
Um exemplo de uso de atribuições polimórficas seria criarmos um sistema de cadastro
Genérico, no qual podemos passar por parâmetro uma instância de qualquer objeto da família
de Pessoa, ou seja, qualquer objeto de uma classe que estenda da classe Pessoa. No
exemplo abaixo a variável genérica Pessoa recebe um objeto como parâmetro e o armazena
em um vetor Genérico de Pessoa.
public class SistemaCadastro {
Pessoa pessoas[] = new Pessoa[3];
int numEntradas = 0;
/** Entrada Generica
* @param pessoa
*/
public void cadastrar (Pessoa pessoa){
if(numEntradas < pessoas.length){
pessoas[numEntradas] = pessoa;
numEntradas++;
}
}
}
Agora na hora de imprimir teremos que utilizar a técnica de conversão para imprimir os dados
específicos de um objeto Pessoa. Como nosso vetor de pessoas é genérico e armazena
vários tipos de pessoas diferentes, como Cliente, Fornecedor e Funcionário então temos que
utilizar o instanceof para verificar qual o tipo do objeto da referência para realizar a conversão
e acessar as propriedades específicas.
/**
* Impressao de forma especifica
*/
public void imprimir (){
for (int i = 0; i < pessoas.length; i++) {
System.out.println(pessoas[i].getNome()+ "");
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 20
//Funcionario
if(pessoas[i] instanceof Funcionario){
//casting
Funcionario func = (Funcionario) pessoas[i] ;
System.out.print(func.getSalario() + " " + func.getCargo());
}
//Faça para Cliente
//Faça para Fornecedor
}
}
Convertendo de String para Inteiro
Quando os objetos não são da mesma família hierárquica não podemos utilizar a mesma
técnica de casting. É possível fazermos uma conversão de uma String para número inteiro
então? Da seguinte forma, não.
String numeroStr = "10";
Integer n = (Integer)numeroStr;
A solução para este caso é a chamada a um o método static de conversão parseInt da classe
Integer ou chamada de um construtor especial que suporta uma entrada String.
String numeroStr = "10";
Integer n1 = Integer.parseInt(numeroStr);
Integer n2 = new Integer(numeroStr);
6 MÉTODOS E PROPRIEDADES ESTÁTICAS
Um método estático é um método que não está ligado a instância do objeto. Para invocar um
método estático basta colocarmos o nome da classe, um ponto e nome do método como:
Integer.parseInt("10");
Uma propriedade estática é uma propriedade da classe e não do objeto. Isso quer dizer que
o valor dela não pode ser diferente para cada instância. Para toda instância de Integer a
propriedade MAX_VALUE sempre terá o mesmo valor.
Integer maximoInt = Integer.MAX_VALUE;
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 21
As propriedades estáticas não servem para manter o ”estado” do objeto. Entende-se por
estado do objeto os valores atribuídos em suas propriedades para uma determinada instância.
No exemplo abaixo os objetos estão com estados diferentes porque suas propriedades não
são estáticas e os dados atribuídos são diferentes.
Funcionario jao = new Funcionario();
jao.setNome("Jão da Silva");
jao.setCargo("Cientista da Computação");
Funcionario maria = new Funcionario();
maria.setNome("Maria da Silva");
maria.setCargo("Analista de Sistemas");
Em nosso caso, será comum utilizarmos métodos estáticos em nossa aplicação para criarmos
classes com métodos utilitários.
Exemplo
public class ValidacaoUtil {
public static void validarCpf(String cpf) {
//implementação aqui
}
public static void validarCnpj(String cnpj) {
//implementação aqui
}
public static void validarEmail(String email) {
//implementação aqui
}
}
A invocação dos métodos estáticos não necessita de instância.
public static void main(String[] args) {
ValidacaoUtil.validarCnpj("10.797.626/0001-88");
ValidacaoUtil.validarCpf("905.044.567-92");
ValidacaoUtil.validarEmail("contato@htcursos.com");
}
O main é estático! O método principal public static void main(String[] args) é estático, por se
tratar de um método principal não sendo necessário a JVM instanciar um objeto do nosso
programa principal para invoca-lo. Um método estático somente pode alterar valores de
variáveis também estáticas. O código abaixo não pode irá funcionar por que a propriedade
não é estática e está tentando ser acessar por um método estático.
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 22
public class ValidacaoUtil {
String cpf; //propriedade não estática
public static void validarCpf(String cpf) {
//Cannot make a static reference to the non-static field numero
this.cpf =cpf;
}
}
Ao utilizarmos métodos estáticos, também não utilizamos a palavra reservada this, porque ela
quer dizer “esta instância atual” e com os métodos estáticos não estamos trabalhando com a
instância. Certo?
O código abaixo pode ser feito.
public class ValidacaoUtil {
static String cpfEstatico;
// propriedade estática
public static void validarCpf(String cpf) {
cpfEstatico = cpf;
}
}
7 SOBRECARGA E SOBRESCRITA DE MÉTODOS
Em Java vimos que a classe mais genérica é a java.lang.Object. A classe Object do java
possui vários métodos implementados, abaixo vamos listar dois deles: toString( ) e equals(
Object obj).
public String toString() {}
Retorna uma String representando
uma versão texto do objeto.
Ao tentarmos imprimir uma variável de
instancia do objeto o método toString é
invocado automaticamente.
Por padrão o método retorna uma
String com uma referência ao objeto
como:
br.com.fabricadeprogramador.sist
emacadastro.Cliente@13d9c02
Exemplo de chamada:
Cliente cli = new Cliente();
System.out.println(cli);
System.out.println(cli.toString());
public boolean equals(Object obj) {} Este método verifica se o objeto atual é
igual ao outro passado no parâmetro.
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 23
Exemplo de chamada:
1. Cliente cli1 = new Cliente();
2. cli1.setNome("jão");
3.
4. Cliente cli2 = new Cliente();
5. cli2.setNome("jão");
6.
7. boolean iguais = cli2.equals(cli1);
8. System.out.println(iguais);
Seu critério de igualdade é a referência,
ou seja, somente se os objetos
estiverem na mesma posição de
memória, então, serão considerados
iguais.
No exemplo ao lado temos 2 clientes
com o mesmo nome, porém em objetos
diferentes, ou seja, em posições
diferentes de memória, logo o retorno
será false na comparação da linha 7.
Os métodos da classe base Object que acabamos de estudar já possuem uma implementação
padrão. Mas seria possível modificarmos essa implementação? E se quisermos considerar
que duas instâncias diferentes de objetos do tipo Cliente com o mesmo CPF sejam
considerados clientes iguais, mesmo que estão em posições de memória diferentes? Neste
caso nós temos que modificar o método equals da classe Object, porém se fosse possível
fazer isso diretamente na classe Object nós comprometeríamos todos os objetos do sistema
porque todos herdam de Object.
Então será possível modificarmos somente o método toString da classe Cliente para fazer
essa adaptação para nossa necessidade específica? Sim, é possível, isso é conhecido como
sobrescrita de método, ou seja, escrever uma “por cima” ou sobre do método herdado da
classe base na classe filha.
7.1 Sobrescrevendo o Método toString()
public class Cliente extends PessoaFisica{
public String toString() {
return getNome() + " "+ getCpf();
}
//demais métodos
}
Desta forma agora ao executarmos o código abaixo a saída será o nome e o CPF
concatenados do objeto Cliente.
Cliente cli1 = new Cliente();
cli1.setNome("jão");
cli1.setCpf("999.999.999-99");
System.out.println(cli);
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 24
7.2 Sobrescrevendo o Método equals(Object obj)
Queremos que o critério de comparação seja o CPF e o RG do cliente, ou seja, se dois clientes
com mesmo CPF e RG são comparados pelo método equals então o retorno deve ser true.
public class Cliente extends PessoaFisica{
public boolean equals(Object obj) {
//Se os objetos estiverem na mesma posição de memória
if (this == obj)
return true;
//Convertendo (casting) o tipo Object para o tipo PessoaFisica
PessoaFisica outro = (PessoaFisica) obj;
//se não forem iguais retorna falso
if(!cpf.equals(outro.cpf))
return false;
//se não forem iguais retorna falso
if(!rg.equals(outro.rg))
return false;
//se não passou
return true;
}
public String toString()
return getNome() + " "+ getCpf();
}
}
7.3 Utilizando a IDE para Gerar o Método Equals e Hashcode
Melhorando o método hashcode e equals de Cliente utilizando a ferramenta da IDE eclipse
ou Netbeans. No eclipse o acesso é pelo menu source / generator hashcode and equals.
public boolean equals(Object obj){
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PessoaFisica other = (PessoaFisica)obj;
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 25
if (cpf == null) {
if (other.cpf != null)
return false;
} else if (!cpf.equals(other.cpf))
return false;
if (rg == null) {
if (other.rg != null)
return false;
} else if (!rg.equals(other.rg))
return false;
return true;
}
7.4 HashCode
Muito usado nas estruturas de dados que iremos ver mais a frente, mas, por esse momento,
precisamos entender que este é um número que representa um objeto toda vez que os valores
de suas propriedades estipuladas no método estiverem iguais, o mesmo hashcode deve ser
gerado, neste exemplo quando uma pessoa possuir o mesmo RG e o mesmo CPF um código
de hashcode será gerado idêntico porque o método utiliza dos dados destas propriedades
para dar origem ao número de hashcode. Em estrutura de armazenamento HashMap e
HashSet iremos ver isso na prática.
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cpf == null) ? 0 : cpf.hashCode());
result = prime * result + ((rg == null) ? 0 : rg.hashCode());
return result;
}
7.5 A Palavra Reservada This
A palavra reservada this sempre será usada dentro da classe para fazer referência à instância
atual. No exemplo anterior no trecho de código abaixo podemos ler: “se a referência da
instância atual (this) for igual a referência à instância obj então return true”.
if (this == obj)
return true;
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 26
8 CONSTRUTORES
Os construtores são como um método chamado somente no momento de construirmos um
objeto. Um objeto é construído quando é alocado na memória. Não iremos tratá-lo como
método por não acessarmos pela variável de referência por meio do operador de acesso
ponto. Mas tem uma sintaxe parecida com a de um método, exceto por não possuir tipo de
retorno. O construtor sempre leva o nome da Classe. O construtor é chamado por meio do
operador new. Exemplo: new Cliente();
Construtor Padrão
Este é o construtor sem parâmetros de entrada. Todo construtor ao ser chamado executa
primeiro o construtor da classe base. O objeto vai sendo construído de cima para baixo, ou
seja, primeiro o construtor da classe Object é executado e depois o construtor das classes
filhas na ordem da herança. A chamada super() invoca o construtor da classe base. Mesmo
se não escrevermos um construtor padrão na classe, o compilador irá escrever no bytecode
gerado, mesmo que não apareça em nosso código fonte, exceto quando nós escrevermos
algum construtor sobrecarregado, que veremos logo a frente.
public class Pessoa {
protected String nome;
private Cidade cidade;
public Pessoa() {
super();
}
}
Chamada ao construtor padrão de Pessoa
Pessoa pessoa = new Pessoa();
8.1 Construtor Sobrecarregado
É um construtor que possui parâmetros de entrada, ou seja, uma nova versão de um
construtor. Podemos criar várias versões de construtores, em que cada versão suporta tipos
diferentes de entradas como parâmetros. No exemplo abaixo temos o construtor padrão e um
construtor sobrecarregado que suporta uma String e uma Cidade como entrada, sendo o
primeiro para iniciar o objeto com um valor “setado” nas propriedades nome e cidade de
Pessoa.
Sobrecarregando o construtor de Pessoa
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 27
public class Pessoa {
protected String nome;
private Cidade cidade;
public Pessoa() {
super();
}
public Pessoa(String nome, Cidade cidade) {
super();
this.nome = nome;
this.cidade = cidade;
}
}
Exemplo de chamada
new Pessoa("Jão", new Cidade());
Se ao instanciarmos um objeto da classe Cliente já quisermos informar o seu nome? Temos
que criar um construtor sobrecarregado na classe Cliente.
public class Cliente extends PessoaFisica{
public Cliente() {
super();
}
public Cliente(String nome) {
//Método Herdado
setNome(nome);
}
}
Agora já podemos fazer a chamada ao construtor sobrecarregado da forma abaixo.
new Cliente("Jão");
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 28
8.2 Sobrecarregando o Construtor de Cidade
public class Cidade {
private String nome;
private Estado estado;
public Cidade() {
super();
}
public Cidade(String nome) {
super();
this.nome = nome;
}
public Cidade(String nome, Estado estado) {
super();
this.nome = nome;
this.estado = estado;
}
}
Agora com o construtor sobrecarregado podemos, no momento da construção do objeto
Pessoa, já passarmos dois objetos como parâmetro de entrada, sendo uma instância de String
e uma instância de Cidade.
Pessoa pessoa = new Pessoa("Jão", new Cidade(“Campo Grande”));
8.3 Lembrando dos Estáticos
Agora como já conhecemos o uso dos construtores vamos utilizá-lo combinando com uma
propriedade estática para armazenar a quantidade de clientes que já foram instanciados.
public class Cliente extends PessoaFisica{
private static int quantidadeCliente=0;
public Cliente() {
quantidadeCliente++;
}
public static int getQuantidadeCliente() {
return quantidadeCliente;
}
}
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 29
Imprimindo o número de instâncias de Objetos cliente
package br.com.fabricadeprogramador.sistemacadastro.construtores;
import br.com.fabricadeprogramador.sistemacadastro.Cliente;
public class ProgramaPrincipalClientes {
public static void main(String[] args) {
new Cliente();
new Cliente();
new Cliente();
System.out.println(Cliente.getQuantidadeCliente());
}
}
9 SOBRECARGA DE CONSTRUTORES
Exemplos de uso de construtores sobrecarregados nos tipos básicos do Java.
Construtores sobrecarregado do tipo java.lang.Integer
//Construtor sobrecarregado parâmetro String
Integer numero1 = new Integer("10");
//Construtor sobrecarregado parâmetro int
Integer numero2 = new Integer(10);
Alguns construtores Sobrecarregados do java.lang.String
String texto1 = new String();
String texto2 = new String(new byte[3]);
String texto3 = new String(new char[3]);
String texto4 = new String("Fábrica de Programador");
String texto5 = new String(new StringBuffer());
10 MÉTODOS SOBRECARREGADOS
Assim como sobrecarregamos os construtores também sobrecarregamos os métodos. Ao
sobrecarregarmos os métodos temos que tomar o cuidado para sempre deixar o modificador
de acesso com o mesmo nível ou mais alto. Um método private não pode ser sobrescrito. Se
o método for default, o mesmo pode ser sobrescrito por default ou por public. Se o método
for public não pode ser sobrescrito por default.
public class ValidacaoUtil {
static String cpfEstatico; // propriedade não estática
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 30
public static void validarCpf(String cpf) {
//valida CPF com os pontos (mascara)
}
public static void validarCpf(Integer cpf){
//valida CPF sem os pontos (mascara)
}
}
11 CLASSES ABSTRATAS
Classes abstratas são classes que possuem métodos abstratos, ou seja, apenas a declaração
do método sem sua implementação. Quando uma classe possui um método abstrato então a
classe vira abstrata. Uma classe abstrata não pode ser instanciada, por que possuem
métodos sem implementação. Declaramos um método abstrato quando não queremos uma
implementação genérica padrão. Desta forma as classes filhas são obrigadas a implementar
o método abstrato. Dizemos que as classes filhas assinam um contrato onde elas concordam
em implementar os métodos abstratos da classe base abstrata. No exemplo abaixo vamos
mostrar um caso, no qual definimos que uma classe que estende de Funcionário deve possuir
uma implementação específica para o método calculoSalario. Assim a classe filha Analista e
Diretor devem implementar o método abstrato conforme seu tipo específico.
public abstract class Funcionario extends PessoaFisica {
private String cargo;
public String getCargo() {
return cargo;
}
public void setCargo(String cargo) {
this.cargo = cargo;
}
public abstract double calculoSalario();
}
Agora a classe que estende funcionário deve implementar o método abstrato da classe base.
Um Analista que é um Funcionário que tem seu cálculo de salário diferente de um diretor com
5% a mais de diferença do salário base.
public class Analista extends Funcionario{
public double calculoSalario() {
return getSalario() + (getSalario()*5/100);
}
}
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 31
Um Diretor é um Funcionário e logo deve implementar o método abstrato da classe base com
10% a mais de diferença do salário base.
public class Diretor extends Funcionario {
public double calculoSalario() {
return getSalario() + (getSalario()* 10/100);
}
}
12 INTERFACES
As interfaces nos permitem definir apenas o padrão de funcionamento ou comportamento dos
objetos. Ela é uma classe 100% abstrata não tendo propriedades e nem métodos concretos
(não abstratos). Usamos interfaces quando queremos trabalhar de forma mais genéricas na
família dos objetos sem entrar nos detalhes da implementação. Como analogia podemos
pensar nos componentes de um carro do mundo real. Eles são todos baseados em interfaces.
A interface Roda do carro diz que a rodas são de 4 furos e seu tamanho é 15. Existem vários
modelos de rodas para esse carro. A interface é o modelo de encaixe que define o padrão e
a roda propriamente dita é a implementação da interface. Podemos trocar de roda quando
quisermos desde que obedeça esse padrão estabelecido pela interface Roda. Assim é para
todos os componentes do carro, podemos trocar de som, trocar de volante, de rodas e de
peças porque o modelo dos componentes foi padronizado em interfaces. Isso garante que
podemos trocar de fabricante de pneus, de sons e etc.
Em nosso sistema vamos criar um Interface que irá padronizar um Pedido de um sistema de
pedidos. Nesta interface iremos apenas definir ou declarar os métodos que o sistema de
pedidos deve possuir. Com o código abaixo iremos construir a Interface Pedido, ou seja, o
padrão que uma implementação de Pedido deve assumir.
public interface Pedido {
public Integer getCodigo()
public Double calcularValorTotal()
public void adicionarItem(ItemPedido itemPedido);
public void removerItemPedido(ItemPedido itemPedido);
public void imprimirItens();
public ItemPedido[] ordenarItensPedidos();
public ItemPedido[] getItensPedidos();
}
Um pedido será constituído de vários itens que iremos chamar de ItemPedido. Vários objetos
podem ser considerados como Itens a serem pedidos em sistema comercial. Por exemplo,
em uma escola podemos ter objetos Livros e Cursos que podem compor um Pedido que é
uma compra. Em uma pizzaria podemos ter Pizza, Refrigerante, Sucos como sendo itens do
Pedido e assim por diante. Na maioria das vezes neste caso uma classe Produto poderia ser
utilizada para representar os itens de um Pizzaria de forma mais genérica.
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 32
Vamos criar uma Interface para definir a representação de um Item de um Pedido.
public interface ItemPedido {
//utilizado para garantir uma ordenação
public Integer getCodigo() ;
public void setCodigo(Integer codigo);
public Double getValor() ;
public void setValor(Double valor);
public String getDescricao() ;
public void setDescricao(String descricao);
}
Com esta interface nós garantimos alguns métodos para cada ItemPedido.
12.1 Implementando as Interfaces
Vamos agora fazer a implementação da interface ItemPedido. Esta interface faz com que um
objeto possa possuir o comportamento padrão de um itemPedido. Um exemplo de item que
pode compor um pedido é um Curso. Então façamos a classe Curso implementar a Interface
ItemPedido por meio da palavra reservada implements.
public class Curso implements ItemPedido {
// propriedade para os métodos definidos na interface
private Integer codigo;
private Double valor;
private String descricao;
// Propriedade especificas
private String conteudo;
private String publicoAlvo;
private String cargaHoraria;
public Integer getCodigo() {
return codigo;
}
public void setCodigo(Integer codigo) {
this.codigo = codigo;
}
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 33
public Double getValor() {
return valor;
}
public void setValor(Double valor) {
this.valor = valor;
}
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
//Outros métodos aqui
}
Um outro exemplo de um ItemPedido pode ser um Livro.
import java.util.Date;
public class Livro implements ItemPedido {
//propriedade para os métodos definidos na interface
private Integer codigo;
private Double valor;
private String descricao;
// Propriedade especificas
private String autor;
private String editora;
private Date dataPublicacao;
public Integer getCodigo() {
return codigo;
}
public void setCodigo(Integer codigo) {
this.codigo = codigo;
}
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 34
public Double getValor() {
return valor;
}
public void setValor(Double valor) {
this.valor = valor;
}
public String getDescricao() {
return descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
//Outros métodos aqui
}
Agora vamos implementar o Pedido utilizando uma classe PedidoImpl, em que o sufixo Impl
é apenas uma abreviação de Implementação como convenção. A classe que implementa a
interface decide como trabalhar os métodos.
public class PedidoImpl implements Pedido {
private Integer codigo;
private Date data;
private Cliente cliente;
private ItemPedido itens[];
public Integer getCodigo() {
// Implementação aqui
}
public Double calcularValorTotal() {
// Implementação aqui
}
public void adicionarItem(ItemPedido itemPedido) {
// Implementação aqui
}
public void removerItemPedido(ItemPedido itemPedido) {
// Implementação aqui
}
public void imprimirItens() {
// Implementação aqui
}
public ItemPedido[] ordenarItensPedidos() {
// Implementação aqui
}
public ItemPedido[] getItensPedidos() {
// Implementação aqui
}
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 35
// Outros métodos aqui
}
Programa Principal de exemplo para construção de um Pedido
public class ProgramaPrincipalPedido {
public static void main(String[] args) {
Pedido pedido = new PedidoImpl();
int codigoItem = 1;
ItemPedido livro = new Livro();
livro.setCodigo(codigoItem);
livro.setValor(120.50);
livro.setDescricao("Livro de Java");
ItemPedido curso1 = new Curso();
curso1.setCodigo(++codigoItem);
curso1.setDescricao("Desenvolvimento para Android");
ItemPedido curso2 = new Curso();
curso2.setCodigo(++codigoItem);
curso2.setDescricao("Fábrica de Programador");
pedido.adicionarItem(livro);
pedido.adicionarItem(curso1);
pedido.adicionarItem(curso2);
pedido.imprimirItens();
double total = pedido.calcularValorTotal();
System.out.println(total);
pedido.removerItemPedido(curso1);
double novoTotal = pedido.calcularValorTotal();
System.out.println(novoTotal);
pedido.ordenarItensPedidos();
pedido.imprimirItens();
}
}
Anônimos - Um gerenciador de Registros Genérico
Uma classe anônima pode ser construída a partir de uma instância de um objeto que é
construído de forma oculta ao tentarmos iniciar uma Interface. Podemos alterar o
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 36
ProgramaPrincipalPedido para incluir um objeto que não possui uma classe, porém ele
implementa a interface ItemPedido. Um objeto anônimo com referência.
ItemPedido curso2 = new Curso();
curso2.setCodigo(++codigoItem);
curso2.setDescricao("Fábrica de Programador");
//Construção de um objeto anonimo do tipo ItemPedido
ItemPedido itemAnonimo = new ItemPedido() {
public void setValor(Double valor) {
//Implementação do anonimo aqui
}
public void setDescricao(String descricao) {
//Implementação do anonimo aqui
}
public void setCodigo(Integer codigo) {
//Implementação do anonimo aqui
}
public Double getValor() {
//Implementação do anonimo aqui
return null;
}
public String getDescricao() {
//Implementação do anonimo aqui
return null;
}
public Integer getCodigo() {
//Implementação do anonimo aqui
return null;
}
};
pedido.adicionarItem(livro);
pedido.adicionarItem(curso1);
pedido.adicionarItem(curso2);
pedido.adicionarItem(itemAnonimo);
Construindo a instância de um objeto anônimo e já passando como parâmetro no
método sem referência
pedido.adicionarItem(new ItemPedido() {
public void setValor(Double valor) {
//Implementação do anonimo aqui
}
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 37
public void setDescricao(String descricao) {
//Implementação do anonimo aqui
}
public void setCodigo(Integer codigo) {
//Implementação do anonimo aqui
}
public Double getValor() {
//Implementação do anonimo aqui
return null;
}
public String getDescricao() {
//Implementação do anonimo aqui
return null;
}
public Integer getCodigo() {
//Implementação do anonimo aqui
return null;
}
});
13 GENÉRICOS - UM GERENCIADOR DE REGISTROS GENÉRICO
A interface genérica Gerenciador Registro padroniza o comportamento de um objeto que tem
a função de gerenciar registros. Essa interface garante que se o objeto terá um a função de
gerenciar registro em um arquivo de texto, um vetor ou até mesmo em um banco de dados,
ele deverá realizar no mínimo os métodos que estão declarados nela.
public interface GerenciadorRegistro<T> {
public void salvar(T obj);
public void excluir(T obj);
public void pesquisar(T obj);
public void imprimirTodos();
}
Conforme falamos, este gerenciador define as operações básicas de um gerenciador de
registros onde podemos utilizar esta interface para construir um Gerenciador de registro de
Pedido, de Clientes, Cidades, Estados e etc.
O tipo parametrizado <T> quer dizer que o tipo do objeto que o método deverá suportar com
parâmetro de entrada e de retorno vai ser definido pela classe que implementar a interface.
Uma classe pode dizer que <T> é Cidade por exemplo desde modo:
GerenciadorRegistro<Cidade>, ou dizer que é Estado, GerenciadorRegistro<Estado>, ou
Pedido como: GerenciadorRegistro<Pedido>. O que precisamos entender é que o <T> é que
faz a classe ficar genérica.
Exemplo de implementação para um Gerenciador de Registros (GR) de Cidades
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 38
public class GRCidade implements GerenciadorRegistro<Cidade> {
public void salvar(Cidade obj) {
// Implementação aqui
}
public void excluir(Cidade obj) {
// Implementação aqui
}
public void pesquisar(Cidade obj) {
// Implementação aqui
}
public void imprimirTodos() {
// Implementação aqui
}
}
No exemplo acima o GRCidade que define qual será a estrutura de armazenamento e
independente disso deve possuir os métodos da interface implementados para garantir seu
funcionamento como Gerenciador de Registros.
14 TRABALHANDO COM COLEÇÕES
Estrutura da API do java para tratar coleções de objetos.
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 39
14.1 List
Uma lista dinâmica de objetos organizada em vetor e acessível por meio de índices que aceita
objetos duplicados. Na API () padrão do Java iremos utilizar várias classes que utilizam tipos
genéricos como uma lista de objetos da Interface List<E>.
java.util.List<E> é uma interface que possui uma implementação padrão em java
java.util.ArrayList<E>. Esta interface define o comportamento padrão de uma Lista Dinâmica.
Um ArrayList nos permite armazenar objetos em um Array Dinâmico de objetos, ou seja, a
alocação do objeto na posição do vetor é dinâmica na qual o ArrayList que controla o número
de posições. No exemplo abaixo podemos ver que da interface java.util.List estende outra
Interface chamada Collection. Isso quer dizer que a classe que implementar List<E> deverá
também implementar os métodos herdados de Collection.
public interface List<E> extends Collection<E> {
int size();
boolean isEmpty();
boolean add(E e);
//Outros métodos declarados aqui
}
14.2 Exemplo de Uso da Interface List com ArrayList
Um ArrayList é uma lista, portanto podemos fazer a atribuição polimórfica declarando uma
variável do tipo da Interface apontando para uma instância de ArrayList.
public class ProgramaPrincipalArrayList {
public static void main(String[] args) {
List<Cliente> clientes = new ArrayList<Cliente>(); clientes.add(new
Cliente());
Cliente clienteAcessado = clientes.get(0);
Cliente clienteRemovido = clientes.remove(0);
}
}
Adicionando mais objetos na lista
clientes.add(new Cliente("Jão"));
clientes.add(new Cliente("Maria"));
clientes.add(new Cliente("Maria"));
clientes.add(new Cliente("José"));
Iterando sobre o Set por meio do índice
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 40
for (int i = 0; i < clientes.size(); i++) {
Cliente cliente = clientes.get(i);
System.out.println(cliente.getNome());
}
Iterando sobre o Set por meio do objeto Iterator
for (Iterator iterator = clientes.iterator(); iterator.hasNext();) {
Cliente cliente = (Cliente) iterator.next();
System.out.println(cliente.getNome());
}
Iterando sobre o Set por meio do For Each
for (Cliente cliente : clientes) {
System.out.println(cliente.getNome());
}
14.3 Set
Não permite registros duplicados. Utilize os métodos equals e hashcode para definir o critério
de igualdade. Sua organização não permite acesso por índice.
Adicionando no conjunto
//Atribuindo os nomes em um conjunto
Set<String> nomes = new HashSet<String>();
nomes.add("Maria");
nomes.add("José");
nomes.add("Maria");
Verificando se um objeto está no conjunto
//verificando se contam um objetos no conjunto
boolean contem = nomes.contains("Maria") ;
System.out.println("Contem Maria? " + contem );
Removendo do conjunto
//removendo objeto do conjunto
nomes.remove("Maria");
Iterando sobre o Set por meio do For Each
for (String nome : nomes) {
System.out.println(nome);
}
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 41
Iterando sobre o Set por meio do objeto Iterator
Iterator<String> iterador = nomes.iterator();
while (iterador.hasNext()) {
String nome = (String) iterador.next();
System.out.println(nome);
}
14.4 Map
Armazena os elementos na forma de pares chaves/valor. As chaves são exclusivas não
podendo ser duplicadas. Os acessos aos objetos são feitos pela chave que são únicas.
public class ProgramaPrincipalMap {
public static void main(String[] args) {
Map<String, String> linguagensProgramacao = new
HashMap<String,String>();
linguagensProgramacao.put("Java", "Web, Móvel e Desktop");
linguagensProgramacao.put("PHP", "Web");
linguagensProgramacao.put("Java Script", "Web Navegador de Internet");
}
}
Removendo do Map por meio da chave
linguagensProgramacao.remove("PHP");
Imprimindo por meio da chave
//Imprimindo por meio de chave
System.out.println(linguagensProgramacao.get("Java"));
Imprimindo por meio de um conjunto de chaves
//Imprimindo por meio de um Set de Chaves
Set<String> keys = linguagensProgramacao.keySet();
for (String k : keys) {
System.out.println(linguagensProgramacao.get(k));
}
15 EXCEPTIONS
Quando executamos um método ou um construtor algo perigoso pode acontecer. Uma
exceção é um objeto java contendo informação de um erro ocorrido em tempo de execução.
Ao tentarmos realizar um cálculo aritmético por exemplo 10/0. O que acontece? Uma exceção.
Um objeto de exceção é instanciado automaticamente pela JVM e enviado para nosso
método. Existem exceções que a JVM lança automaticamente e outras que são lançadas
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 42
programaticamente, ou seja, um método via programação a instância um objeto de exceção
e lança.
Vamos entender um pouco mais:
Na API do Java temos uma família que forma uma hierarquia de classes com Exceções
nativas. Na figura acima temos um exemplo de como essa é a estrutura dessa herança.
A classe mais genérica que corresponde a família das Exceptions é Throwable. Logo, temos
a Exception e RuntimeException. Podemos classificá-las em dois grupos:
1. Grupo das filhas diretamente de Exception (Checked)
2. Grupo das filhas de RuntimeException (Uncheck)
15.1 Lançando uma Exception Unchecked (Não verificadas)
Este tipo de exceção ocorre por alguma falha na lógica de programação. Como exemplo,
pense em um vetor que possui apenas três posições e o código tenta acessar uma posição
que não existe. O Compilador não verifica esse tipo de situação e quando rodarmos o
programa em tempo de execução uma exceção será lançada. Uma exceção é um objeto
derivado ou herdado da classe java.lang.Exception. Este objeto contém várias informações
sobre o erro ocorrido.
No caso abaixo será lançada uma exceção na linha 7 ao tentar atribuir um valor na posição 3
do vetor que não existe pois o mesmo tem apenas 3 posições sendo 0, 1 e 2.
1. public class ProgramaPrincipalException {
2. public static void main(String[] args) {
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 43
3. int [] vetor = new int[3];
4. vetor[0]=10;
5. vetor[1]=20;
6. vetor[2]=30;
7. vetor[3]=40;
8. }
9. }
10.
A Exception lançará uma mensagem como:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at
br.com.fabricadeprogramador.sistemacadastro.sobrescrita.ProgramaPrincipalE
xception.main(ProgramaPrincipalException.java:7)
java.lang.ArrayIndexOutOfBoundsException: 3
15.2 Lançando uma Exception Checked (Verificadas)
Uma exceção Verificada é uma classe que estende diretamente da classe base
java.lang.Exception, logo este método não é da família de RuntimeException.
Criando uma classe CPFInvalidException derivada de java.lang.Exception.
Essa classe será utilizada para lançar um objeto Exception contendo informação sobre um
CPF Inválido. Iremos utilizar esse um objeto dessa classe em um método de validação de
CPF.
public class CPFInvalidException extends Exception {
//Construtor padrão
public CPFInvalidException() {
//passando para o construtor sobrecarregado da classe base
uma mensagem
//padrão
super("CPF inválido!");
}
}
Em nossa classe ValidacaoUtil vamos implementar uma simples validação que verifica se o
CPF informado no parâmetro é válido ou não.
Consideramos que para ser válido o CPF o mesmo deve conter 11 dígitos e se isso não for
verdade então um objeto da classe CPFInvalidException será instanciado (new) e lançado
(throws). Para isso ser possível devemos declarar na assinatura do método que ele poderá
fazer o lançamento throws CPFInvalidException.
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 44
//Na assinatura do método temos que declarar um possível lançamento de
Exception do tipo CPFInvalidException
public static void validarCpf(String cpf) throws CPFInvalidException {
if(cpf.length()!=11){
//Instânciando e lançando uma Exception
throw new CPFInvalidException();
}
}
Uma verificação consiste em tratar a Exception. Temos basicamente duas formas de tratar a
Exception, sendo uma delas usando o try – catch, no qual nós “pegamos” o objeto da exceção
lançada e outra através de uma redeclaração throws onde dizermos que não queremos
“pegar” o objeto Exception lançado.
Agora vamos programar no programa principal uma chamada ao método validarCpf que deve
ser verificado. É agora que acontece a verificação, quando formos invocar o método que diz
que pode lançar uma Exception. Ao tentar invocar o método sem fazer a verificação o
compilador avisa.
public class ProgramaPrincipalException2 { public
static void main(String[] args) {
ValidacaoUtil.validarCpf("905.098.531-90");
}
}
Uma mensagem do
compilador diz que a
exceção deve ser
manipulada:
Unhandled exception type
CPFInvalidException
Forma 1
public class ProgramaPrincipalException2 { public
static void main(String[] args) {
try {
ValidacaoUtil.validarCpf("905.098.531-90");
} catch (CPFInvalidException e) {
//Tratamento da Exception
e.printStackTrace();
}
}
}
Uma forma de fazer o
tratamento é “pegar” o
objeto por meio da
estrutura try-cath. O try
tenta executar o método e
se a exceção for lançada
pelo método validarCpf
então o catch recebe como
parâmetro o objeto o
CPFInvalidException que
foi lançado. A variável
(CPFInvalidException e) é
um parâmetro do bloco
cath funcionando como
uma referência ao objeto
CPFInvalidException
lançada.
Forma 2
public class ProgramaPrincipalException2 {
public static void main(String[] args)
throws CPFInvalidException {
ValidacaoUtil.validarCpf("905.098.531-90");
}
Uma outra forma é
redeclarar na assinatura
do método main que
possui uma chamada ao
método validarCpf
informando que o método
não vai “pegar” a exceção.
Projeto Fábrica de Programador – Módulo 2
www.fabricadeprogramador.com.br Página: 45
} throws
CPFInvalidException
Parabéns pela conclusão de mais uma fase do projeto Fábrica de Programador! No próximo
módulo iremos aprender a fazer aplicações mais interessantes, voltadas para Web.

Mais conteúdo relacionado

Mais procurados

Aula 02 - Principios da Orientação a Objetos (POO)
Aula 02 - Principios da Orientação a Objetos (POO)Aula 02 - Principios da Orientação a Objetos (POO)
Aula 02 - Principios da Orientação a Objetos (POO)Daniel Brandão
 
Linguagem Java - Conceitos e Técnicas
Linguagem Java - Conceitos e TécnicasLinguagem Java - Conceitos e Técnicas
Linguagem Java - Conceitos e TécnicasBreno Vitorino
 
[Lógica] Orientação a Objetos descomplicada
[Lógica] Orientação a Objetos descomplicada[Lógica] Orientação a Objetos descomplicada
[Lógica] Orientação a Objetos descomplicadaEduardo Ricoldi
 
Coreldraw graphics suite x6 português
Coreldraw graphics suite x6   portuguêsCoreldraw graphics suite x6   português
Coreldraw graphics suite x6 portuguêsJosé Maria Oliveira
 
Coreldraw graphics suite_x5
Coreldraw graphics suite_x5Coreldraw graphics suite_x5
Coreldraw graphics suite_x5aulaemvideo
 
Corel draw x6-br
Corel draw x6-brCorel draw x6-br
Corel draw x6-brLucia Rosas
 

Mais procurados (11)

Aula 02 - Principios da Orientação a Objetos (POO)
Aula 02 - Principios da Orientação a Objetos (POO)Aula 02 - Principios da Orientação a Objetos (POO)
Aula 02 - Principios da Orientação a Objetos (POO)
 
POO - 16 - Polimorfismo
POO - 16 - PolimorfismoPOO - 16 - Polimorfismo
POO - 16 - Polimorfismo
 
Linguagem Java - Conceitos e Técnicas
Linguagem Java - Conceitos e TécnicasLinguagem Java - Conceitos e Técnicas
Linguagem Java - Conceitos e Técnicas
 
Padrões de projeto
Padrões de projetoPadrões de projeto
Padrões de projeto
 
[Lógica] Orientação a Objetos descomplicada
[Lógica] Orientação a Objetos descomplicada[Lógica] Orientação a Objetos descomplicada
[Lógica] Orientação a Objetos descomplicada
 
Manual corel draw
Manual corel drawManual corel draw
Manual corel draw
 
Coreldraw graphics suite x6 português
Coreldraw graphics suite x6   portuguêsCoreldraw graphics suite x6   português
Coreldraw graphics suite x6 português
 
Introdução ao C#
Introdução ao C#Introdução ao C#
Introdução ao C#
 
Coreldraw graphics suite_x5
Coreldraw graphics suite_x5Coreldraw graphics suite_x5
Coreldraw graphics suite_x5
 
Corel draw x6-br
Corel draw x6-brCorel draw x6-br
Corel draw x6-br
 
Curso Java Basico
Curso Java BasicoCurso Java Basico
Curso Java Basico
 

Destaque

UNA TECNOLOGÍA DIFERENTE
UNA TECNOLOGÍA DIFERENTEUNA TECNOLOGÍA DIFERENTE
UNA TECNOLOGÍA DIFERENTEanabela sanchez
 
environmental landscape
environmental landscapeenvironmental landscape
environmental landscapeJulian_Divakar
 
Paulo Vieira de Souza fala sobre a Atlantic Ocean Road
Paulo Vieira de Souza fala sobre a Atlantic Ocean Road Paulo Vieira de Souza fala sobre a Atlantic Ocean Road
Paulo Vieira de Souza fala sobre a Atlantic Ocean Road Paulo Vieira de Souza
 
Dna repair
Dna repairDna repair
Dna repairpravee14
 
SanchaITSolutions_CompanyProfile
SanchaITSolutions_CompanyProfileSanchaITSolutions_CompanyProfile
SanchaITSolutions_CompanyProfileKalaivani L
 
20160503 橫a5左翻含封面72頁 中藥材辨識手冊v2
20160503 橫a5左翻含封面72頁 中藥材辨識手冊v220160503 橫a5左翻含封面72頁 中藥材辨識手冊v2
20160503 橫a5左翻含封面72頁 中藥材辨識手冊v2Goldon Chou
 
Enfermedades mentales (1)
Enfermedades mentales (1)Enfermedades mentales (1)
Enfermedades mentales (1)Mitzy Chávez
 
BonillaDanielle_Resume_doc.1
BonillaDanielle_Resume_doc.1BonillaDanielle_Resume_doc.1
BonillaDanielle_Resume_doc.1Danielle Bonilla
 
The Boodles 2015 Media Cuttings
The Boodles 2015 Media CuttingsThe Boodles 2015 Media Cuttings
The Boodles 2015 Media CuttingsTheEmiliaGroup
 
Benefits Realization - May 2016
Benefits Realization - May 2016Benefits Realization - May 2016
Benefits Realization - May 2016Haresh Desai
 

Destaque (18)

Motivasi Berjuang 01
Motivasi Berjuang 01Motivasi Berjuang 01
Motivasi Berjuang 01
 
UNA TECNOLOGÍA DIFERENTE
UNA TECNOLOGÍA DIFERENTEUNA TECNOLOGÍA DIFERENTE
UNA TECNOLOGÍA DIFERENTE
 
environmental landscape
environmental landscapeenvironmental landscape
environmental landscape
 
VITA Certificates
VITA CertificatesVITA Certificates
VITA Certificates
 
Tarea seminario 6
Tarea seminario 6Tarea seminario 6
Tarea seminario 6
 
Fedesoft Bootstrap UTB
Fedesoft Bootstrap UTBFedesoft Bootstrap UTB
Fedesoft Bootstrap UTB
 
Paulo Vieira de Souza fala sobre a Atlantic Ocean Road
Paulo Vieira de Souza fala sobre a Atlantic Ocean Road Paulo Vieira de Souza fala sobre a Atlantic Ocean Road
Paulo Vieira de Souza fala sobre a Atlantic Ocean Road
 
Logistics Plus - 4PL Solutions
Logistics Plus - 4PL SolutionsLogistics Plus - 4PL Solutions
Logistics Plus - 4PL Solutions
 
Seminario 6.2.
Seminario 6.2.Seminario 6.2.
Seminario 6.2.
 
Dna repair
Dna repairDna repair
Dna repair
 
SanchaITSolutions_CompanyProfile
SanchaITSolutions_CompanyProfileSanchaITSolutions_CompanyProfile
SanchaITSolutions_CompanyProfile
 
20160503 橫a5左翻含封面72頁 中藥材辨識手冊v2
20160503 橫a5左翻含封面72頁 中藥材辨識手冊v220160503 橫a5左翻含封面72頁 中藥材辨識手冊v2
20160503 橫a5左翻含封面72頁 中藥材辨識手冊v2
 
0 proje yonetimi egitimi
0   proje yonetimi egitimi0   proje yonetimi egitimi
0 proje yonetimi egitimi
 
Enfermedades mentales (1)
Enfermedades mentales (1)Enfermedades mentales (1)
Enfermedades mentales (1)
 
BonillaDanielle_Resume_doc.1
BonillaDanielle_Resume_doc.1BonillaDanielle_Resume_doc.1
BonillaDanielle_Resume_doc.1
 
The Boodles 2015 Media Cuttings
The Boodles 2015 Media CuttingsThe Boodles 2015 Media Cuttings
The Boodles 2015 Media Cuttings
 
pp 2
pp 2pp 2
pp 2
 
Benefits Realization - May 2016
Benefits Realization - May 2016Benefits Realization - May 2016
Benefits Realization - May 2016
 

Semelhante a TESTE

Aula 1 - Introdução a POO
Aula 1 -  Introdução a POOAula 1 -  Introdução a POO
Aula 1 - Introdução a POODaniel Brandão
 
Aula 2 Prof. MSc. Cloves Rocha BV - (2018.2) CCO 2 MA - POO
Aula 2 Prof. MSc. Cloves Rocha BV - (2018.2) CCO 2 MA - POOAula 2 Prof. MSc. Cloves Rocha BV - (2018.2) CCO 2 MA - POO
Aula 2 Prof. MSc. Cloves Rocha BV - (2018.2) CCO 2 MA - POOCloves da Rocha
 
Aula 2 Prof. MSc. Cloves Rocha - PIE - (2018.2) GTI 2 NA - POO
Aula 2 Prof. MSc. Cloves Rocha - PIE - (2018.2) GTI 2 NA - POOAula 2 Prof. MSc. Cloves Rocha - PIE - (2018.2) GTI 2 NA - POO
Aula 2 Prof. MSc. Cloves Rocha - PIE - (2018.2) GTI 2 NA - POOCloves da Rocha
 
Módulo 9 - Introdução à Programação Orientada a Objectos
Módulo 9 - Introdução à Programação Orientada a Objectos Módulo 9 - Introdução à Programação Orientada a Objectos
Módulo 9 - Introdução à Programação Orientada a Objectos Luis Ferreira
 
ebook-completo c# o melhor para começar no c#
ebook-completo c# o melhor para começar no c#ebook-completo c# o melhor para começar no c#
ebook-completo c# o melhor para começar no c#biandamakengo08
 
Introdução a classes e objetos
Introdução a classes e objetosIntrodução a classes e objetos
Introdução a classes e objetosCícero Quarto
 
Plano de Projeto - Gerencia de Projetos
Plano de Projeto - Gerencia de ProjetosPlano de Projeto - Gerencia de Projetos
Plano de Projeto - Gerencia de ProjetosHelder Filho
 
Linguagens de programação 12º M11
Linguagens de programação 12º M11Linguagens de programação 12º M11
Linguagens de programação 12º M11Luis Ferreira
 
MVC já era! O negócio é DCI!
MVC já era! O negócio é DCI!MVC já era! O negócio é DCI!
MVC já era! O negócio é DCI!Flávio Lisboa
 
Introdução a programação Orientada a Objeto
Introdução a programação Orientada a ObjetoIntrodução a programação Orientada a Objeto
Introdução a programação Orientada a ObjetoMarconi Rodrigues
 
Reutilização
ReutilizaçãoReutilização
Reutilizaçãoemjorge
 

Semelhante a TESTE (20)

Aula 1 - Introdução a POO
Aula 1 -  Introdução a POOAula 1 -  Introdução a POO
Aula 1 - Introdução a POO
 
Aula 2 Prof. MSc. Cloves Rocha BV - (2018.2) CCO 2 MA - POO
Aula 2 Prof. MSc. Cloves Rocha BV - (2018.2) CCO 2 MA - POOAula 2 Prof. MSc. Cloves Rocha BV - (2018.2) CCO 2 MA - POO
Aula 2 Prof. MSc. Cloves Rocha BV - (2018.2) CCO 2 MA - POO
 
Aula 2 Prof. MSc. Cloves Rocha - PIE - (2018.2) GTI 2 NA - POO
Aula 2 Prof. MSc. Cloves Rocha - PIE - (2018.2) GTI 2 NA - POOAula 2 Prof. MSc. Cloves Rocha - PIE - (2018.2) GTI 2 NA - POO
Aula 2 Prof. MSc. Cloves Rocha - PIE - (2018.2) GTI 2 NA - POO
 
Naked Objects
Naked ObjectsNaked Objects
Naked Objects
 
Módulo 9 - Introdução à Programação Orientada a Objectos
Módulo 9 - Introdução à Programação Orientada a Objectos Módulo 9 - Introdução à Programação Orientada a Objectos
Módulo 9 - Introdução à Programação Orientada a Objectos
 
ebook-completo c# o melhor para começar no c#
ebook-completo c# o melhor para começar no c#ebook-completo c# o melhor para começar no c#
ebook-completo c# o melhor para começar no c#
 
Aula 1 4
Aula 1 4Aula 1 4
Aula 1 4
 
Programação Orientada por Objectos - Aula 1
Programação Orientada por Objectos - Aula 1Programação Orientada por Objectos - Aula 1
Programação Orientada por Objectos - Aula 1
 
Plano deprojeto grupo1
Plano deprojeto grupo1Plano deprojeto grupo1
Plano deprojeto grupo1
 
Plano deprojeto grupo1
Plano deprojeto grupo1Plano deprojeto grupo1
Plano deprojeto grupo1
 
POO.pdf
POO.pdfPOO.pdf
POO.pdf
 
Introdução a classes e objetos
Introdução a classes e objetosIntrodução a classes e objetos
Introdução a classes e objetos
 
Plano de Projeto - Gerencia de Projetos
Plano de Projeto - Gerencia de ProjetosPlano de Projeto - Gerencia de Projetos
Plano de Projeto - Gerencia de Projetos
 
Linguagens de programação 12º M11
Linguagens de programação 12º M11Linguagens de programação 12º M11
Linguagens de programação 12º M11
 
Padrões de Projeto de Software
Padrões de Projeto de SoftwarePadrões de Projeto de Software
Padrões de Projeto de Software
 
MVC já era! O negócio é DCI!
MVC já era! O negócio é DCI!MVC já era! O negócio é DCI!
MVC já era! O negócio é DCI!
 
Introdução a programação Orientada a Objeto
Introdução a programação Orientada a ObjetoIntrodução a programação Orientada a Objeto
Introdução a programação Orientada a Objeto
 
Aula1
Aula1Aula1
Aula1
 
Reutilização
ReutilizaçãoReutilização
Reutilização
 
Java aula 2
Java aula 2Java aula 2
Java aula 2
 

Último

Ranking Brasil abril 2024 sites de notícias.pdf
Ranking Brasil abril 2024 sites de notícias.pdfRanking Brasil abril 2024 sites de notícias.pdf
Ranking Brasil abril 2024 sites de notícias.pdfRevista Sociedade Militar
 
representações cartograficas - 1 ano.pptx
representações cartograficas - 1 ano.pptxrepresentações cartograficas - 1 ano.pptx
representações cartograficas - 1 ano.pptxCarladeOliveira25
 
Conferência SC 24 | A força da geolocalização impulsionada em ADS e Fullcomme...
Conferência SC 24 | A força da geolocalização impulsionada em ADS e Fullcomme...Conferência SC 24 | A força da geolocalização impulsionada em ADS e Fullcomme...
Conferência SC 24 | A força da geolocalização impulsionada em ADS e Fullcomme...E-Commerce Brasil
 
Products Catalogue-01-Electronics thin wall heat shrink tubing wire and cable...
Products Catalogue-01-Electronics thin wall heat shrink tubing wire and cable...Products Catalogue-01-Electronics thin wall heat shrink tubing wire and cable...
Products Catalogue-01-Electronics thin wall heat shrink tubing wire and cable...Welldonelily Skype
 
EP GRUPO - Mídia Kit 2024 - conexão de marcas e personagens
EP GRUPO - Mídia Kit 2024 - conexão de marcas e personagensEP GRUPO - Mídia Kit 2024 - conexão de marcas e personagens
EP GRUPO - Mídia Kit 2024 - conexão de marcas e personagensLuizPauloFerreira11
 
Conferência SC 24 | Estratégias de precificação: loja própria e marketplace
Conferência SC 24 | Estratégias de precificação: loja própria e marketplaceConferência SC 24 | Estratégias de precificação: loja própria e marketplace
Conferência SC 24 | Estratégias de precificação: loja própria e marketplaceE-Commerce Brasil
 
Conferência SC 24 | Social commerce e recursos interativos: como aplicar no s...
Conferência SC 24 | Social commerce e recursos interativos: como aplicar no s...Conferência SC 24 | Social commerce e recursos interativos: como aplicar no s...
Conferência SC 24 | Social commerce e recursos interativos: como aplicar no s...E-Commerce Brasil
 
Conferência SC 24 | Data Analytics e IA: o futuro do e-commerce?
Conferência SC 24 | Data Analytics e IA: o futuro do e-commerce?Conferência SC 24 | Data Analytics e IA: o futuro do e-commerce?
Conferência SC 24 | Data Analytics e IA: o futuro do e-commerce?E-Commerce Brasil
 

Último (8)

Ranking Brasil abril 2024 sites de notícias.pdf
Ranking Brasil abril 2024 sites de notícias.pdfRanking Brasil abril 2024 sites de notícias.pdf
Ranking Brasil abril 2024 sites de notícias.pdf
 
representações cartograficas - 1 ano.pptx
representações cartograficas - 1 ano.pptxrepresentações cartograficas - 1 ano.pptx
representações cartograficas - 1 ano.pptx
 
Conferência SC 24 | A força da geolocalização impulsionada em ADS e Fullcomme...
Conferência SC 24 | A força da geolocalização impulsionada em ADS e Fullcomme...Conferência SC 24 | A força da geolocalização impulsionada em ADS e Fullcomme...
Conferência SC 24 | A força da geolocalização impulsionada em ADS e Fullcomme...
 
Products Catalogue-01-Electronics thin wall heat shrink tubing wire and cable...
Products Catalogue-01-Electronics thin wall heat shrink tubing wire and cable...Products Catalogue-01-Electronics thin wall heat shrink tubing wire and cable...
Products Catalogue-01-Electronics thin wall heat shrink tubing wire and cable...
 
EP GRUPO - Mídia Kit 2024 - conexão de marcas e personagens
EP GRUPO - Mídia Kit 2024 - conexão de marcas e personagensEP GRUPO - Mídia Kit 2024 - conexão de marcas e personagens
EP GRUPO - Mídia Kit 2024 - conexão de marcas e personagens
 
Conferência SC 24 | Estratégias de precificação: loja própria e marketplace
Conferência SC 24 | Estratégias de precificação: loja própria e marketplaceConferência SC 24 | Estratégias de precificação: loja própria e marketplace
Conferência SC 24 | Estratégias de precificação: loja própria e marketplace
 
Conferência SC 24 | Social commerce e recursos interativos: como aplicar no s...
Conferência SC 24 | Social commerce e recursos interativos: como aplicar no s...Conferência SC 24 | Social commerce e recursos interativos: como aplicar no s...
Conferência SC 24 | Social commerce e recursos interativos: como aplicar no s...
 
Conferência SC 24 | Data Analytics e IA: o futuro do e-commerce?
Conferência SC 24 | Data Analytics e IA: o futuro do e-commerce?Conferência SC 24 | Data Analytics e IA: o futuro do e-commerce?
Conferência SC 24 | Data Analytics e IA: o futuro do e-commerce?
 

TESTE

  • 1. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Sumário 1 ORIENTAÇÃO AO ALUNO.............................................................................................3 2 CLASSES E OBJETOS ..................................................................................................3 2.1 Propriedades............................................................................................................3 2.2 Métodos ...................................................................................................................4 3 MÉTODOS GETTERS E SETTERS ...............................................................................5 4 RELACIONAMENTOS ENTRE OBJETOS DO TIPO “TEM UM”.....................................5 5 HERANÇA - RELACIONAMENTO DE OBJETOS DO TIPO “É UM” .............................10 5.1 Instanciando Polimorficamente ..............................................................................17 5.2 Fazendo Conversões (Casting)..............................................................................18 5.3 Sistema de Cadastro de Pessoas ..........................................................................19 6 MÉTODOS E PROPRIEDADES ESTÁTICAS...............................................................20 7 SOBRECARGA E SOBRESCRITA DE MÉTODOS ......................................................22 7.1 Sobrescrevendo o Método toString()......................................................................23 7.2 Sobrescrevendo o Método equals(Object obj)........................................................24 7.3 Utilizando a IDE para Gerar o Método Equals e Hashcode ....................................24 7.4 HashCode..............................................................................................................25 7.5 A Palavra Reservada This......................................................................................25 8 CONSTRUTORES........................................................................................................26 8.1 Construtor Sobrecarregado....................................................................................26 8.2 Sobrecarregando o Construtor de Cidade..............................................................28 8.3 Lembrando dos Estáticos.......................................................................................28 9 SOBRECARGA DE CONSTRUTORES ........................................................................29 10 MÉTODOS SOBRECARREGADOS .............................................................................29 11 CLASSES ABSTRATAS ...............................................................................................30 12 INTERFACES ...............................................................................................................31 12.1 Implementando as Interfaces .................................................................................32 13 GENÉRICOS - UM GERENCIADOR DE REGISTROS GENÉRICO .............................37 14 TRABALHANDO COM COLEÇÕES .............................................................................38 14.1 List .........................................................................................................................39 14.2 Exemplo de Uso da Interface List com ArrayList ....................................................39 14.3 Set .........................................................................................................................40 14.4 Map........................................................................................................................41 15 EXCEPTIONS...............................................................................................................41 15.1 Lançando uma Exception Unchecked (Não verificadas).........................................42 15.2 Lançando uma Exception Checked (Verificadas) ...................................................43 Versão: 2.0 2ª Edição
  • 2. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 3 1 ORIENTAÇÃO AO ALUNO Este material é continuação do módulo 1 do projeto Fábrica de Programador, nosso foco é ensinar os conceitos práticos de Orientação a Objetos de modo didático, com uma linguagem menos formal para auxiliar os desenvolvedores iniciantes a darem seus primeiros passos de modo prático e rápido, sem a necessidade de um embasamento teórico aprofundado. Logo, este material não foca os conceitos teóricos da computação. Para você se aprofundar na teoria da computação recomendamos que leia livros voltados para esse fim. 2 CLASSES E OBJETOS No modulo 1 (Java e Algoritmos) vimos os conceitos básicos de classe como sendo a estrutura básica dos objetos. Se você ainda tem dúvidas sobre o que são classe e objetos recomendamos a leitura da matéria do módulo 1. O que precisamos entender, é que um sistema é composto por vários objetos. Um objeto é uma instância da classe e cada objeto ocupa um espaço na memória podendo ser acessado por meio das variáveis de referência. As variáveis de referência guardam o endereço do objeto e funciona com um controle remoto onde podemos acessar seus métodos e propriedades de acordo de suas visibilidades. 2.1 Propriedades Os objetos possuem propriedades que servem para definir ou armazenar as características, campos ou atributos do objeto. No caso de um cliente, por exemplo, temos as propriedades: nome, CPF e RG. Exemplo de classe Cliente em Java
  • 3. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 4 Neste exemplo criamos a classe Cliente e instanciamos dois objetos com o comando new, no qual, cada objeto é uma cópia da classe na memória, com a mesma estrutura da classe. Os dados dos objetos são definidos no objeto. O objeto que possui nome “Jão da Silva” é totalmente independente do objeto que possui o nome “Maria da Silva”, embora os dois objetos vieram da mesma classe, eles não se conhecem por que estão em posições de memória diferentes. 2.2 Métodos Os métodos como já vimos no modulo 1, são as funções que o objeto realiza. Um objeto Calculadora pode possuir os métodos: somar(), multiplicar(), subtrair (), e dividir(). Exemplo de criação de método class Calculadora{ public double somar(double n1, double n2){ return n1+n2; } } Exemplo de invocação por meio de um objeto instanciado public class ProgramaPrincipalMetodos { public static void main(String[] args) { Calculadora c = new Calculadora(); System.out.println(c.somar(10, 20)); } } Representação gráfica da classe (UML) O diagrama de classes é um dos diagramas da UML (Unified Modeling Language ou Linguagem de Modelagem Unificada) que é uma linguagem visual utilizada para modelar softwares que utilizam o padrão orientação a objetos. Voltando a classe Cliente podemos fazer sua representação gráfica utilizando o diagrama como abaixo. Diagrama de Classe Código Java public class Cliente { private String nome; private String cpf; private String rg; }
  • 4. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 5 3 MÉTODOS GETTERS E SETTERS No módulo 1 estudamos sobre os métodos encapsuladores getters e setters. Estes métodos são encapsuladores de propriedades e servem para atribuição (set) e acesso (get) às mesmas. Exemplo public class Cliente { private String nome; public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } } Normalmente utilizamos os métodos getters e setters com modificadores de acesso público e das propriedades privadas. O modificador de acesso público permite a variável de instância a acessar o método e o modificador de acesso privado proíbe o acesso da propriedade pela instância. Para acessar uma propriedade privada somente um método da própria classe pode fazê-lo. Cliente cliente = new Cliente(); //Atribuindo o nome cliente.setNome("Jão da Silva"); //Acessando o nome System.out.println(cliente.getNome()); 4 RELACIONAMENTOS ENTRE OBJETOS DO TIPO “TEM UM” É muito comum termos que relacionar os objetos de um sistema. Um sistema em funcionamento nada mais é que um conjunto de objetos trocando mensagens entre si. Em um corpo humano os órgãos se comunicam entre si, onde cada um faz a sua função. Um software não é diferente, pois precisamos arquitetar e estruturar nossos objetos de modo que eles se comuniquem e sirvam uns aos outros. Pensemos em um caso: Para definirmos uma cidade para um cliente como faríamos? Fácil, basta acrescentarmos um campo ou propriedade chamado Cidade na classe Cliente do tipo String. Certo? Sim, pode ser, mas na maioria dos casos uma cidade será um objeto a parte e independente do cliente, então, neste caso, ao invés de colocarmos um atributo ou propriedade do tipo String em nosso Cliente nós colocaremos uma propriedade do tipo cidade que ainda iremos construir. Podemos dizer que o cliente “tem uma” cidade vinculada a ele.
  • 5. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 6 Classe Cliente sem Relacionamento com Classe Cliente tem Relacionamento com Classe Cidade Classe Cidade public class Cliente { private String nome; private String cpf; private String rg; } private String cidade; public class Cidade { private String nome; private String uf; } public class Cliente { private String nome; private String cpf; private String rg; //getters and Setters } private Cidade cidade; No primeiro caso, não teríamos o reaproveitamento das cidades e necessitaríamos sempre repetir o nome de uma mesma cidade várias vezes para clientes diferentes. Exemplo Cliente jao = new Cliente(); jao.setNome("Jão"); jao.setCidade("Campo Grande"); Cliente maria = new Cliente(); maria.setNome("Maria"); maria.setCidade("Campo Grande"); No segundo caso podemos construir apenas um objeto Cidade e reutilizá-lo em vários clientes. Na verdade, quem se relaciona são os objetos, porém, é na classe que escrevemos isso. Basicamente, o que devemos fazer é “setar” uma instância de Cidade na propriedade cidade do Cliente. Cidade cg = new Cidade(); cg.setNome("Campo Grande"); cg.setUf("MS"); Cliente jao = new Cliente(); jao.setNome("Jão"); jao.setCidade(cg);//Relacionamento com objeto Cidade Cliente maria = new Cliente(); maria.setNome("Maria"); maria.setCidade(cg);//Relacionamento com objeto Cidade Diagrama de Classe da UML
  • 6. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 7 No mundo real, vários clientes do sistema podem ter nascido em uma cidade. Na memória podemos imaginar vários objetos do tipo Cliente e vários objetos do tipo Cidade onde uma ou mais instâncias de clientes podem estar vinculados a uma mesma instância de cidade. Ao acessar um objeto tipo Cidade que está relacionado com um objeto tipo Cliente podemos, a partir da instância do Cliente, navegar no objeto Cidade porque a propriedade cidade nada mais é que uma referência para um objeto do tipo Cidade. Com o método getCidade() acessamos esta referência que foi “setada” para o cliente da instância jao. //Imprimindo dados da cidade do jao System.out.println(jao.getCidade().getNome() + " " + jao.getCidade().getUf()); Podemos, ainda, pensar na possibilidade de representarmos os estados de uma cidade como sendo objetos a parte. Ao invés de termos uma propriedade String uf, poderíamos ter uma propriedade do tipo Estado vinculado ao tipo Cidade, no qual, teríamos uma classe para representá-lo como no diagrama de classe abaixo:
  • 7. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 8 Na memória, agora temos um objeto do tipo Estado relacionado ao objeto do tipo Cidade. Criação Classe Estado Alteração da Classe Cidade public class Estado { private String nome; private String uf; //getters and setters } public class Cidade { private String nome; private Estado estado; //getters and setters } Agora nosso programa principal deve ser alterado para que possamos utilizar a propriedade UF em um objeto do tipo Estado e não mais diretamente na cidade como estava. Assim, já iremos corrigir o erro gerado: The method setUf(String) is undefined for the type Cidade, dizendo que não existe mais o método setUf(String) na cidade. Com uma instância de estado basta “setarmos” ele na cidade em sua nova propriedade de relacionamento estado. Para imprimir o estado da cidade do cliente, utilizamos a navegação por meio do método get. Primeiro acessamos o cliente, depois a cidade do cliente e por fim o estado da cidade conforme o código abaixo:
  • 8. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 9 1. public class ProgramaPrincipal { 2. 3. public static void main( String[] args ) { 4. //Construção do Objeto Estado 5. Estado ms = new Estado(); 6. ms.setNome("Mato Grosso do Sul"); 7. ms.setUf("MS"); 8. 9. //Construção do Objeto Cidade 10. Cidade cg = new Cidade(); 11. cg.setNome("Campo Grande"); 12. //Relacionamento com o objeto Estado 13. cg.setEstado(ms); 14. 15. Cliente jao = new Cliente(); 16. jao.setNome("Jão da Silva"); 17. jao.setCpf("999999999-99"); 18. //Relacionamento com objeto Cidade 19. jao.setCidade(cg); 20. 21. //Imprimindo dados da cidade do jao 22. System.out.println(jao.getCidade().getNome()+ " " + jao.getCidade().getEstado().getUf() + 23. " "+ jao.getCidade().getEstado().getNome()); 24. } 25. }
  • 9. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 10 5 HERANÇA - RELACIONAMENTO DE OBJETOS DO TIPO “É UM” Em muitos casos, podemos ter a necessidade de trabalhar com classes mais genéricas e classes mais específicas. Vamos pensar na seguinte situação: Uma empresa necessita de um sistema de cadastros que possa ter o cadastro de várias pessoas, tais como Clientes, Fornecedores e Funcionários. Estes três tipos de cadastros possuem campos em comum (mais genéricos) e campos específicos que fazem parte exclusivamente daquele cadastro. Nós ainda não estamos trabalhando com tela em Java neste ponto do estudo, mas fizemos um rascunho (protótipo) quando estávamos conversando com o cliente, levantando suas necessidades (levantamento de requisitos) e pudemos observar que o cliente deseja algo semelhante às telinhas ao lado. O que vemos em comum nestes cadastros solicitados por nosso cliente? Primeiramente, que todos os cadastros, podemos considerar, são de uma mesma família mais genérica de objetos que podemos chamar de Pessoa. Podemos ver que todos, por se tratarem de pessoa, possuem um campo (propriedade) nome e também cidade, independente se é Cliente, Fornecedor ou Funcionário. Entre os cadastros temos uma variação de campos, em que cada formulário, além dos campos em comum, possui campos específicos, como no caso do funcionário que possui praticamente os mesmos campos de cliente, exceto um novo campo chamado cargo. Nesta situação vamos trabalhar com um tipo de relacionamento chamado de Herança ou relacionamento “É um”. Neste tipo de relacionamento nós criamos classes que conterão propriedades e métodos mais genéricos. Essas classes servem de “superclasse” ou classe base, para que outras possam estender, ou seja, esta classe contém propriedades e métodos que podem ser herdados. As classes mais específicas ou classes filhas possuem a palavra reservada extends para especificar qual será sua classe base. Em outras palavras, as classes filhas que estendem as superclasses “esticam” a classe base por meio do extends.
  • 10. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 11 A classe base ou superclasse tem suas características e a classe filha herda suas características e também adiciona novas propriedades e métodos específicos dela. Na instância do objeto da classe filha podemos ver os métodos e propriedades que foram estendidos. Senão existisse herança, nós teríamos que criar vários campos ou propriedades repetidas em cada classe. Classes sem Herança – Tentativa 1 Desta forma, criamos uma classe individual para cada Cadastro sem herança e sem a reutilização de campos. public class Cliente{ private String nome; private String cpf; private String rg; private Cidade cidade; } public class Fornecedor{ private String nome; private String razaSocial; private String cnpj; private Cidade cidade; } Public class Funcionario{ private String nome; private String cpf; private String rg; private String cargo; private Cidade cidade; } Classes com Herança sendo 1 classe Genérica e 3 Específicas – Tentativa 2
  • 11. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 12 Desta forma, criamos uma classe Pessoa contendo os campos comuns para todos dos cadastros. Mas ainda parece que ficaram campos repetidos em Cliente e Funcionario. Não poderíamos colocar RG e CPF em Pessoa, senão comprometeríamos o Fornecedor que é Pessoa Jurídica. public class Pessoa { private String nome; private Cidade cidade; //getters e setters } public class Cliente extends Pessoa{ private String cpf; private String rg; } public class Fornecedor extends Pessoa { private String razaSocial; private String cnpj; } public class Funcionario extends Pessoa{ private String cpf; private String rg; private String cargo; } Classes com Herança com mais classes Genéricas e Específicas – Tentativa 3 Deste jeito, pensamos de forma mais genérica ainda, criando uma classe Pessoa e classes filhas Pessoa Física e Pessoa Jurídica. Agora as classes Cliente e Funcionário estendem da classe PessoaFisica e a classe Fornecedor estende da classe PessoaJuridica. Assim, até se precisarmos em outras partes do sistema futuramente representar clientes do tipo PessoaJuridica com este modelo teremos mais suporte para isso. Classe mais Genérica Classes Filhas mais Específicas, mas ainda são Genéricas para suas filhas
  • 12. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 13 public class Pessoa { private String nome; private Cidade cidade; //getters e setters } public class PessoaFisica extends Pessoa { private String cpf; private String rg; //getters e setters } public class PessoaJuridica extends Pessoa { private String cnpj; private String razaSocial; //getters e setters } Classes Filhas das Filhas ainda mais Específicas public class Cliente extends PessoaFisica{ //Todos campos comuns //Foram herdados } public class Fornecedor extends PessoaJuridica { //Todos campos comuns foram //herdados } public class Funcionario extends PessoaFisica { //Todos campos comuns //Foram herdados private String cargo; } Programa Principal Crie um programa principal para testar o acesso à propriedade nome a partir da instância de Cliente. public class ProgramaPrincipalCliente { public static void main(String[] args) { Cliente cli = new Cliente(); cli. ??? // O que será que vai aparecer depois do ponto? } } Observe a diferença entre o ponto de vista do objeto e da classe. Do ponto de Vista do Objeto Acessando os métodos Get e Set do ponto de vista do objeto, ou seja, da instância em um Programa Principal, por exemplo, a IDE deve mostrar os métodos herdados e acessíveis.
  • 13. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 14 Do ponto de Vista da Classe Se tentarmos acessar as propriedades privadas da classe base pela classe filha, acreditando que ela estará acessível, então nos deparamos com a situação de que isso não é possível. A Herança respeita os modificadores de acesso das propriedades, e isso só seria possível se nossa propriedade não fosse private e sim protected. Ao deixarmos uma propriedade protected estamos permitindo que a mesma seja acessível diretamente pelas classes filhas, livres de ter que acessar pelos métodos encapsuladores, como se a propriedade tivesse sido declara dentro da própria classe filha. A figura abaixo ilustra os métodos acessíveis pela classe Cliente. Vemos que possuem métodos getters e setters de Object, Pessoa e PessoaFisica. Tudo estende de java.lang.Object A classe java.lang.Object é a classe base padrão do Java, tudo estende de Object mesmo se não colocarmos o comando extends Object. Só podemos herdar uma classe por vez, não havendo herança múltipla como em outras linguagens, ou seja, cada classe filha só pode ter uma classe base e essa classe base também pode ter outra classe base e assim por diante até chegar no topo da hierarquia que é a classe Object.
  • 14. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 15 Protected do ponto de vista da classe Se colocarmos na propriedade nome da classe Pessoa o modificador protected, podemos acessá-lo diretamente pela classe filha. Faça a seguinte experiência, na classe Cliente, adicione um método calcularPontuacao para tentarmos acessar de dentro do método a propriedade nome da classe Pessoa. public class Pessoa { protected String nome; } public class Cliente extends PessoaFisica{ public void calculaPontuacao(){ } } Na IDE (Eclipse ou Netbeans) você já pode ver que isso é possível utilizando o recurso de auto complete (ctrl+ espaço) como na imagem abaixo.
  • 15. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 16 Assim, podemos acessar essa propriedade de forma direta para atribuirmos um valor ou para recuperarmos seu valor para impressão. Uma forma utilizada também é por meio do comando this ficando this.nome. Protected do ponto de vista da instância Podemos acessar da instância uma propriedade protected diretamente? Resposta: Vai depender dos pacotes. Se a classe que possui a instância de Cliente como o ProgramaPrincipal estiver no mesmo pacote que a classe Cliente então sim, a propriedade fica de livre acesso, podendo ser acessada diretamente como se ela fosse do modificador default. E as classes estiverem em pacotes diferentes então não é possível acessar a propriedade protected, precisando, assim, utilizar os métodos encapsuladores getters e setters. Instância em classe no mesmo pacote Instância em classe em pacote diferente Neste exemplo, podemos ver claramente a possibilidade de acesso da propriedade nome pela instância de cliente no programa principal. Para ficar fácil de entender pense que do ponto de vista da instância a regra é a mesma do modificador default. Mova a classe Pessoa que possui a propriedade protected para um pacote diferente, “temp”, por exemplo. package br.com.fabricadeprogramador .temp; //imports aqui public class Pessoa { protected String nome; //restante da classe aqui } Na instância tente acessar Veja que aparecem os métodos, mas não a propriedade nome.
  • 16. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 17 5.1 Instanciando Polimorficamente É possível declarar uma variável do tipo mais genérico apontando para um objeto de uma classe filha bem mais específico? Sim, a isso chamamos de atribuições polimórficas. Veja no exemplo abaixo. package br.com.fabricadeprogramador.sistemacadastro; import br.com.fabricadeprogramador.temp.Pessoa; public class ProgramaPrincipalPolimorfismo { public static void main(String[] args) { Object objeto = new Funcionario(); Pessoa pessoa = new Funcionario(); PessoaFisica pessoaFisica = new Funcionario(); Funcionario funcionario = new Funcionario(); } } Quando uma classe filha estende uma classe base, dizemos que um objeto da classe filha “é um (a)” do objeto classe base. Exemplo Podemos declarar variáveis de um tipo mais genérico para armazenar referências a objetos mais específicos. Uma variável do tipo Object pode apontar para um objeto do tipo Funcionario porque o mesmo passa no teste “é um”, ou seja, um funcionário “é um” Object, mesmo que não herda diretamente, mas no topo da hierarquia sabemos que tudo herda de Object. Uma variável do tipo Pessoa pode apontar para um objeto Funcionario porque funcionário “é uma” Pessoa. Uma variável do tipo PessoaFisica pode apontar para um objeto do tipo Funcionario porque funcionário “é uma” PessoaFisica. Uma variável do tipo Funcionario pode apontar para um objeto Funcionario porque funcionário “é um” Funcionario. A figura abaixo mostra que todos podem apontar para um Funcionário, porém, os que estão mais abaixo ou específicos podem ver mais detalhes do objeto, porque a variável de referência limita o acesso as propriedades e métodos do objeto de acordo com seu tipo. Um tipo Object embora aponte para um objeto Funcionario não pode ter acesso a tudo do funcionário, podendo acessar apenas o que corresponde ao tipo Object. Um objeto funcionário é constituído de várias partes, sendo a parte de Object, a parte de Pessoa, a parte de PessoaFisica e a parte de Funcionario. A soma destas heranças é o funcionário completo, mas quem pode ter acesso completo é apenas uma referência do tipo Funcionario. A variável do tipo Object é a mais limitada quanto ao acesso ao objeto Funcionário e a variável do tipo Funcionário é a mais completa.
  • 17. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 18 5.2 Fazendo Conversões (Casting) É possível fazermos conversões de tipos desde que os objetos sejam da mesma família. Em nosso exemplo anterior temos uma instância de funcionário sobre uma referência do tipo Object. O Objeto instanciado e do tipo Funcionário, mas a referência declarada foi do tipo Object, então essa variável de referência mesmo podendo acessar o objeto, está limitada pelo seu tipo declarado não podendo acessar tudo de um objeto Funcionario. Mas será possível a variável do tipo Object invocar o método setCargo(String)? Sim, se fizermos uma conversão ou casting. Fazer um casting na variável Object objeto para o tipo Funcionário é como “esticar” a capacidade dela para que ela possa acessar o objeto completo. O que estamos fazendo é tornando a visão de variável que é mais genérica em uma “lupa” para ver os detalhes de um objeto mais específico. Veja: “Setando” um cargo no funcionário fazendo casting ((Funcionario)objeto).setCargo("Motorista"); “Getando” o cargo do funcionário objeto.getCargo(); Se tentarmos acessar diretamente o método getCargo na variável que fizemos o casting, não teremos acesso e receberemos a seguinte mensagem: The method getCargo() is undefined for the type Object Isso porque o casting não altera o tipo original da variável mantendo como sendo do tipo Object. Para acessarmos o método getCargo temos que fazer novamente um casting da seguinte forma:
  • 18. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 19 ((Funcionario)objeto).getCargo(); Assim como podemos “esticar” a visibilidade também podemos “encolher”. Para um objeto do tipo Funcionário podemos fazer um casting para torná-lo de o tipo mais Genérico como: Funcionario funcionario = new Funcionario(); ((PessoaFisica) funcionario).setCpf("99009"); 5.3 Sistema de Cadastro de Pessoas Um exemplo de uso de atribuições polimórficas seria criarmos um sistema de cadastro Genérico, no qual podemos passar por parâmetro uma instância de qualquer objeto da família de Pessoa, ou seja, qualquer objeto de uma classe que estenda da classe Pessoa. No exemplo abaixo a variável genérica Pessoa recebe um objeto como parâmetro e o armazena em um vetor Genérico de Pessoa. public class SistemaCadastro { Pessoa pessoas[] = new Pessoa[3]; int numEntradas = 0; /** Entrada Generica * @param pessoa */ public void cadastrar (Pessoa pessoa){ if(numEntradas < pessoas.length){ pessoas[numEntradas] = pessoa; numEntradas++; } } } Agora na hora de imprimir teremos que utilizar a técnica de conversão para imprimir os dados específicos de um objeto Pessoa. Como nosso vetor de pessoas é genérico e armazena vários tipos de pessoas diferentes, como Cliente, Fornecedor e Funcionário então temos que utilizar o instanceof para verificar qual o tipo do objeto da referência para realizar a conversão e acessar as propriedades específicas. /** * Impressao de forma especifica */ public void imprimir (){ for (int i = 0; i < pessoas.length; i++) { System.out.println(pessoas[i].getNome()+ "");
  • 19. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 20 //Funcionario if(pessoas[i] instanceof Funcionario){ //casting Funcionario func = (Funcionario) pessoas[i] ; System.out.print(func.getSalario() + " " + func.getCargo()); } //Faça para Cliente //Faça para Fornecedor } } Convertendo de String para Inteiro Quando os objetos não são da mesma família hierárquica não podemos utilizar a mesma técnica de casting. É possível fazermos uma conversão de uma String para número inteiro então? Da seguinte forma, não. String numeroStr = "10"; Integer n = (Integer)numeroStr; A solução para este caso é a chamada a um o método static de conversão parseInt da classe Integer ou chamada de um construtor especial que suporta uma entrada String. String numeroStr = "10"; Integer n1 = Integer.parseInt(numeroStr); Integer n2 = new Integer(numeroStr); 6 MÉTODOS E PROPRIEDADES ESTÁTICAS Um método estático é um método que não está ligado a instância do objeto. Para invocar um método estático basta colocarmos o nome da classe, um ponto e nome do método como: Integer.parseInt("10"); Uma propriedade estática é uma propriedade da classe e não do objeto. Isso quer dizer que o valor dela não pode ser diferente para cada instância. Para toda instância de Integer a propriedade MAX_VALUE sempre terá o mesmo valor. Integer maximoInt = Integer.MAX_VALUE;
  • 20. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 21 As propriedades estáticas não servem para manter o ”estado” do objeto. Entende-se por estado do objeto os valores atribuídos em suas propriedades para uma determinada instância. No exemplo abaixo os objetos estão com estados diferentes porque suas propriedades não são estáticas e os dados atribuídos são diferentes. Funcionario jao = new Funcionario(); jao.setNome("Jão da Silva"); jao.setCargo("Cientista da Computação"); Funcionario maria = new Funcionario(); maria.setNome("Maria da Silva"); maria.setCargo("Analista de Sistemas"); Em nosso caso, será comum utilizarmos métodos estáticos em nossa aplicação para criarmos classes com métodos utilitários. Exemplo public class ValidacaoUtil { public static void validarCpf(String cpf) { //implementação aqui } public static void validarCnpj(String cnpj) { //implementação aqui } public static void validarEmail(String email) { //implementação aqui } } A invocação dos métodos estáticos não necessita de instância. public static void main(String[] args) { ValidacaoUtil.validarCnpj("10.797.626/0001-88"); ValidacaoUtil.validarCpf("905.044.567-92"); ValidacaoUtil.validarEmail("contato@htcursos.com"); } O main é estático! O método principal public static void main(String[] args) é estático, por se tratar de um método principal não sendo necessário a JVM instanciar um objeto do nosso programa principal para invoca-lo. Um método estático somente pode alterar valores de variáveis também estáticas. O código abaixo não pode irá funcionar por que a propriedade não é estática e está tentando ser acessar por um método estático.
  • 21. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 22 public class ValidacaoUtil { String cpf; //propriedade não estática public static void validarCpf(String cpf) { //Cannot make a static reference to the non-static field numero this.cpf =cpf; } } Ao utilizarmos métodos estáticos, também não utilizamos a palavra reservada this, porque ela quer dizer “esta instância atual” e com os métodos estáticos não estamos trabalhando com a instância. Certo? O código abaixo pode ser feito. public class ValidacaoUtil { static String cpfEstatico; // propriedade estática public static void validarCpf(String cpf) { cpfEstatico = cpf; } } 7 SOBRECARGA E SOBRESCRITA DE MÉTODOS Em Java vimos que a classe mais genérica é a java.lang.Object. A classe Object do java possui vários métodos implementados, abaixo vamos listar dois deles: toString( ) e equals( Object obj). public String toString() {} Retorna uma String representando uma versão texto do objeto. Ao tentarmos imprimir uma variável de instancia do objeto o método toString é invocado automaticamente. Por padrão o método retorna uma String com uma referência ao objeto como: br.com.fabricadeprogramador.sist emacadastro.Cliente@13d9c02 Exemplo de chamada: Cliente cli = new Cliente(); System.out.println(cli); System.out.println(cli.toString()); public boolean equals(Object obj) {} Este método verifica se o objeto atual é igual ao outro passado no parâmetro.
  • 22. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 23 Exemplo de chamada: 1. Cliente cli1 = new Cliente(); 2. cli1.setNome("jão"); 3. 4. Cliente cli2 = new Cliente(); 5. cli2.setNome("jão"); 6. 7. boolean iguais = cli2.equals(cli1); 8. System.out.println(iguais); Seu critério de igualdade é a referência, ou seja, somente se os objetos estiverem na mesma posição de memória, então, serão considerados iguais. No exemplo ao lado temos 2 clientes com o mesmo nome, porém em objetos diferentes, ou seja, em posições diferentes de memória, logo o retorno será false na comparação da linha 7. Os métodos da classe base Object que acabamos de estudar já possuem uma implementação padrão. Mas seria possível modificarmos essa implementação? E se quisermos considerar que duas instâncias diferentes de objetos do tipo Cliente com o mesmo CPF sejam considerados clientes iguais, mesmo que estão em posições de memória diferentes? Neste caso nós temos que modificar o método equals da classe Object, porém se fosse possível fazer isso diretamente na classe Object nós comprometeríamos todos os objetos do sistema porque todos herdam de Object. Então será possível modificarmos somente o método toString da classe Cliente para fazer essa adaptação para nossa necessidade específica? Sim, é possível, isso é conhecido como sobrescrita de método, ou seja, escrever uma “por cima” ou sobre do método herdado da classe base na classe filha. 7.1 Sobrescrevendo o Método toString() public class Cliente extends PessoaFisica{ public String toString() { return getNome() + " "+ getCpf(); } //demais métodos } Desta forma agora ao executarmos o código abaixo a saída será o nome e o CPF concatenados do objeto Cliente. Cliente cli1 = new Cliente(); cli1.setNome("jão"); cli1.setCpf("999.999.999-99"); System.out.println(cli);
  • 23. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 24 7.2 Sobrescrevendo o Método equals(Object obj) Queremos que o critério de comparação seja o CPF e o RG do cliente, ou seja, se dois clientes com mesmo CPF e RG são comparados pelo método equals então o retorno deve ser true. public class Cliente extends PessoaFisica{ public boolean equals(Object obj) { //Se os objetos estiverem na mesma posição de memória if (this == obj) return true; //Convertendo (casting) o tipo Object para o tipo PessoaFisica PessoaFisica outro = (PessoaFisica) obj; //se não forem iguais retorna falso if(!cpf.equals(outro.cpf)) return false; //se não forem iguais retorna falso if(!rg.equals(outro.rg)) return false; //se não passou return true; } public String toString() return getNome() + " "+ getCpf(); } } 7.3 Utilizando a IDE para Gerar o Método Equals e Hashcode Melhorando o método hashcode e equals de Cliente utilizando a ferramenta da IDE eclipse ou Netbeans. No eclipse o acesso é pelo menu source / generator hashcode and equals. public boolean equals(Object obj){ if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; PessoaFisica other = (PessoaFisica)obj;
  • 24. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 25 if (cpf == null) { if (other.cpf != null) return false; } else if (!cpf.equals(other.cpf)) return false; if (rg == null) { if (other.rg != null) return false; } else if (!rg.equals(other.rg)) return false; return true; } 7.4 HashCode Muito usado nas estruturas de dados que iremos ver mais a frente, mas, por esse momento, precisamos entender que este é um número que representa um objeto toda vez que os valores de suas propriedades estipuladas no método estiverem iguais, o mesmo hashcode deve ser gerado, neste exemplo quando uma pessoa possuir o mesmo RG e o mesmo CPF um código de hashcode será gerado idêntico porque o método utiliza dos dados destas propriedades para dar origem ao número de hashcode. Em estrutura de armazenamento HashMap e HashSet iremos ver isso na prática. public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((cpf == null) ? 0 : cpf.hashCode()); result = prime * result + ((rg == null) ? 0 : rg.hashCode()); return result; } 7.5 A Palavra Reservada This A palavra reservada this sempre será usada dentro da classe para fazer referência à instância atual. No exemplo anterior no trecho de código abaixo podemos ler: “se a referência da instância atual (this) for igual a referência à instância obj então return true”. if (this == obj) return true;
  • 25. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 26 8 CONSTRUTORES Os construtores são como um método chamado somente no momento de construirmos um objeto. Um objeto é construído quando é alocado na memória. Não iremos tratá-lo como método por não acessarmos pela variável de referência por meio do operador de acesso ponto. Mas tem uma sintaxe parecida com a de um método, exceto por não possuir tipo de retorno. O construtor sempre leva o nome da Classe. O construtor é chamado por meio do operador new. Exemplo: new Cliente(); Construtor Padrão Este é o construtor sem parâmetros de entrada. Todo construtor ao ser chamado executa primeiro o construtor da classe base. O objeto vai sendo construído de cima para baixo, ou seja, primeiro o construtor da classe Object é executado e depois o construtor das classes filhas na ordem da herança. A chamada super() invoca o construtor da classe base. Mesmo se não escrevermos um construtor padrão na classe, o compilador irá escrever no bytecode gerado, mesmo que não apareça em nosso código fonte, exceto quando nós escrevermos algum construtor sobrecarregado, que veremos logo a frente. public class Pessoa { protected String nome; private Cidade cidade; public Pessoa() { super(); } } Chamada ao construtor padrão de Pessoa Pessoa pessoa = new Pessoa(); 8.1 Construtor Sobrecarregado É um construtor que possui parâmetros de entrada, ou seja, uma nova versão de um construtor. Podemos criar várias versões de construtores, em que cada versão suporta tipos diferentes de entradas como parâmetros. No exemplo abaixo temos o construtor padrão e um construtor sobrecarregado que suporta uma String e uma Cidade como entrada, sendo o primeiro para iniciar o objeto com um valor “setado” nas propriedades nome e cidade de Pessoa. Sobrecarregando o construtor de Pessoa
  • 26. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 27 public class Pessoa { protected String nome; private Cidade cidade; public Pessoa() { super(); } public Pessoa(String nome, Cidade cidade) { super(); this.nome = nome; this.cidade = cidade; } } Exemplo de chamada new Pessoa("Jão", new Cidade()); Se ao instanciarmos um objeto da classe Cliente já quisermos informar o seu nome? Temos que criar um construtor sobrecarregado na classe Cliente. public class Cliente extends PessoaFisica{ public Cliente() { super(); } public Cliente(String nome) { //Método Herdado setNome(nome); } } Agora já podemos fazer a chamada ao construtor sobrecarregado da forma abaixo. new Cliente("Jão");
  • 27. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 28 8.2 Sobrecarregando o Construtor de Cidade public class Cidade { private String nome; private Estado estado; public Cidade() { super(); } public Cidade(String nome) { super(); this.nome = nome; } public Cidade(String nome, Estado estado) { super(); this.nome = nome; this.estado = estado; } } Agora com o construtor sobrecarregado podemos, no momento da construção do objeto Pessoa, já passarmos dois objetos como parâmetro de entrada, sendo uma instância de String e uma instância de Cidade. Pessoa pessoa = new Pessoa("Jão", new Cidade(“Campo Grande”)); 8.3 Lembrando dos Estáticos Agora como já conhecemos o uso dos construtores vamos utilizá-lo combinando com uma propriedade estática para armazenar a quantidade de clientes que já foram instanciados. public class Cliente extends PessoaFisica{ private static int quantidadeCliente=0; public Cliente() { quantidadeCliente++; } public static int getQuantidadeCliente() { return quantidadeCliente; } }
  • 28. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 29 Imprimindo o número de instâncias de Objetos cliente package br.com.fabricadeprogramador.sistemacadastro.construtores; import br.com.fabricadeprogramador.sistemacadastro.Cliente; public class ProgramaPrincipalClientes { public static void main(String[] args) { new Cliente(); new Cliente(); new Cliente(); System.out.println(Cliente.getQuantidadeCliente()); } } 9 SOBRECARGA DE CONSTRUTORES Exemplos de uso de construtores sobrecarregados nos tipos básicos do Java. Construtores sobrecarregado do tipo java.lang.Integer //Construtor sobrecarregado parâmetro String Integer numero1 = new Integer("10"); //Construtor sobrecarregado parâmetro int Integer numero2 = new Integer(10); Alguns construtores Sobrecarregados do java.lang.String String texto1 = new String(); String texto2 = new String(new byte[3]); String texto3 = new String(new char[3]); String texto4 = new String("Fábrica de Programador"); String texto5 = new String(new StringBuffer()); 10 MÉTODOS SOBRECARREGADOS Assim como sobrecarregamos os construtores também sobrecarregamos os métodos. Ao sobrecarregarmos os métodos temos que tomar o cuidado para sempre deixar o modificador de acesso com o mesmo nível ou mais alto. Um método private não pode ser sobrescrito. Se o método for default, o mesmo pode ser sobrescrito por default ou por public. Se o método for public não pode ser sobrescrito por default. public class ValidacaoUtil { static String cpfEstatico; // propriedade não estática
  • 29. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 30 public static void validarCpf(String cpf) { //valida CPF com os pontos (mascara) } public static void validarCpf(Integer cpf){ //valida CPF sem os pontos (mascara) } } 11 CLASSES ABSTRATAS Classes abstratas são classes que possuem métodos abstratos, ou seja, apenas a declaração do método sem sua implementação. Quando uma classe possui um método abstrato então a classe vira abstrata. Uma classe abstrata não pode ser instanciada, por que possuem métodos sem implementação. Declaramos um método abstrato quando não queremos uma implementação genérica padrão. Desta forma as classes filhas são obrigadas a implementar o método abstrato. Dizemos que as classes filhas assinam um contrato onde elas concordam em implementar os métodos abstratos da classe base abstrata. No exemplo abaixo vamos mostrar um caso, no qual definimos que uma classe que estende de Funcionário deve possuir uma implementação específica para o método calculoSalario. Assim a classe filha Analista e Diretor devem implementar o método abstrato conforme seu tipo específico. public abstract class Funcionario extends PessoaFisica { private String cargo; public String getCargo() { return cargo; } public void setCargo(String cargo) { this.cargo = cargo; } public abstract double calculoSalario(); } Agora a classe que estende funcionário deve implementar o método abstrato da classe base. Um Analista que é um Funcionário que tem seu cálculo de salário diferente de um diretor com 5% a mais de diferença do salário base. public class Analista extends Funcionario{ public double calculoSalario() { return getSalario() + (getSalario()*5/100); } }
  • 30. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 31 Um Diretor é um Funcionário e logo deve implementar o método abstrato da classe base com 10% a mais de diferença do salário base. public class Diretor extends Funcionario { public double calculoSalario() { return getSalario() + (getSalario()* 10/100); } } 12 INTERFACES As interfaces nos permitem definir apenas o padrão de funcionamento ou comportamento dos objetos. Ela é uma classe 100% abstrata não tendo propriedades e nem métodos concretos (não abstratos). Usamos interfaces quando queremos trabalhar de forma mais genéricas na família dos objetos sem entrar nos detalhes da implementação. Como analogia podemos pensar nos componentes de um carro do mundo real. Eles são todos baseados em interfaces. A interface Roda do carro diz que a rodas são de 4 furos e seu tamanho é 15. Existem vários modelos de rodas para esse carro. A interface é o modelo de encaixe que define o padrão e a roda propriamente dita é a implementação da interface. Podemos trocar de roda quando quisermos desde que obedeça esse padrão estabelecido pela interface Roda. Assim é para todos os componentes do carro, podemos trocar de som, trocar de volante, de rodas e de peças porque o modelo dos componentes foi padronizado em interfaces. Isso garante que podemos trocar de fabricante de pneus, de sons e etc. Em nosso sistema vamos criar um Interface que irá padronizar um Pedido de um sistema de pedidos. Nesta interface iremos apenas definir ou declarar os métodos que o sistema de pedidos deve possuir. Com o código abaixo iremos construir a Interface Pedido, ou seja, o padrão que uma implementação de Pedido deve assumir. public interface Pedido { public Integer getCodigo() public Double calcularValorTotal() public void adicionarItem(ItemPedido itemPedido); public void removerItemPedido(ItemPedido itemPedido); public void imprimirItens(); public ItemPedido[] ordenarItensPedidos(); public ItemPedido[] getItensPedidos(); } Um pedido será constituído de vários itens que iremos chamar de ItemPedido. Vários objetos podem ser considerados como Itens a serem pedidos em sistema comercial. Por exemplo, em uma escola podemos ter objetos Livros e Cursos que podem compor um Pedido que é uma compra. Em uma pizzaria podemos ter Pizza, Refrigerante, Sucos como sendo itens do Pedido e assim por diante. Na maioria das vezes neste caso uma classe Produto poderia ser utilizada para representar os itens de um Pizzaria de forma mais genérica.
  • 31. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 32 Vamos criar uma Interface para definir a representação de um Item de um Pedido. public interface ItemPedido { //utilizado para garantir uma ordenação public Integer getCodigo() ; public void setCodigo(Integer codigo); public Double getValor() ; public void setValor(Double valor); public String getDescricao() ; public void setDescricao(String descricao); } Com esta interface nós garantimos alguns métodos para cada ItemPedido. 12.1 Implementando as Interfaces Vamos agora fazer a implementação da interface ItemPedido. Esta interface faz com que um objeto possa possuir o comportamento padrão de um itemPedido. Um exemplo de item que pode compor um pedido é um Curso. Então façamos a classe Curso implementar a Interface ItemPedido por meio da palavra reservada implements. public class Curso implements ItemPedido { // propriedade para os métodos definidos na interface private Integer codigo; private Double valor; private String descricao; // Propriedade especificas private String conteudo; private String publicoAlvo; private String cargaHoraria; public Integer getCodigo() { return codigo; } public void setCodigo(Integer codigo) { this.codigo = codigo; }
  • 32. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 33 public Double getValor() { return valor; } public void setValor(Double valor) { this.valor = valor; } public String getDescricao() { return descricao; } public void setDescricao(String descricao) { this.descricao = descricao; } //Outros métodos aqui } Um outro exemplo de um ItemPedido pode ser um Livro. import java.util.Date; public class Livro implements ItemPedido { //propriedade para os métodos definidos na interface private Integer codigo; private Double valor; private String descricao; // Propriedade especificas private String autor; private String editora; private Date dataPublicacao; public Integer getCodigo() { return codigo; } public void setCodigo(Integer codigo) { this.codigo = codigo; }
  • 33. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 34 public Double getValor() { return valor; } public void setValor(Double valor) { this.valor = valor; } public String getDescricao() { return descricao; } public void setDescricao(String descricao) { this.descricao = descricao; } //Outros métodos aqui } Agora vamos implementar o Pedido utilizando uma classe PedidoImpl, em que o sufixo Impl é apenas uma abreviação de Implementação como convenção. A classe que implementa a interface decide como trabalhar os métodos. public class PedidoImpl implements Pedido { private Integer codigo; private Date data; private Cliente cliente; private ItemPedido itens[]; public Integer getCodigo() { // Implementação aqui } public Double calcularValorTotal() { // Implementação aqui } public void adicionarItem(ItemPedido itemPedido) { // Implementação aqui } public void removerItemPedido(ItemPedido itemPedido) { // Implementação aqui } public void imprimirItens() { // Implementação aqui } public ItemPedido[] ordenarItensPedidos() { // Implementação aqui } public ItemPedido[] getItensPedidos() { // Implementação aqui }
  • 34. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 35 // Outros métodos aqui } Programa Principal de exemplo para construção de um Pedido public class ProgramaPrincipalPedido { public static void main(String[] args) { Pedido pedido = new PedidoImpl(); int codigoItem = 1; ItemPedido livro = new Livro(); livro.setCodigo(codigoItem); livro.setValor(120.50); livro.setDescricao("Livro de Java"); ItemPedido curso1 = new Curso(); curso1.setCodigo(++codigoItem); curso1.setDescricao("Desenvolvimento para Android"); ItemPedido curso2 = new Curso(); curso2.setCodigo(++codigoItem); curso2.setDescricao("Fábrica de Programador"); pedido.adicionarItem(livro); pedido.adicionarItem(curso1); pedido.adicionarItem(curso2); pedido.imprimirItens(); double total = pedido.calcularValorTotal(); System.out.println(total); pedido.removerItemPedido(curso1); double novoTotal = pedido.calcularValorTotal(); System.out.println(novoTotal); pedido.ordenarItensPedidos(); pedido.imprimirItens(); } } Anônimos - Um gerenciador de Registros Genérico Uma classe anônima pode ser construída a partir de uma instância de um objeto que é construído de forma oculta ao tentarmos iniciar uma Interface. Podemos alterar o
  • 35. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 36 ProgramaPrincipalPedido para incluir um objeto que não possui uma classe, porém ele implementa a interface ItemPedido. Um objeto anônimo com referência. ItemPedido curso2 = new Curso(); curso2.setCodigo(++codigoItem); curso2.setDescricao("Fábrica de Programador"); //Construção de um objeto anonimo do tipo ItemPedido ItemPedido itemAnonimo = new ItemPedido() { public void setValor(Double valor) { //Implementação do anonimo aqui } public void setDescricao(String descricao) { //Implementação do anonimo aqui } public void setCodigo(Integer codigo) { //Implementação do anonimo aqui } public Double getValor() { //Implementação do anonimo aqui return null; } public String getDescricao() { //Implementação do anonimo aqui return null; } public Integer getCodigo() { //Implementação do anonimo aqui return null; } }; pedido.adicionarItem(livro); pedido.adicionarItem(curso1); pedido.adicionarItem(curso2); pedido.adicionarItem(itemAnonimo); Construindo a instância de um objeto anônimo e já passando como parâmetro no método sem referência pedido.adicionarItem(new ItemPedido() { public void setValor(Double valor) { //Implementação do anonimo aqui }
  • 36. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 37 public void setDescricao(String descricao) { //Implementação do anonimo aqui } public void setCodigo(Integer codigo) { //Implementação do anonimo aqui } public Double getValor() { //Implementação do anonimo aqui return null; } public String getDescricao() { //Implementação do anonimo aqui return null; } public Integer getCodigo() { //Implementação do anonimo aqui return null; } }); 13 GENÉRICOS - UM GERENCIADOR DE REGISTROS GENÉRICO A interface genérica Gerenciador Registro padroniza o comportamento de um objeto que tem a função de gerenciar registros. Essa interface garante que se o objeto terá um a função de gerenciar registro em um arquivo de texto, um vetor ou até mesmo em um banco de dados, ele deverá realizar no mínimo os métodos que estão declarados nela. public interface GerenciadorRegistro<T> { public void salvar(T obj); public void excluir(T obj); public void pesquisar(T obj); public void imprimirTodos(); } Conforme falamos, este gerenciador define as operações básicas de um gerenciador de registros onde podemos utilizar esta interface para construir um Gerenciador de registro de Pedido, de Clientes, Cidades, Estados e etc. O tipo parametrizado <T> quer dizer que o tipo do objeto que o método deverá suportar com parâmetro de entrada e de retorno vai ser definido pela classe que implementar a interface. Uma classe pode dizer que <T> é Cidade por exemplo desde modo: GerenciadorRegistro<Cidade>, ou dizer que é Estado, GerenciadorRegistro<Estado>, ou Pedido como: GerenciadorRegistro<Pedido>. O que precisamos entender é que o <T> é que faz a classe ficar genérica. Exemplo de implementação para um Gerenciador de Registros (GR) de Cidades
  • 37. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 38 public class GRCidade implements GerenciadorRegistro<Cidade> { public void salvar(Cidade obj) { // Implementação aqui } public void excluir(Cidade obj) { // Implementação aqui } public void pesquisar(Cidade obj) { // Implementação aqui } public void imprimirTodos() { // Implementação aqui } } No exemplo acima o GRCidade que define qual será a estrutura de armazenamento e independente disso deve possuir os métodos da interface implementados para garantir seu funcionamento como Gerenciador de Registros. 14 TRABALHANDO COM COLEÇÕES Estrutura da API do java para tratar coleções de objetos.
  • 38. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 39 14.1 List Uma lista dinâmica de objetos organizada em vetor e acessível por meio de índices que aceita objetos duplicados. Na API () padrão do Java iremos utilizar várias classes que utilizam tipos genéricos como uma lista de objetos da Interface List<E>. java.util.List<E> é uma interface que possui uma implementação padrão em java java.util.ArrayList<E>. Esta interface define o comportamento padrão de uma Lista Dinâmica. Um ArrayList nos permite armazenar objetos em um Array Dinâmico de objetos, ou seja, a alocação do objeto na posição do vetor é dinâmica na qual o ArrayList que controla o número de posições. No exemplo abaixo podemos ver que da interface java.util.List estende outra Interface chamada Collection. Isso quer dizer que a classe que implementar List<E> deverá também implementar os métodos herdados de Collection. public interface List<E> extends Collection<E> { int size(); boolean isEmpty(); boolean add(E e); //Outros métodos declarados aqui } 14.2 Exemplo de Uso da Interface List com ArrayList Um ArrayList é uma lista, portanto podemos fazer a atribuição polimórfica declarando uma variável do tipo da Interface apontando para uma instância de ArrayList. public class ProgramaPrincipalArrayList { public static void main(String[] args) { List<Cliente> clientes = new ArrayList<Cliente>(); clientes.add(new Cliente()); Cliente clienteAcessado = clientes.get(0); Cliente clienteRemovido = clientes.remove(0); } } Adicionando mais objetos na lista clientes.add(new Cliente("Jão")); clientes.add(new Cliente("Maria")); clientes.add(new Cliente("Maria")); clientes.add(new Cliente("José")); Iterando sobre o Set por meio do índice
  • 39. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 40 for (int i = 0; i < clientes.size(); i++) { Cliente cliente = clientes.get(i); System.out.println(cliente.getNome()); } Iterando sobre o Set por meio do objeto Iterator for (Iterator iterator = clientes.iterator(); iterator.hasNext();) { Cliente cliente = (Cliente) iterator.next(); System.out.println(cliente.getNome()); } Iterando sobre o Set por meio do For Each for (Cliente cliente : clientes) { System.out.println(cliente.getNome()); } 14.3 Set Não permite registros duplicados. Utilize os métodos equals e hashcode para definir o critério de igualdade. Sua organização não permite acesso por índice. Adicionando no conjunto //Atribuindo os nomes em um conjunto Set<String> nomes = new HashSet<String>(); nomes.add("Maria"); nomes.add("José"); nomes.add("Maria"); Verificando se um objeto está no conjunto //verificando se contam um objetos no conjunto boolean contem = nomes.contains("Maria") ; System.out.println("Contem Maria? " + contem ); Removendo do conjunto //removendo objeto do conjunto nomes.remove("Maria"); Iterando sobre o Set por meio do For Each for (String nome : nomes) { System.out.println(nome); }
  • 40. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 41 Iterando sobre o Set por meio do objeto Iterator Iterator<String> iterador = nomes.iterator(); while (iterador.hasNext()) { String nome = (String) iterador.next(); System.out.println(nome); } 14.4 Map Armazena os elementos na forma de pares chaves/valor. As chaves são exclusivas não podendo ser duplicadas. Os acessos aos objetos são feitos pela chave que são únicas. public class ProgramaPrincipalMap { public static void main(String[] args) { Map<String, String> linguagensProgramacao = new HashMap<String,String>(); linguagensProgramacao.put("Java", "Web, Móvel e Desktop"); linguagensProgramacao.put("PHP", "Web"); linguagensProgramacao.put("Java Script", "Web Navegador de Internet"); } } Removendo do Map por meio da chave linguagensProgramacao.remove("PHP"); Imprimindo por meio da chave //Imprimindo por meio de chave System.out.println(linguagensProgramacao.get("Java")); Imprimindo por meio de um conjunto de chaves //Imprimindo por meio de um Set de Chaves Set<String> keys = linguagensProgramacao.keySet(); for (String k : keys) { System.out.println(linguagensProgramacao.get(k)); } 15 EXCEPTIONS Quando executamos um método ou um construtor algo perigoso pode acontecer. Uma exceção é um objeto java contendo informação de um erro ocorrido em tempo de execução. Ao tentarmos realizar um cálculo aritmético por exemplo 10/0. O que acontece? Uma exceção. Um objeto de exceção é instanciado automaticamente pela JVM e enviado para nosso método. Existem exceções que a JVM lança automaticamente e outras que são lançadas
  • 41. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 42 programaticamente, ou seja, um método via programação a instância um objeto de exceção e lança. Vamos entender um pouco mais: Na API do Java temos uma família que forma uma hierarquia de classes com Exceções nativas. Na figura acima temos um exemplo de como essa é a estrutura dessa herança. A classe mais genérica que corresponde a família das Exceptions é Throwable. Logo, temos a Exception e RuntimeException. Podemos classificá-las em dois grupos: 1. Grupo das filhas diretamente de Exception (Checked) 2. Grupo das filhas de RuntimeException (Uncheck) 15.1 Lançando uma Exception Unchecked (Não verificadas) Este tipo de exceção ocorre por alguma falha na lógica de programação. Como exemplo, pense em um vetor que possui apenas três posições e o código tenta acessar uma posição que não existe. O Compilador não verifica esse tipo de situação e quando rodarmos o programa em tempo de execução uma exceção será lançada. Uma exceção é um objeto derivado ou herdado da classe java.lang.Exception. Este objeto contém várias informações sobre o erro ocorrido. No caso abaixo será lançada uma exceção na linha 7 ao tentar atribuir um valor na posição 3 do vetor que não existe pois o mesmo tem apenas 3 posições sendo 0, 1 e 2. 1. public class ProgramaPrincipalException { 2. public static void main(String[] args) {
  • 42. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 43 3. int [] vetor = new int[3]; 4. vetor[0]=10; 5. vetor[1]=20; 6. vetor[2]=30; 7. vetor[3]=40; 8. } 9. } 10. A Exception lançará uma mensagem como: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3 at br.com.fabricadeprogramador.sistemacadastro.sobrescrita.ProgramaPrincipalE xception.main(ProgramaPrincipalException.java:7) java.lang.ArrayIndexOutOfBoundsException: 3 15.2 Lançando uma Exception Checked (Verificadas) Uma exceção Verificada é uma classe que estende diretamente da classe base java.lang.Exception, logo este método não é da família de RuntimeException. Criando uma classe CPFInvalidException derivada de java.lang.Exception. Essa classe será utilizada para lançar um objeto Exception contendo informação sobre um CPF Inválido. Iremos utilizar esse um objeto dessa classe em um método de validação de CPF. public class CPFInvalidException extends Exception { //Construtor padrão public CPFInvalidException() { //passando para o construtor sobrecarregado da classe base uma mensagem //padrão super("CPF inválido!"); } } Em nossa classe ValidacaoUtil vamos implementar uma simples validação que verifica se o CPF informado no parâmetro é válido ou não. Consideramos que para ser válido o CPF o mesmo deve conter 11 dígitos e se isso não for verdade então um objeto da classe CPFInvalidException será instanciado (new) e lançado (throws). Para isso ser possível devemos declarar na assinatura do método que ele poderá fazer o lançamento throws CPFInvalidException.
  • 43. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 44 //Na assinatura do método temos que declarar um possível lançamento de Exception do tipo CPFInvalidException public static void validarCpf(String cpf) throws CPFInvalidException { if(cpf.length()!=11){ //Instânciando e lançando uma Exception throw new CPFInvalidException(); } } Uma verificação consiste em tratar a Exception. Temos basicamente duas formas de tratar a Exception, sendo uma delas usando o try – catch, no qual nós “pegamos” o objeto da exceção lançada e outra através de uma redeclaração throws onde dizermos que não queremos “pegar” o objeto Exception lançado. Agora vamos programar no programa principal uma chamada ao método validarCpf que deve ser verificado. É agora que acontece a verificação, quando formos invocar o método que diz que pode lançar uma Exception. Ao tentar invocar o método sem fazer a verificação o compilador avisa. public class ProgramaPrincipalException2 { public static void main(String[] args) { ValidacaoUtil.validarCpf("905.098.531-90"); } } Uma mensagem do compilador diz que a exceção deve ser manipulada: Unhandled exception type CPFInvalidException Forma 1 public class ProgramaPrincipalException2 { public static void main(String[] args) { try { ValidacaoUtil.validarCpf("905.098.531-90"); } catch (CPFInvalidException e) { //Tratamento da Exception e.printStackTrace(); } } } Uma forma de fazer o tratamento é “pegar” o objeto por meio da estrutura try-cath. O try tenta executar o método e se a exceção for lançada pelo método validarCpf então o catch recebe como parâmetro o objeto o CPFInvalidException que foi lançado. A variável (CPFInvalidException e) é um parâmetro do bloco cath funcionando como uma referência ao objeto CPFInvalidException lançada. Forma 2 public class ProgramaPrincipalException2 { public static void main(String[] args) throws CPFInvalidException { ValidacaoUtil.validarCpf("905.098.531-90"); } Uma outra forma é redeclarar na assinatura do método main que possui uma chamada ao método validarCpf informando que o método não vai “pegar” a exceção.
  • 44. Projeto Fábrica de Programador – Módulo 2 www.fabricadeprogramador.com.br Página: 45 } throws CPFInvalidException Parabéns pela conclusão de mais uma fase do projeto Fábrica de Programador! No próximo módulo iremos aprender a fazer aplicações mais interessantes, voltadas para Web.