Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Programação Modular | Polimorfismo

Programação Modular | Polimorfismo

Slides utilizados em aula na disciplina Programação Modular do Instituto de Ciências Exatas e Informática - Sistemas de Informação. Pontifícia Universidade Católica de Minas Gerais - Unidade Barreiro, 1º Semestre 2015.

Eduardo Miranda

March 11, 2015
Tweet

More Decks by Eduardo Miranda

Other Decks in Education

Transcript

  1. polimorfismo O termo polimorfismo é originário do grego e significa

    "muitas formas" (poli = muitas, morphos = formas). Em linguagens de programação o polimorfismo costuma ser considerado o terceiro pilar da programação orientada a objetos, depois do encapsulamento e herança. Este termo se refere à possibilidade de criar código capaz de operar sobre valores de tipos distintos.
  2. polimorfismo Existem diferentes tipos de polimorfismo. Uma classificação foi proposta

    por Luca Cardelli e Peter Wegner (1985)1 . 1 http://lucacardelli.name/papers/onunderstanding.a4.pdf Polimorfismo Ad-hoc Universal Coerção Sobrecarga Paramétrico Inclusão
  3. coerção Coerção significa conversão implícita de tipos. Veja o exemplo

    abaixo em C++. #include <iostream> #include <string> using namespace std; int main() { int i; char c = 'a'; float x; i = c; c = i + 1; x = i; i = x / 7; cout << i; return 0; }
  4. coerção Coerção significa conversão implícita de tipos. Veja o exemplo

    abaixo em C++. #include <iostream> #include <string> using namespace std; int main() { int i; char c = 'a'; float x; i = c; c = i + 1; x = i; i = x / 7; cout << i; return 0; } Saída correta: 13
  5. coerção Coerção significa conversão implícita de tipos. Veja o exemplo

    abaixo em C#. int a = 2, b = 3; float x = 1.5F, y = 3.4F; a = a + b; x = x + y; x = a + y;
  6. sobrecarga (overloading) public static void Main() { Complex num1 =

    new Complex(2,3); Complex num2 = new Complex(3,4); // Soma dois números complexos através do operador sobrecarregado (+) Complex sum = num1 + num2; // Imprime os números e a some usando o método ToString sobrescrito Console.WriteLine("Primeiro número complexo: {0}",num1); Console.WriteLine("Segundo número complexo: {0}",num2); Console.WriteLine("A soma dos dois números complexos: {0}",sum); } } public struct Complex { public int real; public int imaginary; public Complex(int real, int imaginary) { this.real = real; this.imaginary = imaginary; } // Declara qual operador a ser sobrecarregado (+) public static Complex operator +(Complex c1, Complex c2) { return new Complex(c1.real + c2.real, c1.imaginary + c2. imaginary); } // Sobrescreve o método ToString para mostrar o número complexo de forma apropriada public override string ToString() { return(String.Format("{0} + {1}i", real, imaginary)); } Saída correta: Primeiro número complexo: 2 + 3i Segundo número complexo: 3 + 4i A soma dos dois números complexos: 5 + 7i
  7. paramétrico "No polimorfismo paramétrico é possível construir abstrações de dados

    e controle que atuam uniformemente sobre valores de vários tipos. A principal característica desse polimorfismo é a parametrização das estruturas de dados e subprogramas com relação ao tipo do elemento sobre o qual operam." (Flávio Varejão, 2004) Em C# isso é possível através de classes e métodos genéricos. Classes genéricas encapsulam as operações que não são específicos para um determinado tipo de dados. O uso mais comum para as classes genéricas é com coleções como listas encadeadas, tabelas hash, pilhas, filas, árvores, e assim por diante. As operações como adição e remoção de itens da coleção são realizados basicamente da mesma maneira, independentemente do tipo de dados armazenados.
  8. método genérico em C# class Program { static void Troca<T>(ref

    T lhs, ref T rhs) { T temp; temp = lhs; lhs = rhs; rhs = temp; } static void Main(string[] args) { int a = 1; int b = 2; Troca<int>(ref a, ref b); System.Console.WriteLine(a + " " + b); } }
  9. método genérico em C# class Program { static void Troca<T>(ref

    T lhs, ref T rhs) { T temp; temp = lhs; lhs = rhs; rhs = temp; } static void Main(string[] args) { int a = 1; int b = 2; Troca<int>(ref a, ref b); System.Console.WriteLine(a + " " + b); } } Você também pode omitir o argumento de tipo e o compilador conseguirá inferir. Esta chamada poderia ser assim então: Troca(ref a, ref b);
  10. paramétrico private Node head; public GenericList() { head = null;

    } public void AddHead(T t) { Node n = new Node(t); n.Next = head; head = n; } public IEnumerator<T> GetEnumerator() { Node current = head; while (current != null) { yield return current.Data; current = current.Next; } } } public class GenericList<T> { private class Node { public Node(T t) { next = null; data = t; } private Node next; public Node Next { get { return next; } set { next = value; } } private T data; public T Data { get { return data; } set { data = value; } } } class TestGenericList { static void Main() { GenericList<int> list = new GenericList<int>(); for (int x = 0; x < 10; x++) { list.AddHead(x); } foreach (int i in list) { System.Console.Write(i + " "); } System.Console.WriteLine("\nPronto"); } }
  11. paramétrico private Node head; public GenericList() { head = null;

    } public void AddHead(T t) { Node n = new Node(t); n.Next = head; head = n; } public IEnumerator<T> GetEnumerator() { Node current = head; while (current != null) { yield return current.Data; current = current.Next; } } } public class GenericList<T> { private class Node { public Node(T t) { next = null; data = t; } private Node next; public Node Next { get { return next; } set { next = value; } } private T data; public T Data { get { return data; } set { data = value; } } } Note que T está disponível para a classe Node aninhada. Quando GenericList <t> for instanciada com um tipo concreto, por exemplo: GenericList <int> cada ocorrência de T será substituída por int. class TestGenericList { static void Main() { GenericList<int> list = new GenericList<int>(); for (int x = 0; x < 10; x++) { list.AddHead(x); } foreach (int i in list) { System.Console.Write(i + " "); } System.Console.WriteLine("\nPronto"); } } Saída correta: 9 8 7 6 5 4 3 2 1 0 Done
  12. inclusão "O polimorfismo de inclusão é característico de linguagens orientadas

    a objetos. Ele se baseia no uso de uma hierarquia de tipos para criar abstrações de dados e controle polimórficas. A ideia fundamental do polimorfismo por inclusão é que elementos dos subtipos são também elementos do super tipo (daí o nome inclusão). Assim, as abstrações formadas a partir do supertipo podem também envolver elementos dos subtipos." (Flávio Varejão, 2004)
  13. inclusão No livro Linguagens de Programação: Java, C e C++

    e Outras - Conceitos e Técnicas o autor divide polimorfismo por inclusão nos seguintes subtópicos: • Herança; ◦ Especificador de acesso para classes herdeiras; ◦ Inicialização de atributos com herança; ◦ Sobrescrição; • Identificação dinâmica de tipos; ◦ Ampliação (upcasting); ◦ Estreitamento (downcasting); ◦ Amarração tardia de tipos; ◦ Classes abstratas; • Herança múltipla; • Metaclasses;
  14. No livro Linguagens de Programação: Java, C e C++ e

    Outras - Conceitos e Técnicas o autor divide polimorfismo por inclusão nos seguintes subtópicos: • Herança; ◦ Especificador de acesso para classes herdeiras; ◦ Inicialização de atributos com herança; ◦ Sobrescrição; • Identificação dinâmica de tipos; ◦ Ampliação (upcasting); ◦ Estreitamento (downcasting); ◦ Amarração tardia de tipos; ◦ Classes abstratas; • Herança múltipla; • Metaclasses; inclusão C# não suporta herança múltipla nem metaclasses.
  15. Estreitamento (downcasting) Estreitamento converte um objeto de um tipo geral

    de um tipo mais especializado. Ou seja, é o movimento de objetos na sua linha de ancestrais no sentido da superclasse para a subclasse.
  16. estreitamento ContaBancaria cb1, cb2 = new ContaBancaria("João", 250.00, 0.01); ConcaCorrente

    cc1, cc2 = new ConcaCorrente("Bento", 100.00); cb1 = cc2; cc1 = cb2; cc1 = (ContaCorrente)cb2; cc1 = (ContaCorrente)cb1;
  17. estreitamento ContaBancaria cb1, cb2 = new ContaBancaria("João", 250.00, 0.01); ConcaCorrente

    cc1, cc2 = new ConcaCorrente("Bento", 100.00); cb1 = cc2; // upcasting legal // cc1 = cb2; // downcasting ilegal. Descoberto em tempo de compilação. // cc1 = (ContaCorrente)cb2; // downcasting ilegal. Descoberto em tempo de execução. cc1 = (ContaCorrente)cb1; // downcasting legal. cb1 já refere ao tipo Conta Corrente
  18. estreitamento ContaBancaria cb1, cb2 = new ContaBancaria("João", 250.00, 0.01); ConcaCorrente

    cc1, cc2 = new ConcaCorrente("Bento", 100.00); cb1 = cc2; // upcasting legal // cc1 = cb2; // downcasting ilegal. Descoberto em tempo de compilação. // cc1 = (ContaCorrente)cb2; // downcasting ilegal. Descoberto em tempo de execução. cc1 = (ContaCorrente)cb1; // downcasting legal. cb1 já refere ao tipo Conta Corrente Como resolver isso?
  19. estreitamento Existem 3 opções no C# para tratar estes casos:

    • typeof : Usado para obter o tipo System.Type de um objeto que é especificado em tempo de compilação. • GetType : O tipo exato em tempo de execução da instância atual. • is : Verifica se um objeto é compatível com um determinado tipo. Retorna true se a instância pertence a árvore de herança. Avalia a compatibilidade do tipo em tempo de execução.
  20. typeof, GetType, is class Animal { } class Dog :

    Animal { } class Program { public static void PrintTypes(Animal a) { Console.WriteLine(a.GetType()); Console.WriteLine(typeof(Animal)); Console.WriteLine(typeof(Dog)); Console.WriteLine(); Console.WriteLine(a is Animal); Console.WriteLine(a.GetType() == typeof(Animal)); Console.WriteLine(a.GetType() == typeof(Dog)); } static void Main(string[] args) { Dog spot = new Dog(); PrintTypes(spot); } } Saída correta: typeofGetTypeIs.Dog typeofGetTypeIs.Animal typeofGetTypeIs.Dog True False True
  21. Animal pet1 = new Animal(); Animal pet1 = new Gato();

    Animal pet2 = new Cachorro(); Gato cat1 = new Gato(); Gato dog1 = new Gato(); Gato cat2 = new Animal(); Cachorro dog1 = new Cachorro(); Cachorro dog2 = new Gato(); Cachorro dog3 = new Animal(); Cachorro cat4 = new Cachorro(); public class Animal { private String nome; public String getName(){ return this.nome; } public virtual void FazerBarulho() { } } public class Gato : Animal { public override void FazerBarulho(){ Console.WriteLine("Miau!"); } } public class Cachorro : Animal { public override void FazerBarulho() { Console.WriteLine("Auau!"); } } exercício
  22. Animal pet1 = new Animal(); ✓ Animal pet1 = new

    Gato(); Animal pet2 = new Cachorro(); Gato cat1 = new Gato(); Gato dog1 = new Gato(); Gato cat2 = new Animal(); Cachorro dog1 = new Cachorro(); Cachorro dog2 = new Gato(); Cachorro dog3 = new Animal(); Cachorro cat4 = new Cachorro(); public class Animal { private String nome; public String getName(){ return this.nome; } public virtual void FazerBarulho() { } } public class Gato : Animal { public override void FazerBarulho(){ Console.WriteLine("Miau!"); } } public class Cachorro : Animal { public override void FazerBarulho() { Console.WriteLine("Auau!"); } } exercício
  23. Animal pet1 = new Animal(); ✓ Animal pet1 = new

    Gato(); ✓ Animal pet2 = new Cachorro(); Gato cat1 = new Gato(); Gato dog1 = new Gato(); Gato cat2 = new Animal(); Cachorro dog1 = new Cachorro(); Cachorro dog2 = new Gato(); Cachorro dog3 = new Animal(); Cachorro cat4 = new Cachorro(); public class Animal { private String nome; public String getName(){ return this.nome; } public virtual void FazerBarulho() { } } public class Gato : Animal { public override void FazerBarulho(){ Console.WriteLine("Miau!"); } } public class Cachorro : Animal { public override void FazerBarulho() { Console.WriteLine("Auau!"); } } exercício
  24. Animal pet1 = new Animal(); ✓ Animal pet1 = new

    Gato(); ✓ Animal pet2 = new Cachorro(); ✓ Gato cat1 = new Gato(); Gato dog1 = new Gato(); Gato cat2 = new Animal(); Cachorro dog1 = new Cachorro(); Cachorro dog2 = new Gato(); Cachorro dog3 = new Animal(); Cachorro cat4 = new Cachorro(); public class Animal { private String nome; public String getName(){ return this.nome; } public virtual void FazerBarulho() { } } public class Gato : Animal { public override void FazerBarulho(){ Console.WriteLine("Miau!"); } } public class Cachorro : Animal { public override void FazerBarulho() { Console.WriteLine("Auau!"); } } exercício
  25. Animal pet1 = new Animal(); ✓ Animal pet1 = new

    Gato(); ✓ Animal pet2 = new Cachorro(); ✓ Gato cat1 = new Gato(); ✓ Gato dog1 = new Gato(); Gato cat2 = new Animal(); Cachorro dog1 = new Cachorro(); Cachorro dog2 = new Gato(); Cachorro dog3 = new Animal(); Cachorro cat4 = new Cachorro(); public class Animal { private String nome; public String getName(){ return this.nome; } public virtual void FazerBarulho() { } } public class Gato : Animal { public override void FazerBarulho(){ Console.WriteLine("Miau!"); } } public class Cachorro : Animal { public override void FazerBarulho() { Console.WriteLine("Auau!"); } } exercício
  26. Animal pet1 = new Animal(); ✓ Animal pet1 = new

    Gato(); ✓ Animal pet2 = new Cachorro(); ✓ Gato cat1 = new Gato(); ✓ Gato dog1 = new Gato(); ✓ Gato cat2 = new Animal(); Cachorro dog1 = new Cachorro(); Cachorro dog2 = new Gato(); Cachorro dog3 = new Animal(); Cachorro cat4 = new Cachorro(); public class Animal { private String nome; public String getName(){ return this.nome; } public virtual void FazerBarulho() { } } public class Gato : Animal { public override void FazerBarulho(){ Console.WriteLine("Miau!"); } } public class Cachorro : Animal { public override void FazerBarulho() { Console.WriteLine("Auau!"); } } exercício
  27. Animal pet1 = new Animal(); ✓ Animal pet1 = new

    Gato(); ✓ Animal pet2 = new Cachorro(); ✓ Gato cat1 = new Gato(); ✓ Gato dog1 = new Gato(); ✓ Gato cat2 = new Animal(); X Cachorro dog1 = new Cachorro(); Cachorro dog2 = new Gato(); Cachorro dog3 = new Animal(); Cachorro cat4 = new Cachorro(); public class Animal { private String nome; public String getName(){ return this.nome; } public virtual void FazerBarulho() { } } public class Gato : Animal { public override void FazerBarulho(){ Console.WriteLine("Miau!"); } } public class Cachorro : Animal { public override void FazerBarulho() { Console.WriteLine("Auau!"); } } exercício
  28. Animal pet1 = new Animal(); ✓ Animal pet1 = new

    Gato(); ✓ Animal pet2 = new Cachorro(); ✓ Gato cat1 = new Gato(); ✓ Gato dog1 = new Gato(); ✓ Gato cat2 = new Animal(); X Cachorro dog1 = new Cachorro(); ✓ Cachorro dog2 = new Gato(); Cachorro dog3 = new Animal(); Cachorro cat4 = new Cachorro(); public class Animal { private String nome; public String getName(){ return this.nome; } public virtual void FazerBarulho() { } } public class Gato : Animal { public override void FazerBarulho(){ Console.WriteLine("Miau!"); } } public class Cachorro : Animal { public override void FazerBarulho() { Console.WriteLine("Auau!"); } } exercício
  29. Animal pet1 = new Animal(); ✓ Animal pet1 = new

    Gato(); ✓ Animal pet2 = new Cachorro(); ✓ Gato cat1 = new Gato(); ✓ Gato dog1 = new Gato(); ✓ Gato cat2 = new Animal(); X Cachorro dog1 = new Cachorro(); ✓ Cachorro dog2 = new Gato(); X Cachorro dog3 = new Animal(); Cachorro cat4 = new Cachorro(); public class Animal { private String nome; public String getName(){ return this.nome; } public virtual void FazerBarulho() { } } public class Gato : Animal { public override void FazerBarulho(){ Console.WriteLine("Miau!"); } } public class Cachorro : Animal { public override void FazerBarulho() { Console.WriteLine("Auau!"); } } exercício
  30. Animal pet1 = new Animal(); ✓ Animal pet1 = new

    Gato(); ✓ Animal pet2 = new Cachorro(); ✓ Gato cat1 = new Gato(); ✓ Gato dog1 = new Gato(); ✓ Gato cat2 = new Animal(); X Cachorro dog1 = new Cachorro(); ✓ Cachorro dog2 = new Gato(); X Cachorro dog3 = new Animal(); X Cachorro cat4 = new Cachorro(); public class Animal { private String nome; public String getName(){ return this.nome; } public virtual void FazerBarulho() { } } public class Gato : Animal { public override void FazerBarulho(){ Console.WriteLine("Miau!"); } } public class Cachorro : Animal { public override void FazerBarulho() { Console.WriteLine("Auau!"); } } exercício
  31. Animal pet1 = new Animal(); ✓ Animal pet1 = new

    Gato(); ✓ Animal pet2 = new Cachorro(); ✓ Gato cat1 = new Gato(); ✓ Gato dog1 = new Gato(); ✓ Gato cat2 = new Animal(); X Cachorro dog1 = new Cachorro(); ✓ Cachorro dog2 = new Gato(); X Cachorro dog3 = new Animal(); X Cachorro cat4 = new Cachorro(); ✓ public class Animal { private String nome; public String getName(){ return this.nome; } public virtual void FazerBarulho() { } } public class Gato : Animal { public override void FazerBarulho(){ Console.WriteLine("Miau!"); } } public class Cachorro : Animal { public override void FazerBarulho() { Console.WriteLine("Auau!"); } } exercício
  32. exercício public class Animal { private String nome; public String

    getName(){ return this.nome; } public virtual void FazerBarulho() { Console.WriteLine("..."); } } public class Gato : Animal { public override void FazerBarulho(){ Console.WriteLine("Miau!"); } } public class Cachorro : Animal { public override void FazerBarulho() { Console.WriteLine("Auau!"); } } static void Main(string[] args) { Gato cat1 = new Gato(); cat1.FazerBarulho(); Cachorro dog1 = new Cachorro(); dog1.FazerBarulho(); Animal pet1 = new Gato(); pet1.FazerBarulho(); Animal pet2 = new Cachorro(); pet2.FazerBarulho(); }
  33. exercício public class Animal { private String nome; public String

    getName(){ return this.nome; } public virtual void FazerBarulho() { Console.WriteLine("..."); } } public class Gato : Animal { public override void FazerBarulho(){ Console.WriteLine("Miau!"); } } public class Cachorro : Animal { public override void FazerBarulho() { Console.WriteLine("Auau!"); } } static void Main(string[] args) { Gato cat1 = new Gato(); cat1.FazerBarulho(); Cachorro dog1 = new Cachorro(); dog1.FazerBarulho(); Animal pet1 = new Gato(); pet1.FazerBarulho(); Animal pet2 = new Cachorro(); pet2.FazerBarulho(); } Saída correta: Miau! Auau! Miau! Auau!
  34. referência Flávio Miguel Varejão, Linguagens de Programação: Java, C e

    C++ e Outras - Conceitos e Técnicas. Rio de Janeiro. Elsevier (2004), 334 páginas.