Programação Orientada a Objetos* Reuso de classes Prof. Isabel Cafezeiro [email protected] http://www.dcc.ic.uff.br/~isabel *Baseado no livro Introdução à Programação Orientada a Objetos usando JAVA – Rafael Santos – Editora Campus – Série SBC Reuso de código Mecanismo de Reuso: Diminui a necessidade de re-escrever código: menos trabalho para o programador. Permite o aproveitamento de código pré-existente (livre de erro e otimizado): menos chances de cometer erros Em linguagens convencionais: biblioteca de funções e procedimentos Introdução Linguagens de Programação 2 Delegação Reuso de classes em POO: Para criar uma classe que se aproveita de características de uma outra classe: Delegação (composição) Uma instância da classe existente é usada como componente da nova classe. Herança A nova classe é uma extensão da classe existente. Introdução Linguagens de Programação 3 Reuso de código Reuso de classes em POO: Exemplo: Um aluno de um curso universitário é modelado pela classe RegistroAcadêmico. Delegação (composição) A classe RegistroAcadêmico possui o campo dataDeNascimento, que delega à classe Data a função de armazenar e manipular adequadamente a data de nascimento do aluno. Introdução Linguagens de Programação 4 Delegação ou Composição class RegistroAcademicoDeGraduacao { private String nomeDoAluno; private Data dataDeNascimento; private int númeroDeMatrícula; delegação: campos que são instâncias de classes. São manipulados da mesma forma que tipos nativos RegistroAcademicoDeGraduacao(String n,Data d,int m) { nomeDoAluno = n; dataDeNascimento = d; Chamada implícita do método tostring da númeroDeMatrícula = m; classe Data. A classe } RegistroAcademicoDeGraduacao delega à classe Data a formatação de seus dados. public String toString() { String resultado = ""; resultado += "Matrícula: “ + númeroDeMatrícula + " Nome: “ + nomeDoAluno+"\n"; resultado += "Data de Nascimento: “ + dataDeNascimento + "\n"; return resultado; } } // fim da classe RegistroAcademicoDeGraduacao RegistroAcademicoDeGraduacao.java Introdução Linguagens de Programação 5 Delegação ou Composição class DemoRegistroAcademicoDeGraduacao { public static void main(String args[]) { Data nascimento = new Data((byte)10,(byte)4,(short)1940); RegistroAcademicoDeGraduacao millôr = new RegistroAcademicoDeGraduacao("Millôr Fernandes", nascimento, 34990917); } System.out.println(millôr); } // fim da classe DemoRegistroAcademicoDeGraduacao DemoRegistroAcademicoDeGraduacao.java Introdução Linguagens de Programação 6 Reuso de código Reuso de classes em POO: Exemplo: Um aluno de um curso universitário é modelado pela classe RegistroAcadêmico. Herança Alunos de pós graduação possuem os mesmos componentes e comportamento de alunos de graduação. Porém, possuem também os componentes tese e orientador, e operações adequadas para lidar com estas informações. A classe RegistroAcadêmicoDePosGraduação estende RegistroAcadêmico com os campos tese e orientador e suas operações. Introdução Linguagens de Programação 7 Herança Relacionamento hierárquico entre classes: (super)classe ou ancestral (sub)classe ou classe herdeira A subclasse herda da classe: mais especializada todos os campos todos os métodos A subclasse pode conter atributos e métodos adicionais Introdução Linguagens de Programação 8 Herança Pessoa nome,identidade,nascimento Pessoa(n,i,nasc); qualIdentidade(); toString(); Funcionário admissão,salário Funcionário(n,i,nasc,adm,sal); qualSalário(); toString(); Introdução Linguagens de Programação 9 Herança class Pessoa { private String nome; private int identidade; private DataCons nascimento; Pessoa(String n,int i,DataCons d) { nome = n; identidade = i; nascimento = d; } public String toString() { return "Nome: "+nome+"\nIdentidade: "+identidade+" "+ "\nData de Nascimento: "+nascimento; } final public float qualIdentidade() { return identidade; } } // fim da classe Pessoa classes herdeiras não podem sobrepor este código. Introdução Linguagens de Programação Pessoa.java 10 Herança class Funcionario extends Pessoa { private DataCons admissão; private float salário; especifica a herança. nome e idade são privados em Pessoa: mesmo nas subclasses devem ser acessados através dos serviços oferecidos. Funcionario(String nome,int id,DataCons nasc, DataCons adm,float sal) { super(nome,id,nasc); admissão = adm; O construtor desta classe delega ao salário = sal; construtor da superclasse a tarefa de } inicializar os dados herdados. public String toString() { return super.toString()+"\n"+ "Data de admissão: "+admissão+ "\n" + "Salário: "+salário; } final public float qualSalário() { return salário; } } // fim da classe Funcionario toString desta classe delega a toString da superclasse a impressão de seus dados. Sintaxe diferente para invocar construtor ou método da superclasse. Funcionário.java Introdução Linguagens de Programação 11 Herança public class Empresa { public static void main(String[] args) { float s; int i; DataCons d1 = new DataCons((byte)12,(byte)12,(short)1967); Pessoa p = new Pessoa ("Denise", 3454637, d1); DataCons d2 = new DataCons((byte)1,(byte)12,(short)1972); DataCons d3 = new DataCons((byte)1,(byte)12,(short)2002); i = p.qualIdentidade(); Funcionario f1 = new Funcionario ("Rogerio", 93452128 ,d2 ,d3 ,(float)1000.00); s = f1.qualSalário(); i = f1.qualIdentidade(); System.out.println(f1); Funcionário herda as } operações de Pessoa } Empresa.java Introdução Linguagens de Programação 12 Herança Pessoa nome,identidade,nascimento Pessoa(n,i,nasc); toString(); Funcionário admissão,salário Funcionário(n,i,nasc,adm,sal); qualSalário(); toString(); ChefeDeDepartamento departamento, promoçãoAChefe ChefeDeDepartamento(n,i,nasc,adm,sal,dep,prom); qualDepartamento(); toString(); Introdução Linguagens de Programação 13 Herança class ChefeDeDepartamento extends Funcionario { private String departamento; private Data promoçãoAChefe; a herança é transitiva ChefeDeDepartamento(String nome,int id,Data nasc, Data adm, float sal, String dep,Data prom) { super(nome,id,nasc,adm,sal); departamento = dep; promoçãoAChefe = prom; } public String toString() { return super.toString()+"\n"+ Departamento:"+departamento+"\n" + "Data de promoção ao cargo:"+promoçãoAChefe; } public String qualDepartamento() { return departamento; } } // fim da classe ChefeDeDepartamento ChefeDeDepartamento.java Introdução Linguagens de Programação 14 Herança Pessoa nome,identidade,nascimento Pessoa(n,i,nasc); toString(); PacienteDeClínica planoDeSaúde PacienteDeClínica(n,i,nasc,plano); toString(); Funcionário admissão,salário Funcionário(n,i,nasc,adm,sal); qualSalário(); toString(); A herança é uma hierarquia: da raiz para as folhas; sem relacionamento entre irmãos. Não há herança múltipla ChefeDeDepartamento departamento, promoçãoAChefe ChefeDeDepartamento(n,i,nasc,adm,sal,dep,prom); qualDepartamento(); toString(); Introdução Linguagens de Programação 15 Hierarquia de classes em Java Class Hierarchy oclass java.lang.Object oclass java.lang.Boolean (implements java.io.Serializable) oclass java.lang.Character (implements java.lang.Comparable, java.io.Serializable) oclass java.lang.Character.Subset oclass java.lang.Character.UnicodeBlock oclass java.lang.Class (implements java.io.Serializable) ... oclass java.lang.Math oclass java.lang.Number (implements java.io.Serializable) oclass java.lang.Byte (implements java.lang.Comparable) oclass java.lang.Double (implements java.lang.Comparable) oclass java.lang.Float (implements java.lang.Comparable) oclass java.lang.Integer (implements java.lang.Comparable) oclass java.lang.Long (implements java.lang.Comparable) oclass java.lang.Short (implements java.lang.Comparable) ... Introdução Linguagens de Programação 16 Object: A raíz da hierarquia Todas as classes herdam de Object, mesmo que não contenham a declaração de herança. Contém apenas métodos genéricos, que devem ser reimplementados pelas classes. Introdução Linguagens de Programação 17 Object: A raíz da hierarquia Method Summary protected O bject boolean clone() Creates and returns a copy of this object. equals(Object obj) Indicates whether some other object is "equal to" this one. protected v oid Class finalize() Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. getClass() Returns the runtime class of an object. int hashCode() Returns a hash code value for the object. void notify() Wakes up a single thread that is waiting on this object's monitor. void notifyAll() Wakes up all threads that are waiting on this object's monitor. String toString() Returns a string representation of the object. void wait() Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. void wait(long timeout) Causes current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed. void wait(long timeout, int nanos) de Programação 18 another thread invokes the notify() method or the notifyAll() method for this object, or some Introdução Causes current thread to wait untilLinguagens other thread interrupts the current thread, or a certain amount of real time has elapsed. Reuso e Herança 1. 2. 3. 4. 5. 6. Campos da superclasse que não sejam privados podem ser utilizados diretamente. Campos privados da superclasse devem ser usados através dos serviços oferecidos pela superclasse. Construtores da superclasse podem ser utilizados através da palavra super. Somente os Construtores da superclasse imediata podem ser utilizados diretamente. Métodos da superclasse que não sejam privados podem ser utilizados diretamente. Métodos sobrepostos da superclasse que não sejam privados podem ser utilizados através da palavra super. class Funcionario extends Pessoa { private Data admissão; private float salário; Funcionario(String nome,int id,Data nasc,Data adm,float sal) { super(nome,id,nasc); (3) admissão = adm; salário = sal; } public String toString() { (6) return super.toString()+"\n"+ "Data de admissão: "+admissão+ "\n" + "Salário: "+salário; } final public float qualSalário() { return salário; } } // fim da classe Funcionario Funcionário.java Introdução Linguagens de Programação 19 Sobreposição Sobreposição de campos: Um campo declarado na subclasse oculta o campo de mesmo nome da superclasse. Sobreposição de métodos: Método herdado pode não ser adequado para os objetos das subclasses. Um método declarado na subclasse oculta o método com a mesma assinatura declarado na superclasse. O método oculto da superclasse, se não for privado, pode ser invocado através da palavra super. Sobrecarga de métodos: (aula 5) Método da super classe , que não seja privado, declarado com a mesma assinatura que um método da classe pode ser invocado através da palavra super. Introdução Linguagens de Programação 20 Amarração Tardia de Tipos Definição dinâmica do método a ser executado: depende do objeto que invoca o método public class Empresa { public static void main(String[] args) { float s; int i; DataCons d1 = new DataCons((byte)12,(byte)12,(short)1967); Pessoa p = new Pessoa ("Denise", 3454637, d1); DataCons d2 = new DataCons((byte)1,(byte)12,(short)1972); DataCons d3 = new DataCons((byte)1,(byte)12,(short)2002); i = p.qualIdentidade(); instância de Pessoa, método de Pessoa Funcionario f1 = new Funcionario ("Rogerio", 93452128 ,d2 ,d3 ,(float)1000.00); s = f1.qualSalário(); i = f1.qualIdentidade(); instância de Funcionário, método de System.out.println(f1); Pessoa } } Empresa.java Introdução Linguagens de Programação 21 Amarração Tardia de Tipos pclasse nome:“Rogerio” identidade: 457928 nascimento: 01/12/1972 admissão: 01/12/2002 salário: 1000.00 f1 PESSOA psuper Pessoa(...) toString() FUNCIONÁRIO psuper funcionário(...) qualsalário() toString() Introdução Linguagens de Programação 22 Amarração Tardia de Tipos Definição dinâmica do método a ser executado: depende do objeto que invoca o método public class EmpresaDin { public static void main(String[] args) { float s; int i; DataCons d1 = new DataCons((byte)12,(byte)12,(short)1967); Pessoa p = new Pessoa ("Denise", 3454637, d1); DataCons d2 = new DataCons((byte)1,(byte)12,(short)1972); DataCons d3 = new DataCons((byte)1,(byte)12,(short)2002); Funcionario f1 = new Funcionario ("Rogerio", 457928,d2,d3,(float)1000.00) } } p = f1; System.out.println(p); referência de Pessoa passa a apontar para instância de Funcionário invoca toString de Pessoa? de Funcionário? EmpresaDin.java Introdução Linguagens de Programação 23 Amarração Tardia de Tipos pclasse p nome:“Denise” pclasse identidade: 3454637 nascimento: 01/12/1967 nome:“Rogerio” f1 Introdução identidade: 457928 nascimento: 01/12/1972 admissão: 01/12/2002 salário: 1000.00 PESSOA psuper Pessoa(...) toString() FUNCIONÁRIO psuper funcionário(...) qualsalário() toString() Linguagens de Programação 24 Sobreposição Sobreposição de métodos: Um método public (subclasse) pode sobrepor um método private (superclasse); Um método private (subclasse) não pode sobrepor um método public (superclasse); Um método estático não pode ser sobreposto; Um método final é herdado pelas subclasses, mas não pode ser sobreposto. Classes declaradas como Final : tem todos os métodos final. Não pode ter subclasses. Mecanismo para barrar a herança !!! Introdução Linguagens de Programação 25 Polimorfismo Mecanismo que permite que uma operação receba argumentos de diferentes tipos Um parâmetro declarado como valor de um tipo... ... pode receber valores do subtipo. Mecanismo que permite que um método receba argumentos de diferentes classes: Um parâmetro declarado como instância da superclasse... ... pode receber instâncias da subclasse. Introdução Linguagens de Programação 26 Delegação X Herança Delegação: tem-um Quando se quer as características de uma classe, mas não seus campos e métodos; O componente auxilia na implementação da funcionalidade da subclasse. Herança: é-um Além de usar as características da superclasse, a subclasse também usa campos e/ou métodos da superclasse. Introdução Linguagens de Programação 27