Baixe o app para aproveitar ainda mais
Prévia do material em texto
Programação Orientada a Objetos Parte I – Conceitos Básicos: Classes, Objetos, Encapsulamento, Construtores, Atributos/Métodos Estáticos, Finalizadores, Pacotes. Prof. Cristiano Leite de Castro DCC-UFLA/2010 2 Programação Orientada por Objetos (POO) • Programação Tradicional: – Na programação convencional (procedimental ou estruturada), orientada a rotinas em uma linguagem como C, por exemplo, o problema é visualizado como uma seqüência de coisas a serem feitas. Os itens de dados relacionados são organizados em estruturas C (structs) e as funções necessárias (rotinas) são escritas para manipular os dados. • Programação Orientada por Objetos: – A Programação Orientada a Objetos (POO) toma a vantagem da modularidade dos objetos para implementar um programa em unidades relativamente independentes que são mais fáceis de manter e de estender. 3 Programação Orientada por Objetos (POO) • Programação Orientada por Objetos: – POO é apenas um método para projetar e implementar software. As técnicas usadas não acrescentam nada ao produto final visto pelo usuário. Entretanto, essas técnicas oferecem vantagens significativas para gerenciar problemas complexos, especialmente em grandes projetos. 4 Programação Procedimental vs. POO Dados Globais Função Função Função Função Dados Método Método Dados Método Método Dados Método Método Procedimental POO 5 Objeto • Um objeto representa uma entidade física ou uma entidade conceitual ou uma entidade de software. (definição informal) • Um objeto é um conceito, abstração, ou algo com fronteiras bem definidas e significado para uma aplicação. • Um Objeto é algo que possui: – Estado • armazena informação sobre o objeto. – Comportamento • define as mensagens aceitas pelo objeto. – Identidade • identifica unicamente o objeto. 6 Classe • Uma classe é a descrição de um grupo de objetos com propriedades similares (atributos), comportamento comum (operações), relacionamentos comuns com outros objetos e semânticas idênticas. – Um objeto é uma instância de uma classe. • Exemplo: Classe Atributos Operações Pedido Número Adiciona item Data Cancela Vendedor Confirma venda 7 Classes e Objetos • Uma classe é uma definição abstrata de um objeto. – Define a estrutura (propriedades) e o comportamento de qualquer objeto da classe. – Serve como um padrão para criação de objetos. • Os objetos podem ser agrupados em classes. Objetos Classe José Silva Maria Helena João Barros Funcionário 8 Representação de Classes • Um classe possui atributos e operações (métodos). • Em UML, uma classe é representada utilizando-se um retângulo dividido em três seções: – A primeira seção contém o nome da classe. – A segunda seção mostra a estrutura (atributos). – A terceira seção mostra o comportamento (operações). • Exemplo: Pedido confirmaVenda número data vendedor adicionaItem Cancela Nome da Classe Atributos Operações (Métodos) 9 Classes - Outros Exemplos: Carro cor modelo velocidadeAtual liga acelera Conta transfere_para número titular saldo saca deposita Cliente nome endereço cpf alteraEndereco 10 Definição de Classe em Java class Nome_da_Classe { // definição dos atributos [visibilidade] tipo nome_do_atributo [= valor_inicial]; // ... outros atributos // definição dos métodos [visibilidade] tipo_de_retorno nome_do_método (lista_de_parâmetros) { comandos; } // ... outros métodos } 11 Definição de Classe: Exemplo class Employee{ // atributos private String name; private Double salary; private Date hireDay; // mais atributos ... // definição de métodos public String getName(){ return name; // ou this.name } // mais métodos ... } 12 Atributos • Os atributos definem o conjunto de propriedades de uma classe. • Nome de atributos são substantivos simples ou frases substantivas. • Cada atributo deve ter uma definição clara e concisa. • Cada objeto tem um valor para cada atributo definido na sua classe. • Para definir atributos, liste as propriedades de uma classe que sejam relevantes para o domínio em questão. Deve-se procurar um compromisso entre objetividade (procurar atender a determinado projeto, com o mínimo custo) e generalidade (permitir a reutilização da classe em outros projetos). 13 Atributos • Um atributo é definido por: – nome: um identificador para o atributo. – tipo: o tipo do atributo (inteiro, real, caractere etc.) – valor_default: opcionalmente, pode-se especificar um valor inicial para o atributo. – visibilidade: opcionalmente, pode-se especificar o quão acessível é um atributo de um objeto a partir de outros objetos. Valores possíveis são: • privativo - nenhuma visibilidade externa; • público - visibilidade externa total; • protegido - visibilidade externa limitada. 14 Operações • Uma classe incorpora um conjunto de responsabilidades que definem o comportamento dos objetos na classe. • As responsabilidades de uma classe são executadas por suas operações. • Uma operação é um serviço que pode ser requisitado por um objeto para obter um dado comportamento. • Operações também são chamadas de métodos (Java) ou funções-membro (C++). 15 Diretrizes para Escolha de Operações • Cada operação deve realizar uma função simples. • O nome deve refletir o resultado da operação, e não as suas etapas. – Ex.: Use ObterSaldo() ao invés de CalcularSaldo(). Esta última indica que o saldo deve ser calculado, o que é uma decisão de implementação. • Evite excesso de argumentos de entrada e saída, o que geralmente indica a necessidade de partir as operações em outras mais simples. 16 Definição de Operações • Uma operação (método) é definida por: – nome: um identificador para o método. – tipo: quando o método tem um valor de retorno, o tipo desse valor. – lista de argumentos: quando o método recebe parâmetros para sua execução, o tipo e um identificador para cada parâmetro. – visibilidade: como para atributos, define o quão visível é um método a partir de objetos de outras classes. - Exemplo: class Conta{ double salario; // ... outros atributos public void saca(double quantidade){ double novoSaldo = this.saldo – quantidade; this.saldo = novoSaldo; } 17 Criação de Objetos • Conceito: – No paradigma de orientação por objetos, tudo pode ser potencialmente representado como um objeto. Um objeto não é muito diferente de uma variável normal. – Quando se cria um objeto, esse objeto adquire um espaço em memória para armazenar seu estado (os valores de seu conjunto de atributos, definidos pela classe) e um conjunto de operações que podem ser aplicadas ao objeto (o conjunto de métodos definidos pela classe). – Um programa orientado por objetos é composto por um conjunto de objetos que interagem através de "trocas de mensagens". Na prática, essa troca de mensagem traduz-se na aplicação de métodos a objetos. 18 Criação de Objetos • A criação de um objeto é feita pelo operador new. new NomeDaClasse(); – Essa expressão é uma invocação do construtor, um método especial cujo objetivo é construir e inicializar objetos. – A aplicação do operador new ao construtor da classe retorna uma referência para o objeto. Para que o objeto possa ser efetivamente manipulado, essa referência deve ser armazenada por uma variável (variável-objeto) : NomeDaClasse minhaRef = new NomeDaClasse(); • Nesse exemplo, minhaRef é uma variável que guarda uma referência para um objeto do tipo NomeDaClasse. 19 Manipulação de Objetos • A declaração de uma variável cujo tipo é uma classe não cria um objeto. Cria-se uma referência para um objeto da classe, a qual inicialmente não faz referência a nenhum objeto válido. • Exemplo: String nome; nome ? 20 Manipulação de Objetos • Ao se criar um objeto, usando o operador new, obtém-se uma referência válida, que é armazenada na variável do tipo da classe.• Exemplo (continuação): nome = new String(“Curso de Java”); – a variável nome armazena uma referência para o objeto cujo conteúdo é “Curso de Java”. nome Curso de Java Outras informações Objeto 21 Manipulação de Objetos • A biblioteca Java padrão contém uma classe Date. Os objetos dessa classe descrevem pontos no tempo como, por exemplo: “December 31, 1999, 23:59:59 GMT”. – Exemplos: new Date(); // constrói um novo objeto. O objeto é inicializado de acordo com a data e hora atuais. System.out.println(new Date()); // é possível passar diretamente um objeto para um método String s = new Date().toString(); // aplicação do método toString() ao objeto criado. Date birthday = new Date(); // armazenando o objeto em uma variável para poder referenciá-lo. 22 Manipulação de Objetos • Diferença entre objetos e variáveis-objeto (que fazem referência a objetos) Date deadline; // dealine não referencia nenhum objeto s = deadline.toString(); // causa um erro de compilação pois deadline ainda não referencia nenhum objeto • Formas de inicialização de variáveis-objeto: deadline = new Date(); ou deadline = birthday; 23 Manipulação de Objetos • Indicando “explicitamente” que uma variável não referencia nenhum objeto. deadline = null; ... if (deadline != null) System.out.println(deadline); • Aplicar um método a variável que contenha null, gera um erro em tempo de execução: birthday = null; String s = birthday.toString(); // Erro em tempo de execução 24 Manipulação de Objetos nome = new String(“Curso de Java”); • A variável nome do exemplo anterior mantém (armazena) apenas a referência para o objeto e não o objeto em si. • O operador = (atribuição) não cria outro objeto. Ele simplesmente atribui a referência para o objeto. • Exemplo: String outroNome = nome; nome Curso de Java Outras informaçõesoutroNome 25 Manipulação de Objetos • Para efetuar uma cópia de um objeto, criando um novo objeto com o mesmo conteúdo de um objeto já existente, é necessário usar o método clone() da classe Object, da qual todos os objetos descendem. • Exemplo (continuação): String outraString = nome.clone(); nome Curso de Java Outras informaçõesoutroNome outraString Curso de Java Outras informações 26 Manipulação de Objetos • O operador == para objetos compara apenas se os dois objetos têm a mesma referência (apontam para o mesmo local). – Exemplo (continuação): nome == outroNome // resulta true nome == outraString // resulta false outroNome == outraString // resulta false • O método equals() da classe String compara se o conteúdo de dois objetos são iguais. – Exemplo (continuação): nome.equals(outroNome) // resulta true outroNome.equals(nome) // resulta true nome.equals(outraString) // resulta true outraString.equals(nome) // resulta true 27 Exemplo OO public class PrimeiroProgramaOO { private int x; public void atribuiValor(int valor) { x = valor; } public int obtemValor() { return x; } public static void main (String[] args) { PrimeiroProgramaOO p = new PrimeiroProgramaOO(); p.atribuiValor(15); System.out.println(p.obtemValor()); } } 28 Métodos Construtores • Construtor é um método especial chamado quando um novo objeto é criado pelo operador new(). • Métodos construtores possuem as seguintes características: – normalmente são métodos públicos; – possuem o mesmo nome da classe; – não possuem valor de retorno; – podem ter parâmetros; – pode haver sobrecarga (overloading) de construtores; – um construtor default sem parâmetros é gerado se nenhum construtor é fornecido pelo implementador da classe. • O construtor default inicializa todas os atributos da classe, não inicializados explicitamente, com seus valores padrão (números com zero, variáveis-objeto com NULL e booleanos com falso). 29 Exemplo public class Caixa { private double comprimento, largura, altura; public Caixa() { // construtor default comprimento = 10; largura = 10; altura = 10; } public Caixa(double comp, double larg, double alt) { comprimento = comp; largura = larg; altura = alt; } public void setComprimento(double comp) { comprimento = comp; } public void setLargura(double larg) { largura = larg; } public double getLargura() { return largura; } public double volume() { return (comprimento * largura * altura); } public static void main(String[] args) { Caixa c1 = new Caixa(); System.out.println("Volume da caixa 1 = " + c1.volume()); // volume = 1000 Caixa c2 = new Caixa(10,5,3); System.out.println("Volume da caixa 2 = " + c2.volume()); // volume = 150 c2.setComprimento(8); c2.setLargura(c2.getLargura()-3); System.out.println("Novo volume da caixa 2 = " + c2.volume()); // volume = 48 } } 30 this • Suponha o seguinte código: Caixa c1 = new Caixa(); Caixa c2 = new Caixa(10,5,3); double v1 = c1.volume(); // v1 = 1000 double v2 = c2.volume(); // v2 = 150 – Como é que o método volume sabe de qual objeto ele deve obter o tamanho? • this é uma referência implícita passada para os métodos para referenciar o objeto corrente. – usada quando um método precisa se referir ao objeto que o chamou; – pode ser usada dentro de qualquer método para se referir ao objeto corrente; – pode ser usada sempre que uma referência ao objeto for permitida. 31 this • this é usada principalmente em dois contextos: – diferenciar atributos de objetos de parâmetros ou variáveis locais de mesmo nome. public class Caixa { private double comprimento, largura, altura; public Caixa(double comprimento, double largura, double altura) { this.comprimento = comprimento; this.largura = largura; this.altura = altura; } } – Acessar o método construtor a partir de outros construtores. public Caixa() { this (10, 10, 10) } 32 Exemplo import java.util.*; public class EmployeeTest{ public static void main(String[] args){ // preenche o array de funcionários com três objetos Employee Employee[] staff = new Employee[3]; staff[0] = new Employee("Carl Cracker", 75000, 1987, 12, 15); staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1); staff[2] = new Employee("Tony Tester", 40000, 1990, 3, 15); // aumenta o salário do todos os funcionários em 5% for (Employee e : staff) e.raiseSalary(5); // imprime as informações sobre todos os objetos Employee for (Employee e : staff) System.out.println("name=" + e.getName() + ",salary=" + e.getSalary() + ",hireDay=“ + e.getHireDay()); } } 33 Exemplo (continuação) class Employee{ public Employee(String n, double s, int year, int month, int day){ name = n; salary = s; GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day); // GregorianCalendar usa 0 para indicar o mês de janeiro hireDay = calendar.getTime(); } public String getName(){ return name; } public double getSalary(){ return salary; } public Date getHireDay(){ return hireDay; } 34 Exemplo (continuação) public void raiseSalary(double byPercent){ double raise = salary * byPercent / 100; salary += raise; } private String name; private double salary; private Date hireDay; } 35 Exemplo: Comentários • Existem 2 classes em um único arquivo fonte: Employe e EmployeeTest (com o modificador public) • O nome do arquivo fonte é: EmployeeTest.java porque o nome do arquivo deve corresponder ao nome da classe public. • Só pode haver uma classe pública em um arquivo fonte, mas pode haver um número qualquer de classes não públicas. • Ao chamar javac EmployeeTest.java: – o compilador criará dois arquivos: EmployeeTest.class e Employee.class. – A execução do programa é iniciada da seguinte forma: java EmployeeTest • Observação: é permitido colocar cada classe em um arquivo fonte-próprio. Ex: Employee.java e EmployeeTest.java – Nesse caso, existem duas opções de compilação: javac Employee*.java // uso de um curinga * javac EmployeeTest.java 36 “Dissecando” a classe Employee (1) • Métodos da Classe: public Employee(String n, double s, int year, int month, int day) public String getName()public double getSalary() public Date getHireDay() public void raiseSalary(double byPercent) – A palavra-chave public significa que qualquer método em qualquer classe pode chamar o método. (essa propriedade será vista mais adiante) • Atributos: private String name; private double salary; private Date hireDay; – A palavra-chave private assegura que os únicos métodos que podem acessar esses atributos são os métodos da própria classe Employee. Nenhum método externo pode ler ou gravar nesses campos. 37 “Dissecando” a classe Employee (2) • Construtor: public Employee(String n, double s, int year, int month, int day){ name = n; salary = s; GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day); hireDay = calendar.getTime(); } – O construtor possui o mesmo nome da classe e é executado quando se instancia um novo objeto da classe Employee – dando aos atributos o estado inicial desejado. new Employee(“James Bond”, 100000, 1950, 1, 1); name = “James Bond” salary = 100000; hireDay = January, 1, 1950; – Todo construtor só pode ser chamado em conjunto com o operador new. Não se pode aplicar um construtor a um objeto já existente para reinicializar os atributos desse objeto. Employee Teste = new Employee(“James Bond”, 100000, 1950, 1, 1); Teste.Employee(“Wolverine”, 200000, 1975, 2, 1); // Erro de compilação 38 “Dissecando” a classe Employee (3) • Parâmetros implícitos e explícitos: os métodos operam nos objetos e acessam seus atributos. - Exemplo: public void raiseSalary(double byPercent){ double raise = salary * byPercent / 100; salary += raise; } Considere a seguinte chamada: number007.raiseSalary(5); – O método raiseSalary tem dois parâmetros: • Implícito: é o objeto (number007) da classe Employee que aparece antes do nome do método. Não aparece na declaração do método. • Explícito: o número (5) entre o parenteses. Eles são listados explicitamente na declaração do método, como double byPercent. • Em cada método, a palavra chave this referencia o parâmetro implícito. Se preferir o método pode ser reescrito da seguinte forma: public void raiseSalary(double byPercent){ double raise = this.salary * byPercent / 100; this.salary += raise; } 39 “Dissecando” a classe Employee (4) • Alguns benefícios do Encapsulamento: public String getName(){ // método de acesso return name; } 1) O atributo name é um campo de leitura somente. Após inicializá-lo (configurá-lo) no construtor, não há nenhum método disponível na classe para alterá-lo. Assim, tem-se a garantia de que name nunca será corrompido. public void raiseSalary(double byPercent){ // método modificador double raise = salary * byPercent / 100; salary += raise; } 2) O atributo salary não é de leitura somente. Mas, ele só pode ser alterado pelo método raiseSalary. Caso, alguma vez, seu valor esteja inconsistente, somente esse método precisa ser depurado. Se salary fosse public, o culpado por bagunçar o valor poderia estar em qualquer lugar 40 “Dissecando” a classe Employee (5) • Benefícios do Encapsulamento (continuação) • Em POO, para obter e configurar (alterar) o valor de um atributo, é recomendado fornecer 3 itens: – atributo de dados privado; – método de acesso público; // getter – método modificador público; // setter • Principal vantagem: alteração da implementação interna da classe sem afetar nenhum código cliente (que faz uso da classe). Exemplo: O atributo de String name na classe Employee poderia ser substituído por dois outros atributos: String firstName; String lastName; Assim, o método getName() poderá ser alterado para retornar: return firstName + “ ” + lastName; Essa mudança é completamente invisível ao resto do programa !!! 41 Cuidado: Quebra de Encapsulamento !!! (1) • Evite não escrever métodos de acesso que retornem referência a objetos mutáveis. Exemplo: (violação da regra) public Date getHireDay(){ return hireDay; } Isso pode quebrar o encapsulamento !!! Observe: Employee harry = new Employee(“Harry”, 1000, 1975, 1, 1); Date d = harry.getHireday(); double tenYearsInMilliSeconds = 10*365.25*24*60*60*1000; d.setTime(d.getTime()-(long) tenYearsInMilliSeconds); // esse método modificador altera tanto d como harry.hireDay, pois ambos referenciam o mesmo objeto 42 Cuidado: Quebra de Encapsulamento !!! (2) • Se for necessário retornar uma referência a um objeto mutável, deve-se primeiro cloná-lo. Um clone é uma cópia exata do objeto porém armazenado em uma nova localização. Exemplo: Correção que evita quebra de encapsulamento !!! public Date getHireDay(){ return (Date) hireDay.clone(); } • Como regra prática, utilize clone() sempre que precisar retornar uma cópia de um campo de dados mutável. 43 Atributos e Métodos Estáticos (1) • Atributos Estáticos: – Ao se definir um atributo como estático, usando o modificador static, haverá apenas um desses campos por classe individual. – Nesse caso, todos os objetos de uma classe compartilham o atributo estático. O atributo estático funciona como “uma variável global da classe”. – Em comparação, cada objeto tem sua cópia separada dos atributos definidos para a classe. Exemplo: class Employee{ ... private int id; private static int nextId = 1; } Obs.: cada objeto Employee tem um campo id próprio, mas há apenas um campo nextId que é compartilhado entre todas as intâncias da classe. 44 Constantes Estatísticas (1) Exemplo: public class Math { ... public static final double PI = 3.14159265358979323846; ... } - Atributos estáticos públicos podem ser acessados em outros programas como “nomeClasse.nomeAtributo” Ex: Math.PI; Obs.: se o modificador static fosse omitido, então PI seria um atributo da classe Math. Isto é, você precisaria de um objeto da classe Math para acessar PI, e cada objeto Math teria uma cópia de PI. 45 Constantes Estatísticas (2) • Curiosidade: System.out é uma constante estatística !!! Ela é declarada na classe System assim: public class System { ... public static final PrintStream out = ... ... } -Acesso:“nomeClasse.nomeAtributo” = “System.out” Obs: Nunca é uma boa idéia ter campos públicos, porque qualquer programa cliente pode modificá- los. Mas tudo bem para constantes públicas. 46 Métodos Estáticos (1) • Assim como atributos estáticos, métodos estáticos não precisam de um objeto para serem ativados. Pode-se invocar diretamente um método estático sem necessidade de se criar um objeto. • Por conseqüência, métodos estáticos: – só podem acessar dados estáticos da classe, i.e., não é possível acessar atributos da classe não estáticos a partir de um método estático. – não podem se referir a this; – só podem chamar outros métodos estáticos. • Declaração – precedido da palavra-chave static. – Exemplo: public static double potencia(double x, double a) 47 Métodos Estáticos (2) • Ativação: NomeDaClasse.método() • Exemplos: Public static int getNextId(){ return nextId; // retorna o campo estático } Para chamar o método: int n = Employee.getNextId(); – todos os métodos da classe java.lang.Math. double cosseno = Math.cos(60); double valor = Math.sqrt(144); double pot = Math.pow(2,3); – método main: public static void main (String[] args) • pode ser chamado antes de qualquer objeto existir. • geralmente instancia um objeto aplicação para acessar atributos não estáticos. 48 Métodos Estáticos (3) • Quando usar Métodos Estáticos: – Quando um método não precisa acessar o estado de um objeto pois todos os parâmetros necessários são fornecidos como parâmetros explícitos. Exemplo: Math.pow(x,a) – Quando um método só precisa acessar campos estáticos da classe. Exemplo: Employee.getNextId() 49 Exemplo: Atributos e Métodos Estáticos (1) public class StaticTest { public static void main(String[] args) { // preenche o array de funcionários com 3 objetos Employee Employee[] staff = new Employee[3]; staff[0] = new Employee("Tom", 40000); staff[1] = new Employee("Dick", 60000); staff[2]= new Employee("Harry", 65000); // imprime as informações sobre todos os objetos Employee for (Employee e : staff) { e.setId(); System.out.println("name=" + e.getName() + ",id=" + e.getId() + ",salary=" + e.getSalary()); } int n = Employee.getNextId(); // chama o método estático System.out.println("Next available id=" + n); } } 50 Exemplo: Atributos e Métodos Estáticos (2) class Employee { public Employee(String n, double s){ name = n; salary = s; id = 0; } public String getName(){ return name; } public double getSalary(){ return salary; } public int getId(){ return id; } public void setId(){ id = nextId; // configura o id com o próximo id disponível nextId++; } 51 Exemplo: Atributos e Métodos Estáticos (3) public static int getNextId(){ return nextId; // retorna o campo estático } public static void main(String[] args) // teste de unidade { Employee e = new Employee("Harry", 50000); System.out.println(e.getName() + " " + e.getSalary()); } private String name; private double salary; private int id; private static int nextId = 1; } Obs: cada classe pode ter um método main. É um truque prático para o teste de unidade das classes. Assim, para testar a classe Employee separadamente, deve-se executar: java Employee Se a classe Employee for parte de um aplicativo maior (chamado Application), ao iniciar o aplicativo com: java Application (o método main da classe Employee nunca é executado) 52 Finalizadores (1) • Java não possui métodos destrutores – A coleta de lixo é automática. – C++ possui métodos destrutores explícitos para qualquer código de limpeza (liberação de memória) • Em Java, não há necessidade de explicitamente liberar áreas de memória alocadas para um objeto – quando não há mais referências para uma área, ela pode ser liberada. – a liberação ocorre esporadicamente durante a execução, podendo até não ocorrer. A coleta de lixo é não-determinística. 53 Finalizadores (2) • Método finalize() – usado quando o objeto precisar realizar alguma ação antes de ser destruído. – antes de liberar o objeto, o método finalize() será chamado. protected void finalize() { // corpo do método } – como a coleta de lixo é não-determinística não se tem certeza quando o método finalize() será executado. 54 Finalizadores (3) • O programador não tem como atuar explicitamente na coleta de lixo. No entanto, o programador pode: – remover explicitamente a referência a um objeto para sinalizar ao coletor de lixo que o objeto não mais é necessário e pode ser removido; – sugerir (mas não forçar) que o sistema execute o coletor de lixo (garbage collector) através da invocação ao método gc() da classe java.lang.System. public static void gc() – sugerir que o sistema execute os métodos finalize() de objetos descartados através da invocação ao método runFinalization() da classe java.lang.System. public static void runFinalization() 55 Pacotes (1) • Pacote é um recurso para agrupar física e logicamente classes e interfaces relacionadas. • O uso de Pacotes garante a singularidade dos nomes das classes. – Não há conflito entre duas classes contendo o mesmo nome (ex. Employee.class) desde que elas estejam em pacotes diferentes. • O nome de um pacote corresponde a um nome de diretório. • Pacotes podem ser organizados usando níveis de aninhamento (hierarquia). • Do ponto de vista do compilador, não há nenhum relacionamento entre pacotes aninhados. – java.util e java.util.jar são coleções independentes de classes 56 Pacotes (2) • Importação de Classes: – Uma classe pode utilizar todas as classes do seu próprio pacote e as públicas de outros pacotes. – As classes públicas definidas em um pacote podem ser usados fora do pacote da seguinte maneira: • prefixados pelo nome do pacote: Ex:. java.util.Date today = new java.util.Date(); • importados diretamente via cláusula import: Ex:. import java.util.Date; // ou import java.util.* Date today = new Date(); Na instrução import java.util.* vc importa o pacote inteiro. Entretanto, as importações supérfluas são descartadas. – as instruções import devem ser inseridas na parte superior de seus arquivos-fontes (mas abaixo da instrução package) 57 Pacotes (3) • Conflito de Nomes: – pacotes java.util e java.sql têm uma classe Date. Ex: import java.util.*; import java.sql.*; Date today; // Error – java.util.Date ou java.sql.Date? Resolvendo o problema: import java.util.*; import java.sql.*; import java.util.Date; Date today; // ok Funciona !!! 58 Pacotes (4) • Importações Estatísticas: – import pode ser usada para a importação de campos e métodos estáticos, não somente classes. import static java.lang.System.*; out.println(“Alô Mundo”); // System.out exit(0); // System.exit - Usos Práticos para Impotações Estáticas: - Funções Matemáticas: torna seu uso mais natural, Ex: sqrt(pow(x,2) + pow(y,2)) // ao invés de Math.sqrt(Math.pow(x,2) + Mathpow(y,2)) - Constantes Incômodas: uso de grande número de constantes. Ex: if (d.get(DAY_OF_WEEK == MONDAY)) // ao invés de if (d.get(Calendar.DAY_OF_WEEK == Calendar.MONDAY)) 59 Pacotes (5) • Adicionando Classes a um Pacote – Uso da instrução package na parte superior do arquivo-fonte, antes do código que define as classes no pacote. package com.horstmann.corejava; public class Employee { ... } – a não definição de um pacote no arquivo-fonte implica que as classes nesse arquivo fonte pertencem ao pacote padrão. – Os arquivos-fontes devem ser inseridos em um subdiretório que corresponde ao nome do pacote completo. Portanto, o arquivo Employee.java deve estar contido em um subdiretório com\horstmann\corejava – O compilador insere os arquivos de classe na mesma estrutura de diretório. 60 Pacotes (6) import com.horstmann.corejava.*; // a classe Employee é definida neste pacote import static java.lang.System.*; public class PackageTest { public static void main(String[] args) { //por causa da intrução de importação, não precisamos usar // com.horstmann.corejava.Employee aqui Employee harry = new Employee("Harry Hacker", 50000, 1989, 10, 1); harry.raiseSalary(5); // por causa da instrução de importação estática, não precisamos usar System.out // aqui out.println("name=" + harry.getName() + ",salary=" + harry.getSalary()); } } 61 Pacotes (7) package com.horstmann.corejava; // as classes nesse arquivo são parte desse pacote import java.util.*; // instruções de importação vêm depois da instrução de pacote public class Employee { public Employee(String n, double s, int year, int month, int day){ name = n; salary = s; GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day); // GregorianCalendar uses 0 for January hireDay = calendar.getTime(); } public void raiseSalary(double byPercent){ double raise = salary * byPercent / 100; salary += raise; } private String name; private double salary; private Date hireDay; } 62 Pacotes (8) • O programa anterior é distribuído em relação a dois pacotes: – a classe PackageTest pertence ao pacote padrão – a classe Employee pertence ao pacote com.horstmann.corejava. – Para compilar o programa, mude para o diretório de base e execute o comando: • javac PackageTest.java – O compilador localiza automaticamente o arquivo com\horstmann\corejava\Employee.java e o compila 63 Pacotes (9) • Arquivos jar (java archive): contém múltiplos arquivos de classe e subdiretórios em um formato compactado. (economiza espaço) • Ao receber uma biblioteca no formato jar, ela deve ser incluída no seu programa, i.e., deve-se especificar ao carregador da máquina virtual de classes onde procurá-la. • Caminho de Classe (ClassPath): coleção de todas as localizações que podem conter arquivos de classe. – Ele lista todos os diretórios e repositórios de arquivos que são pontos de partida para localizar classes. 64 Pacotes (10) • Caminho de Classe – Exemplo: c:\cristiano\classdir;.;c:\cristiano\archives\archive.jar- Suponha que a máquina virtual pesquise o arquivo de classe com.horstmann.corejava.Employee. Ela recorre ao caminho de classe e procura os seguintes arquivos: 1. c:\cristiano\classdir\com\horstmann\corejava\Employee.class 2. \com\horstmann\corejava\Employee.class (iniciando no diretório atual) 3. \com\horstmann\corejava\Employee.class (dentro de c:\cristiano\archives\archive.jar) • Configurando o Caminho de Classe: java –classpath c:\cristiano\classdir;.;c:\cristiano\archives\archive.jar MyProg - O caminho de classe também pode ser definido através da variável de ambiente CLASSPATH no shell do Windows ou Linux: set CLASSPATH = c:\cristiano\classdir;.;c:\cristiano\archives\archive.jar 65 Pacotes (11) • Pacotes da API Java: – java.applet • criação de applets, interação de applets com o browser. – java.awt • criação e manipulação de interfaces gráficas de usuário. – java.awt.event • tratamento de eventos dos componentes da interface. – java.io • entrada e saída de dados. – java.lang • importado automaticamente por todos os programas, contém classes e interfaces básicas. 66 Pacotes (12) • Pacotes da API Java: – java.net • comunicação via Internet. – java.rmi • criação de programas distribuídos. – java.sql • interação com bancos de dados. – java.text • manipulação de textos, números, datas e mensagens. – java.util • manipulação de datas, hora, geração de números aleatórios etc. – javax.swing • componentes de interface gráfica independentes de plataforma. 67 Comentários (1) • javadoc: gera documentação html a partir de arquivos-fonte. – Extrai informações para os seguintes itens: • Pacotes; • Interfaces e classes públicas; • Métodos públicos e protegidos; • Campos públicos e protegidos. – Um comentário javadoc inicia com /** e termina com */. É possível utilizar modificadores html e tags especiais. Exemplo: <em>...</em>, <code>...</code>, <strong>...<strong>, etc. 68 Comentários (2) • Comentários de Classe: precede a classe /** Um objeto <code> Card </code> representa a carta de um baralho, como “rainha de copas”. Uma carta tem um naipe (ouro, copa, espada ou pau) e um valor (1=ás, 2 . . ., 10, 11=valete, 12=rainha, 13=rei) */ public class Card{ } • Comentários de Método: precede o método /** Aumenta o salário de um funcionário. @param byPercent é a porcentagem de aumento do salário (por exemplo, 10 = 10%) @return o valor do aumento */ public double raiseSalary(double byPercent){ double raise = salary * byPercent / 100; salary += raise; return raise; } 69 Comentários (3) • Comentários de Atributo: para atributos públicos (geralmente constantes estáticas) /** O naipe de carta copas */ public static final HEARTS = 1; • Tags para uso em comentário gerais: @author nome @version texto @since texto @deprecated texto Ex: @deprecated Use <code>setVisible(true)</code> instead @see referência Ex: @see com.horstmann.corejava.Employee#raiseSalary(double) // cria um link para o método raiseSalary(double) na classe com.horstmann.corejava.Employee 70 Dicas de Design de Classes 1. Sempre mantenha os atributos privados. 2. Sempre inicialize os dados. 3. Não utilize muitos tipos básicos em uma classe. 4. Nem todos os campos específicos precisam de métodos de acesso e modificadores; 5. Use uma forma padrão para as definições de classe; 6. Divida classes que têm muitas responsabilidades; 7. Faça os nomes de suas classes e de seus métodos refletirem suas respectivas responsabilidades.
Compartilhar