Linguagens de Programação Conceitos e Técnicas Polimorfismo Prof. Isabel Cafezeiro [email protected] http://www.dcc.ic.uff.br/~isabel *Adaptação das transparências do professor Flávio Varejão Polimorfismo Código capaz de operar sobre valores de tipos diferentes. Sistema de tipos: mais polimórfico, mais reusável Polimorfismo Linguagens de Programação 2 Sistemas de Tipos Verificação de Tipos: Operandos compatíveis com operador? Verificação a priori, quando possível, é recomendada: evita a realização de operações sem sentido LPs podem possibilitar ou não a realização de uma ampla verificação de tipos Em C: ponteiro para float pode apontar para vetor de caracteres. Postura fraca de verificação de tipos. Em ADA e JAVA: verificação de tipos extremamente ampla. Polimorfismo Linguagens de Programação 3 Sistemas de Tipos Verificação de Tipos Em geral, o quanto antes melhor Nem sempre isso é possível ou desejável. Exemplo: LOO’s o objeto pode mudar de tipo durante a execução. Brechas no sistema de tipos impedem a verificação. Exemplo: Registro variante em PASCAL e MODULA-2 Polimorfismo Linguagens de Programação 4 Sistemas de Tipos Verificação de Tipos Estática Tempo de Compilação (Análise textual) Dinâmica Tempo de Execução Mista Polimorfismo Linguagens de Programação 5 Sistemas de Tipos Verificação Estática de Tipos Confiabilidade redigibilidade C faz poucas verificações MODULA-2 faz muitas verificações C e Modula-2 não fazem verificações em tempo de execução. Polimorfismo Linguagens de Programação 6 Sistemas de Tipos Verificação Dinâmica de Tipos Informações de tipos associadas aos valores, e não às operações Variáveis,parâmetros: não têm tipo. Podem designar valores de diferentes tipos em pontos distintos da execução. Verificação dos tipos de operandos imediatamente antes da execução da operação. Exemplos: LISP, BASIC, APL, SMALLTALK Polimorfismo Linguagens de Programação 7 Sistemas de Tipos Verificação Mista de Tipos Muitas verificações em tempo de compilação. Algumas verificações em tempo de execução. Exemplos: Índices de vetor em pascal; Tipos de objetos em LOO’s Exemplos: C++, ADA e JAVA,PASCAL Polimorfismo Linguagens de Programação 8 Sistemas de Tipos Linguagens Fortemente Tipadas Programa não executa se tiver erros de tipo. Conceito muito em voga nos anos 80 e 90. Verificação estática tanto quanto o possível e a verificação dinâmica quando for necessário. ALGOL-68 é fortemente tipada PASCAL, ADA e JAVA são quase fortemente tipadas. registro variante Polimorfismo Linguagens de Programação 9 Sistemas de Tipos Verificação Dinâmica ou Estática? estática Flexibilidade Confiabilidade Eficiência dinâmica Flexibilidade em Lisp (define segundo(lambda(l) (car (cdr l)))) (segundo ́(1 2 3)) (segundo ́( ́(1 2 3) (4 5 6))) (segundo ́(“manga” “abacaxi” 5 6)) Polimorfismo lista de números lista de listas lista de strings e números Linguagens de Programação 10 Sistemas de Tipos Inferência de Tipos A LP “deduz” o tipo dos operandos para que uma operação possa ser aplicada Verificação Estática nem sempre é necessário declarar tipos par (n) { retorna (resto(n, 2) = 0); } ... par (3); ... Verificação Dinâmica Polimorfismo Linguagens de Programação 11 Sistemas de Tipos Inferência de Tipos redigibilidade legibilidade facilidade de depuração complexidade do compilador Exemplos: HASKELL, ML Polimorfismo Linguagens de Programação 12 Sistemas de Tipos Conversão Implícita (coerção) Situações nas quais se aplica um operando de tipo diferente do esperado por uma operação C faz muitas coerções (pode camuflar um erro) MODULA-2 faz poucas coerções Pascal, JAVA adotam postura intermediária Necessário estabelecer regras nas quais a conversão é possível Polimorfismo Linguagens de Programação 13 Sistemas de Tipos Regras para Coerção: Duas abordagens Baseadas em inclusão de tipos Baseadas em equivalência de tipos Estrutural Nominal Polimorfismo Linguagens de Programação 14 Sistemas de Tipos Inclusão de Tipos T = <C,O>, T’ = <C’,O’>, T T’ sse C C’ Coerção baseada em Inclusão de Tipos Permitida se os valores do tipo do operando também são valores do tipo esperado pela operação T T’ tipo do operando Polimorfismo tipo da operação Linguagens de Programação 15 Sistemas de Tipos Equivalência de Tipos Nominal Equivalentes se e somente se possuem o mesmo nome Estrutural T e T’ são primitivos: T = A x B e T’= A’ x B’: T = A + B e T’= A’ + B’: T = A B e T’= A’ B’: Polimorfismo T T’ sse T = T’ T T’ sse A A’ e B B’ T T’ sse A A’ e B B’ T T’ sse A A’ e B B’ Linguagens de Programação 16 Sistemas de Tipos Estrutural X Nominal typedef float quilometros; typedef float milhas; quilometros converte (milhas m) { return 1.6093 * m; } main() { milhas m = 200; quilometros q = converte(m); m = converte(q); // inválido em equivalência nominal } C adota estrutural neste caso Polimorfismo Linguagens de Programação 17 Sistemas de Tipos Sistemas de tipos: Monomórficos Todas constantes, variáveis e subprogramas devem ser definidos com um tipo específico. Polimórficos Constantes, variáveis e subprogramas podem ser definidas com tipos diversos. Polimorfismo Linguagens de Programação 18 Sistemas de Tipos Sistemas de tipos Monomórficos simplicidade reusabilidade redigibilidade Exemplos: PASCAL, MODULA-2 Limitação: Muitos algoritmos e estruturas de dados são inerentemente genéricos Algoritmo para ordenação: tipo do elemento precisa ter operação de comparação Conjuntos e suas operações Polimorfismo Linguagens de Programação 19 Sistemas de Tipos Sistemas de Tipos Monomórficos Nenhuma LP é totalmente monomórfica PASCAL: read, readln, write, writeln e eof PASCAL, MODULA-2: ‘+’ atua sobre diversos tipos Linguagens monomórficas exigem que se crie representação e operações distintas para cada tipo de elemento Lista de inteiros, lista de cadeia de caracteres, etc Polimorfismo Linguagens de Programação 20 Sistemas de Tipos Sistemas de Tipos Polimórficos Estruturas de dados e algoritmos podem atuar sobre elementos de tipos diversos Subprogramas polimórficos: parâmetros (e, no caso de funções, o tipo de retorno) podem assumir valores de mais de um tipo. Tipos de dados polimórficos: operações são aplicáveis a valores de mais de um tipo. Em C void* possibilita a criação de variáveis e parâmetros cujos valores podem ser ponteiros para tipos quaisquer possibilita a construção de estruturas de dados genéricas funções com lista de parâmetros variável. Polimorfismo Linguagens de Programação 21 Polimorfismo Classificação de Cardelli e Wegner Polimorfismo Capacidade de uma abstração atuar sobre tipos diferentes Oculta a existência de várias implementações; Só se aplica a abstrações de processos Polimorfismo Ad-hoc (aparente) Coerção Sobrecarga Universal Relativo à mesma implementação; Se aplica a abstrações de processos e dados Linguagens de Programação Paramétrico Inclusão 22 Polimorfismo Ad-hoc Se aplica apenas a subprogramas. Aparentemente proporciona reuso do código de implementação do subprograma, mas na realidade não o faz: são criados subprogramas específicos para operar sobre cada tipo admissível. Proporciona reuso do código de chamada dos subprogramas Polimorfismo Linguagens de Programação 23 Polimorfismo Universal Se aplica a subprogramas e estruturas de dados: Estrutura de dados podem incorporar elementos de tipos diversos. Mesmo código de subprograma pode atuar sobre elementos de tipos diversos. Reuso de código na chamada e na implementação. Considerado o verdadeiro polimorfismo. Polimorfismo Linguagens de Programação 24 Polimorfismo Adhoc Coerção: Conversão implícita de tipos Em C void f (float i) { } main() { long num; f (num); } f aparenta lidar com float e long, mas de fato, lida apenas com float. Compilador se encarrega de embutir código para transformar long em float C possui tabela de conversões permitidas Polimorfismo Linguagens de Programação 25 Polimorfismo Adhoc Tipos de Coerção Ampliação Tipo de menor conjunto de valores para tipo de maior conjunto. Operação segura: valor do tipo menor tem correspondente no tipo maior. Estreitamento Tipo de maior conjunto de valores para tipo de menor conjunto. Operação insegura:pode haver perda de informação. Nem sempre é ampliação ou estreitamento Em C: int para unsigned Polimorfismo Linguagens de Programação 26 Polimorfismo Adhoc Coerção: Polimorfismo aparente main() { int w = 3; float x; float y = 5.2; x = x + y; x = x + w; } Polimorfismo // x = somafloat (x, y) // x = somafloat (x, inttofloat(w)); Linguagens de Programação 27 Polimorfismo Adhoc Coerção Redigibilidade: evita chamada de funções de conversão Confiabilidade: pode impedir a detecção de certos tipos de erros por parte do compilador main() { int a, b = 2, c = 3; float d; d = a * b; // sem coerção seria: d = (float) (a * b) ; a = b * d; // coerção pode camuflar erro: d no lugar de c! } Polimorfismo Linguagens de Programação 28 Polimorfismo Adhoc Coerção Em ADA e MODULA-2: não há coerções. Em C: muitas coerções. Em JAVA: coerções só para tipos mais amplos. byte a, b = 10, c = 10; int d; d = b; c = (byte) d; a = (byte) (b + c); Polimorfismo Linguagens de Programação 29 Polimorfismo Adhoc Sobrecarga Identificador ou operador é usado para designar duas ou mais operações distintas. Aceitável quando o uso do operador ou identificador não é ambíguo: A operação apropriada pode ser identificada usando-se as informações do contexto de aplicação. Polimorfismo Linguagens de Programação 30 Polimorfismo Adhoc Sobrecarga Em C: Operador – de C pode designar Negações inteiras Negações reais Subtrações inteiras Subtrações reais Polimorfismo int int ou short short ou long long loat float ou double double int x int int float x float float Linguagens de Programação 31 Polimorfismo Adhoc Sobrecarga: Polimorfismo Aparente Sugere que determinada operação ou subprograma pode ser realizada com operandos de tipos diferentes mas não é isso que ocorre main(){ int a = 2, b = 3; float x = 1.5, y = 3.4; a = a + b; // x = x + y; // } Polimorfismo a = somaint (a, b); x = somafloat (x, y); Linguagens de Programação 32 Polimorfismo Adhoc Sobrecarga Em MODULA-2 e C Operadores sobrecarregados Programadores não podem implementar novas sobrecargas de operadores. Não existe qualquer sobrecarga de subprogramas Em PASCAL Existem subprogramas sobrecarregados na biblioteca padrão readln e writeln Programadores não podem implementar novas sobrecargas de subprogramas. Polimorfismo Linguagens de Programação 33 Polimorfismo Adhoc Sobrecarga Em JAVA Sobrecarga em operadores e em subprogramas de suas bibliotecas. Só subprogramas podem ser sobrecarregados pelo programador. Em ADA e C++ Postura mais ampla e ortogonal. Realizam e permitem que programadores realizem sobrecarga de subprogramas e operadores. Não admitem a criação de novos operadores. Sintaxe e precedência não podem ser alteradas. Polimorfismo Linguagens de Programação 34 Polimorfismo Adhoc Sobrecarga em C++ class umValor { Sobrecarga do construtor int v; umValor public: umValor() { v = 0; } Sobrecarga do operador + umValor(int j) { v = j; } const umValor operator+(const umValor& u)const { return umValor(v + u.v); Sobrecarga do operador += } umValor& operator+=(const umValor& u) { v += u.v; return *this; } Polimorfismo Linguagens de Programação 35 Polimorfismo Adhoc Sobrecarga em C++ const umValor& operator++() { // prefixado v++; Sobrecarga do operador ++ return *this; } const umValor operator++(int) { // posfixado umValor antes(v); v++; return antes; } }; Polimorfismo Linguagens de Programação 36 Sobrecarga em C++ main() { int a = 1, b = 2, c = 3; c += a +b; umValor r(1), s(2), t; t += r + s; r = ++s; s = t++; } soma inteiros cria objetos da classe umValor soma umValor como se somasse inteiros Útil na criação de objetos em diferentes contextos Sintaxe esquisita para sobrecarga de ++ e –– Nem todos operadores podem ser sobrecarregados: :: (resolução de escopo), . (seleção de membro), sizeof (tamanho do objeto/tipo) Polimorfismo Linguagens de Programação 37 Polimorfismo Adhoc Sobrecarga Independente de Contexto O Tipo de retorno não pode ser usado para identificar o subprograma a ser chamado. A identificação é dada pela lista de parâmetros diferenciada em número ou tipo dos parâmetros. JAVA e C++ Polimorfismo Linguagens de Programação 38 Polimorfismo Adhoc Sobrecarga Independente de Contexto Em C++ Polimorfismo void f(void) { } void f(float) { } void f(int, int) { } void f(float, float) { } main() { f(); f(2.3); // é double f(4, 5); f(2.2f, 7.3f); // f(3, 5.1f); } Pode gerar ambiguidade quando combinada com coerção Linguagens de Programação 39 Polimorfismo Adhoc Dependente de Contexto O Tipo de retorno pode ser usado para identificar o subprograma a ser chamado. Exige mais esforço dos compiladores Pode provocar erros de ambigüidade ADA Polimorfismo Linguagens de Programação 40 Polimorfismo Adhoc Sobrecarga Dependente de Contexto Em Ada, ‘/’ designa divisão real ou divisão inteira A sobrecarga de ‘/’ gera ambigüidade mesmo sem coerção: function “/” (m,n : integer) return float is begin return float (m) / float (n); end “/”; n : integer; x : float; x := 7.0/2.0; -- calcula 7.0/2.0 = 3.5 float x float float x := 7/2; -- calcula 7/2 = 3.5 int x int float n := 7/2; -- calcula 7/2 = 3 int x int int n := (7/2) / (5/2); -- calcula (7/2)/(5/2) = 3/2 = 1 int x int int x := (7/2) / (5/2); -- erro: ambiguidade (pode ser 1.4 ou 1.5) Polimorfismo Linguagens de Programação 41 Polimorfismo Adhoc Sobrecarga Programas podem ficar mais fáceis de serem lidos e redigidos com a sobrecarga Aumenta a complexidade da LP Pode ser mal utilizado, tendo efeito contrário a legibilidade JAVA não inclui a sobrecarga de operadores por considerá-la capaz de gerar confusões e aumentar a complexidade da LP Polimorfismo Linguagens de Programação 42 Polimorfismo Universal Polimorfismo Paramétrico Abstrações de dados e controle que atuam uniformemente sobre valores de diferentes tipos. Abstrações recebem um parâmetro implícito adicional especificando o tipo sobre o qual elas agem. Exemplo: identidade (inteiro x) retorna inteiro { retorna x; } identidade (T x) retorna T { return x; } T é um parâmetro de tipo: Politipo Polimorfismo Linguagens de Programação 43 Polimorfismo Universal Polimorfismo Paramétrico Politipo: tipo do qual se deriva uma família de tipos. No exemplo, O tipo retornado por identidade será o mesmo usado na chamada x = identidade (3.2); // x receberá um float Tipo de identidade é sua assinatura T T Não existe impedimento em se usar mais de um parâmetro tipo em um politipo U x T T indica que parâmetros podem ser de tipos distintos e que o tipo retornado será o tipo do segundo Polimorfismo Linguagens de Programação 44 Polimorfismo Universal Polimorfismo Paramétrico em C++: template main () { template <class T> T identidade (T x) { return x; } class tData { int d, m, a; }; Polimorfismo } int x; float y; tData d1, d2; x = identidade (1); y = identidade (2.5); d2 = identidade (d1); // y = identidade (d2); Linguagens de Programação 45 Polimorfismo Universal Polimorfismo Paramétrico em C++ Muitas funções são parcialmente genéricas template <class T> T maior (T x, T y) { return x > y ? x : y; } class tData { int d, m, a; }; main ( ) { tData d1, d2; printf ("%d", maior (3, 5)); printf ("%f", maior (3.1, 2.5)); // d1 = maior (d1, d2); } Erro de compilação porque o operador > não está definido para a classe tData Necessário sobrecarregar o operador > para a classe tData Polimorfismo Linguagens de Programação 46 Polimorfismo Universal Polimorfismo Paramétrico em C++ Estruturas de dados parametrizadas: template <class T, int tam> A pilha é parametrizada pelo class tPilha { tipo do elemento e pela T elem[tam]; capacidade máxima. int topo; public: tPilha(void) { topo = -1; } elem é um vetor de tam int vazia (void) { return topo == -1; } componentes do tipo T. void empilha (T); void desempilha (void); T obtemTopo (void); }; Polimorfismo Linguagens de Programação 47 Polimorfismo Universal template <class T, int tam> void tPilha<T, tam>::empilha (T el){ if (topo < tam-1) elem[++topo] = el; } template <class T, int tam> void tPilha<T, tam>::desempilha (void){ if (!vazia()) topo--; } template <class T, int tam> T tPilha<T, tam>::obtemTopo (void) { if (!this->vazia()) return elem[topo]; } Polimorfismo Linguagens de Programação 48 Polimorfismo Universal class tData { int d, m, a; }; Polimorfismo void main () { tData d1, d2; tPilha <int, 3> x; tPilha <tData, 2> y; x.empilha (1); y.empilha (d1); x.empilha (3); y.empilha (d2); while (!x.vazia() || !y.vazia()) { x.desempilha(); y.desempilha(); } } Linguagens de Programação 49 Polimorfismo Universal Polimorfismo Paramétrico em C++ Implementação de template em C++ Só possibilita a reutilização de código fonte: • Não é possível compilar o código usuário separadamente do código de implementação. • O compilador C++ necessita saber quais tipos serão associados ao template – Faz varredura do código usuário – replica todo o código de implementação para cada tipo utilizado • Compilador necessita verificar se o tipo usado é compatível com as operações definidas nas implementações e saber o tamanho a ser alocado Polimorfismo Linguagens de Programação 50 Polimorfismo Universal Polimorfismo Paramétrico em C++ Em ADA Pacotes Genéricos Em JAVA Não possui atualmente Reserva da palavra generic Polimorfismo Linguagens de Programação 51 Polimorfismo Universal Polimorfismo por Inclusão Característico de linguagens orientadas a objetos Hierarquia de tipos Elementos dos subtipos são também elementos do supertipo. Abstrações formadas a partir do supertipo podem também envolver elementos dos seus subtipos Polimorfismo!!! Polimorfismo Linguagens de Programação 52 Polimorfismo Universal Polimorfismo por Inclusão S = (S,Os) é subtipo de T = (T,Ot): S T: Todo valor de S é também um valor de T Ot são aplicáveis ao subtipo S S herda todas as operações do tipo T O Conceito de tipo é implementado através de classes em linguagens orientadas a objetos. Polimorfismo Linguagens de Programação 53 Polimorfismo Universal Herança Herança associa à subclasse uma representação para os objetos dessa classe (os atributos herdados) um conjunto de métodos aplicáveis aos objetos dessa classe (os métodos herdados) A Subclasse pode conter atributos e métodos adicionais, especializando o estado e o comportamento dos objetos da superclasse Polimorfismo Linguagens de Programação 54 Polimorfismo Universal Herança Pessoa nome,idade Pessoa(n,i); AumentarIdade(); Empregado salário Empregado(n,i,s); MudarSalário(s); Polimorfismo Linguagens de Programação 55 Polimorfismo Universal Herança em JAVA public class Pessoa { private String nome; private int idade; public Pessoa (String n, int i) { nome = n; idade = i; } public void aumentarIdade () { idade++; } } Polimorfismo Linguagens de Programação 56 Polimorfismo Universal public class Empregado extends Pessoa { private float salario; public Empregado (String n, int i, float s) { super(n, i); salario = s; } public void mudarSalario (float s) { salario = s; } } Polimorfismo Linguagens de Programação 57 Polimorfismo Universal public class Empresa { public static void main(String[] args) { Pessoa p = new Pessoa (“Denise”, 34); p.aumentarIdade(); Empregado e1 = new Empregado (“Rogerio”, 28, 1000.00); e1.mudarSalario(2000.00); e1.aumentarIdade(); } } Polimorfismo Linguagens de Programação 58 Polimorfismo Universal Vantagens da Herança Aumenta a reusabilidade do código Desnecessário redefinir os atributos e métodos da classe Pessoa na classe Empregado. Herança é polimorfismo universal o método aumentarIdade(), usado para mudar a idade de uma Pessoa, e também aplicado para mudar a idade de um Empregado. Polimorfismo Linguagens de Programação 59 Polimorfismo Universal Sobrescrição Método herdado pode não ser adequado para os objetos das subclasses Pessoa nome,idade Pessoa(n,i); AumentarIdade(); Mecanismo de sobrecarga Empregado salário Empregado(n,i,s); MudarSalário(s); AumentarIdade(); Polimorfismo Linguagens de Programação Sobrescrição 60 Polimorfismo Universal Sobrescrição em JAVA public class Pessoa { private String nome; private int idade; public Pessoa (String n, int i) { nome = n; idade = i; } public void aumentarIdade () { idade++; } } Polimorfismo Linguagens de Programação 61 Polimorfismo Universal public class Empregado extends Pessoa { private float salario; public Empregado (String n, int i, float s) { super(n, i); salario = s; } public void mudarSalario (float s) { salario = s; } public void aumentarIdade () { idade++; salario = salario*1.01; //um por cento de aumento a cada ano } } Polimorfismo Linguagens de Programação 62 Polimorfismo Universal Sobrescrição com extensão de método em Java public void aumentarIdade () { super.aumentarIdade(); salario = salario*1.01; //um por cento de aumento a cada ano } Polimorfismo Linguagens de Programação 63 Polimorfismo Universal Identificação Dinâmica de Tipos útil em situações nas quais o programador desconhece o tipo verdadeiro de um objeto permite elaboração de trechos de código nos quais métodos invocados por um mesmo referenciador de objetos se comportam de maneira diferenciada. Polimorfismo Linguagens de Programação 64 Polimorfismo Universal Ampliação ou Upcast Instância: objetos da classe Membro: instâncias da classe e subclasses Exemplo: X Y Polimorfismo declara-se x, objeto da classe X declara-se y, objeto da classe Y instâncias da classe X: x instâncias da classe Y: y membros da classe X: x,y membros da classe Y: y Linguagens de Programação 65 Polimorfismo Universal Ampliação ou Upcast Movimento de objetos da subclasse para a superclasse Exemplo x := y É a possibilidade de uma instância da subclasse aparecer, quando um membro da superclasse é solicitado. Polimorfismo Linguagens de Programação 66 Ampliação em JAVA public class Empresa { public void paga (Pessoa pes) {} public void contrata (Empregado emp) {} public static void main(String[] args) { Pessoa p = new Pessoa ("Lucas", 30); Empregado e = new Empregado ("Luis", 23, 1500.00); p = e; // e = p; Empresa c = new Empresa(); c.paga(e); // c.contrata(p); } } Polimorfismo Linguagens de Programação 67 Ampliação em C++ Só através de ponteiros ou referências Pessoa p, *q; Empregado e, *r; q = r; // r = q; // p = e; // e = p; Limitação como consequência do mecanismo de cópia de objetos utilizado pela operação de atribuição e para passagem de parâmetros por valor Polimorfismo Linguagens de Programação 68 Amarração Tardia de Tipos Definição dinâmica do método a ser executado Polimorfismo Depende do objeto que invoca o método class Pessoa { String nome; int idade; public Pessoa (String n, int i) { nome = n; idade = i; } public void aumentaIdade () { idade++; } public void imprime(){ System.out.print(nome + " , " + idade); } } Linguagens de Programação 69 Amarração Tardia de Tipos class Empregado extends Pessoa { float salario; Empregado (String n, int i, float s) { super(n, i); salario = s; } public void imprime(){ super.imprime(); System.out.print(" , " + salario); } } Polimorfismo Linguagens de Programação 70 Amarração Tardia de Tipos public class Empresa { public static void main(String[] args) { Pessoa p = new Empregado (“Rogerio”, 28, 1000.00); p.aumentaIdade(); p.imprime(); } } Menos eficiente que amarração estática Polimorfismo Linguagens de Programação 71 Amarração Tardia de Tipos pclasse nome:“Rogerio” p idade: 28 PESSOA salario: 1000.00 psuper aumentarIdade imprime EMPREGADO psuper imprime Polimorfismo Linguagens de Programação 72 Amarração Tardia x Amarração Estática em C++ Todas chamadas utilizam amarração tardia em JAVA Em C++ o implementador da classe pode decidir se deseja o uso de amarração tardia ou não para cada método da classe Visa não comprometer a eficiência de execução desnecessariamente Uso da palavra virtual class Pessoa { public: void ler(){} virtual void imprimir() {} }; Polimorfismo Linguagens de Programação 73 Amarração Tardia de Tipos Possibilita a criação polimorfismo universal de código usuário class Militar { void operacao(){} } class Exercito extends Militar { void operacao(){System.out.println(“Marchar”);} } class Marinha extends Militar { void operacao(){System.out.println(“Navegar”);} } class Aeronautica extends Militar { void operacao(){System.out.println(“Voar”);} } Polimorfismo Linguagens de Programação com 74 Amarração Tardia de Tipos public class Treinamento { public static void treinar(Militar[] m) { for (int i = 0; i < m.length; i++) { m[i].operacao(); } } public static void main (String[] args) { Militar[] m = new Militar[] { new Exercito(), new Marinha(), new Aeronautica(), new Militar() } treinar(m); } } Polimorfismo Linguagens de Programação 75 Composição X Herança Composição: tem-um Quando se quer as características de uma classe, mas não sua interface Objeto é utilizado para implementar a funcionalidade da nova classe Herança: é-um Além de usar as características, a classe herdeira também usa a interface da classe herdada Polimorfismo Linguagens de Programação 76 Herança Múltipla Pilha: fifo Fila: lifo Filha Polimorfismo Linguagens de Programação 77 Herança Múltipla LPs com herança múltipla Problemas X x() Conflito de Nomes Herança Repetida Pilha mostra() Pilha x() Fila mostra() Fila x() Filha x() x() ??? Filha ?? Polimorfismo Linguagens de Programação 78 Herança Múltipla Interfaces: Classes abstratas que possuem apenas métodos abstratos Na Interface: Métodos são implicitamente abstract e public Campos são implicitamente static e final Não possuem construtores Polimorfismo Linguagens de Programação assim como as classes abstratas, as interfaces não podem ser instanciadas. 79 Herança Múltipla em JAVA Não permite herança múltipla de classes Usa o conceito de interfaces para permitir subtipagem múltipla interface Aluno { void estuda(); void estagia(); } class Graduando implements Aluno { public void estuda() {} public void estagia() {} } Polimorfismo Linguagens de Programação 80 Herança Múltipla em JAVA interface Cirurgiao { void opera(); } interface Neurologista { void consulta(); } class Medico { public void consulta() {} } class NeuroCirurgiao extends Medico implements Cirurgiao, Neurologista { public void opera() { } } public class Hospital { static void plantãoCirurgico (Cirurgiao x) { x.opera(); } static void atendimentoGeral (Medico x) { x.consulta(); } static void neuroAtendimento (Neurologista x) { x.consulta(); } static void neuroCirurgia (NeuroCirurgiao x) { x.opera(); } Polimorfismo Linguagens de Programação 81 Herança Múltipla em JAVA public static void main(String[ ] args) { NeuroCirurgiao doutor = new NeuroCirurgiao(); plantãoCirurgico(doutor); atendimentoGeral(doutor); neuroAtendimento(doutor); neuroCirurgia(doutor); } } Não existem problemas de conflito de nomes e herança repetida Dificulta a reutilização de código pois limita a herança aos protótipos dos métodos Polimorfismo Linguagens de Programação 82