BCC221 Programação Orientada a Objetos. Prof. Marco Antonio M. Carvalho 2014/2 - PDF
Download "BCC221 Programação Orientada a Objetos. Prof. Marco Antonio M. Carvalho 2014/2"
Elias Fagundes Canto
1 BCC221 Programação Orientada a Objetos Prof. Marco Antonio M. Carvalho 2014/2
2 Site da disciplina: Moodle: Lista de e- mails: bcc221- Para solicitar acesso: decom 2
5 Métodos static Classe Math Promoção de Argumentos Sobrecarga de Métodos Composição Enumerações Enumerações e Classes static import Criando Pacotes Acesso de Pacote 5
6 Herança Especificadores de Acesso Classe Object Exemplo Construtores em Subclasses Compilação Redefinição de Métodos Métodos e Classes final Engenharia de Software com Herança 6
7 A herança é uma das características primárias da orientação a objetos Uma forma de reuso de software pela qual uma classe nova é criada e absorve os membros de classes já existentes, aprimorando- os; Diminui o tempo de implementação; Aumenta a confiabilidade e qualidade do software Desde que sejam utilizados bons componentes. 7
8 Uma classe já existente e que é herdada é chamada de superclasse A nova classe que herdará os membros é chamada de subclasse. Normalmente, uma subclasse adiciona os seus próprios atributos e métodos ao comportamento da superclasse Logo, é uma forma especializada da superclasse; Uma subclasse também pode vir a ser uma superclasse. A superclasse direta é a superclasse da qual a subclasse herda explicitamente As outras são consideradas superclasses indiretas. 8
9 Na herança única, uma subclasse herda somente de uma superclasse direta Java não permite a realização de herança múltipla, em que uma subclasse pode herdar de mais de uma superclasse direta; No entanto, é possível utilizar interfaces para desfrutar de alguns dos benefícios da herança múltipla evitando alguns dos problemas relacionados. 9
10 Relembrando Herança define um relacionamento é um Um objeto da subclasse é um objeto da superclasse; O contrário não é verdadeiro. Um problema com a herança é que a subclasse pode herdar métodos que não precisa ou que não deveria ter Ainda, o método pode ser necessário, mas inadequado; A classe pode sobrescrever (override) um método herdado para adequá- lo. 10
12 public: Os membros public de uma classe são acessíveis em qualquer parte de um programa em que haja uma referência a um objeto da classe ou das subclasses. private: Membros private são acessíveis apenas dentro da própria classe. protected: Membros protected podem ser acessados por por membros da própria classe, de subclasses e de classes do mesmo pacote protected também tem acesso de pacote. 12
13 Todos os membros public e protected de uma superclasse mantêm seus especificadores de acesso quando se tornam membros de uma subclasse Subclasses se referem a estes membros simplesmente pelo nome; Quando uma subclasse sobrescreve um método da superclasse, o método original da superclasse ainda pode ser acessado quando antecedido pela palavra super seguida de. super.metodo(); 13
15 A hierarquia das classes em Java é iniciada pela classe Object Todas as outras classes herdam (ou estendem) direta ou indiretamente a partir dela Mesmo que não seja definido explicitamente. Define um construtor e 11 métodos Alguns devem ser sobrescritos pelas subclasses para melhor funcionamento. Não possui atributos. 15
16 clone() equals() finalize() tostring() Métodos da classe Object getclass() hashcode() notify(), notifyall() wait() 3 versões 16
17 clone() Método protected; Retorna uma referência para Object Exige um cast para o objeto original. Realiza a cópia do objeto a partir do qual foi invocado; Classes devem sobrescrevê- lo como um método público Devem também implementar a interface Cloneable. A implementação padrão realiza uma cópia rasa Uma implementação sobrescrita normalmente realiza uma cópia profunda. tips.org/java- se- tips/java.lang/how- to- implement- cloneable- interface.html 17
18 A cópia rasa (shallow copy) realiza o mínimo de duplicação possível É uma cópia de referência, não dos elementos Não existe para classes que possuem apenas tipos primitivos. Dois objetos compartilham os mesmos membros. A cópia profunda (deep copy) realiza o máximo de duplicação possível Cria um novo objeto completo e independente; Mesmo conteúdo do objeto clonado, membro a membro. 18
19 shallow copy deep copy 19
20 equals() Compara dois objetos quanto a igualdade e retorna true caso sejam iguais, false caso contrário; Quando dois objetos de uma classe em particular precisarem ser comparados, este método deve ser sobrescrito Para considerar todos os membros. Toda implementação deve retornar true para comparação de um único objeto a.equals(a); false se o argumento é null; true sse a.equals(b) e b.equals(a) retornarem true; Se a.equals(b) e a.equals(c) retornarem true então b.equals(c) retorna true. 20
21 finalize() Invocado pelo coletor de lixo automático para realizar a terminação de um objeto prestes a ser coletado; Não há garantia de que o objeto será coletado, portanto, não há garantia de que este método será executado; Não possui parâmetros e retorna void; A implementação padrão não realiza nenhuma operação. 21
22 getclass() Todos objetos em Java conhecem o seu tipo em tempo de execução; Este método retorna um objeto da classe Class (pacote java.lang) que contém informações sobre o objeto, como o nome da classe (obtido pelo método getname()). 22
23 hashcode() Retorna um código hash (int) para o objeto a partir do qual foi invocado; Utilizado por tabelas hash, definidas em java.util.hashtable; Deve ser sobrescrito se o método equals() for sobrescrito. 23
24 wait() Relacionada a multithreading; Faz com que uma thread aguarde uma invocação para resumir sua execução, ou aguarde um determinado intervalo de tempo. 24
25 notify(), notifyall() Relacionada a multithreading; Respectivamente, acordam uma ou todas as threads que aguardam para resumir sua execução. 25
26 tostring() Retorna a representação do objeto que o invocou em formato de string; A implementação padrão retorna os nomes do pacote e da classe, seguidos pela representação em hexadecimal do valor retornado pelo método hashcode(); É recomendado que todas as subclasses sobrescrevam este método; Pode ser utilizado em substituição de métodos print(). 26
28 Consideremos novamente o exemplo de uma empresa que possui dois tipos de empregados Comissionados (superclasse) Recebem uma comissão sobre vendas. Assalariados Comissionados (subclasse) Recebem salário fixo e comissão sobre vendas. 28
29 public class CommissionEmployee { private String firstname; private String lastname; private String socialsecuritynumber; private double grosssales; private double commissionrate; public CommissionEmployee(String first, String last, String ssn, double sales, double rate) { //uma chamada implicita ao construtor Object ocorre aqui firstname = first; lastname = last; socialsecuritynumber = ssn; setgrosssales( sales ); setcommissionrate( rate ); } 29
30 // setter public void setfirstname( String first ) { firstname = first; } //getter public String getfirstname() { return firstname; } //setter public void setlastname( String last ) { lastname = last; } //getter public String getlastname() { return lastname; } 30
31 //setter public void setsocialsecuritynumber( String ssn ) { socialsecuritynumber = ssn; // should validate } //getter public String getsocialsecuritynumber() { return socialsecuritynumber; } //setter public void setgrosssales( double sales ) { grosssales = ( sales < 0.0 )? 0.0 : sales; } //getter public double getgrosssales() { return grosssales; } 31
32 //setter public void setcommissionrate( double rate ) { commissionrate = ( rate > 0.0 && rate < 1.0 )? rate : 0.0; } //getter public double getcommissionrate() { return commissionrate; } //calcula o salário public double earnings() { return getcommissionrate() * getgrosssales(); } 32
33 } //sobrescreve o método tostring da classe Object public String tostring() { return String.format( "%s: %s %s\n%s: %s\n%s: %.2f\n%s: %.2f", "commission employee", getfirstname(), getlastname(), "social security number", getsocialsecuritynumber(), "gross sales", getgrosssales(), "commission rate", getcommissionrate()); } 33
34 Construtores não são herdados Logo, a classe CommissionEmployee não herda o construtor da classe Object; Porém, o construtor da classe CommissionEmployee invoca implicitamente o construtor da classe Object; A primeira tarefa de qualquer construtor é invocar o construtor da superclasse direta Implicita ou explicitamente. Se não houver uma chamada explícita, o compilador invoca o construtor padrão Sem argumentos; Não efetua nenhuma operação. 34
35 O método tostring(), herdado da classe Object é sobrescrito na classe de exemplo Retorna uma String que representa um objeto; Este método é chamado implicitamente quando tentamos imprimir um objeto com %s no printf, por exemplo. O exemplo ainda utiliza o método format da classe String Retorna uma String montada a partir de parâmetros. 35
36 //declaração de herança public class BasePlusCommissionEmployee extends CommissionEmployee { private double basesalary; public BasePlusCommissionEmployee(String first, String last, String ssn, double sales, double rate, double salary) { //chama o construtor da superclasse super( first, last, ssn, sales, rate ); setbasesalary( salary ); } //setter public void setbasesalary( double salary ) { basesalary = ( salary < 0.0 )? 0.0 : salary; } 36
37 //getter public double getbasesalary() { return basesalary; } //metodo sobrescrito public double earnings() { //invoca o metodo earnings da superclasse return getbasesalary() + super.earnings(); } } //sobrescreve o método tostring da classe Object public String tostring() { return String.format("%s %s\n%s: %.2f", "base-salaried", super.tostring(), "base salary", getbasesalary()); } 37
38 A herança é definida pela palavra reservada extends; A subclasse invoca o construtor da superclasse explicitamente através da instrução super( first, last, ssn, sales, rate ); Esta deve ser a primeira ação em um construtor. 38
39 Se um método realiza as operações necessárias em outro método, é preferível que ele seja chamado, ao invés de duplicarmos o código Reduz a manutenção no código; Boa prática de Engenharia de Software. No exemplo, invocamos o método earnings() da superclasse, já que ele é sobrescrito na subclasse super.earnings(); 39
41 Como vimos no exemplo, instanciar uma classe derivada inicia uma cadeia de chamadas a construtores O construtor da subclasse chama o construtor da superclasse antes de executar suas próprias ações; O construtor da superclasse é chamada direta ou indiretamente (construtor default). Considerando um hierarquia de classes mais extensa: O primeiro construtor chamado é o da última subclasse E é o último a ser executado. O último construtor chamado é o da classe Object E é o primeiro a ser executado. 41
42 Primeiro a ser executado Superclasse Segundo a ser executado Chama o construtor da superclasse direta Subclasse 1 Subclasse 2 Terceiro a ser executado Último a ser executado Chama o construtor da superclasse direta Subclasse 3 Instância Chama o construtor da superclasse direta Chama o construtor da classe 42
44 Compilamos cada classe separadamente Uma maneira é compilar todas as classes de um diretório javac *.java 44
46 Subclasses podem redefinir métodos das superclasses A assinatura pode até mudar, embora o nome do método permaneça; A precedência é do método redefinido na classe derivada Na verdade, este substitui o método da classe base na classe derivada. Por exemplo, é possível sobrescrever um método public como private. 46
47 É comum que métodos redefinidos chamem o método original dentro de sua redefinição e acrescentem funcionalidades Como no exemplo anterior, em que frases adicionais são impressas na redefinição do método print(). 47
49 Uma variável ou atributo declarado com o modificador final é constante Ou seja, depois de inicializada não pode ser modificada. Um método declarado com o modificador final não pode ser sobrescrito; Uma classe declarada com o modificador final não pode ser estendida Embora possa ser utilizada em composições. 49
51 Em uma hierarquia de herança, uma subclasse não necessita ter acesso ao código fonte da superclasse Java exige apenas acesso ao arquivo.class da superclasse para que possamos compilar e executar uma subclasse. Esta característica é útil para software proprietário Basta distribuí- lo em formato bytecode, não é necessário fornecer o código fonte; No entanto, deve haver documentação precisa sobre o funcionamento da classe, para que outros programadores a compreendam. 51
52 Projetistas de sistemas orientados a objetos devem evitar a proliferação de classes Cria problemas de administração; Pode impedir o reuso de software Uma biblioteca grande demais e confusa dificulta ao usuário encontrar a funcionalidade desejada. Uma alternativa é criar menos classes com maior funcionalidade substancial. 52