O que é polimorfismo, para que serve e como é usado?

564

O que é polimorfismo, para que serve e como é usado?

UnkwnTech
fonte
19
@ John: +1 Concordo que é um fenômeno muito interessante. Tenho certeza de que a Unkwntech não é a única pessoa qualificada e capaz a ter lacunas no que os outros considerariam um vocabulário fundamental. Apenas mostra que a programação é um assunto muito amplo.
AnthonyWJones
9
Ele pode usá-lo, mas não dê um nome.
Aiden Sino
10
@Aamir: Não tenho certeza de que seja razoável supor que alguém com 8k conheça todos os fundementals em todas as áreas da programação. Também não acho que isso indique que o sistema de reputação seja imperfeito. Alguém pode ganhar uma reputação considerável fazendo muitas boas perguntas. Eu acho que nossa resposta natural a essa revelação simplesmente demonstra que nós (programadores) temos uma tendência natural de ser um pouco tacanha (não é uma coisa ruim quando precisamos ser realmente bons em alguma área técnica específica) e isso tem suas desvantagens.
AnthonyWJones
43
Vocês parecem ter uma visão muito limitada da programação. Conheço caras que estão desenvolvendo sistemas embarcados que não têm conhecimento (ou precisam) de conceitos de OO. O resumo deles é extrair todo o último átomo de desempenho do código e é isso - o código no qual eles trabalham nunca entra no mundo dos objetos e, por sorte, estão perto o suficiente da aposentadoria para que não precisem se preocupar. aprendendo novos conceitos, como objetos, polimorfismo e nomes de variáveis ​​com mais de duas letras :-) #
214
29
Como é que você aprende alguma coisa? Ninguém veio a este mundo conhecendo o PHP OOP e os padrões de design; portanto, em algum momento , todos vocês tiveram que aprender, na faculdade, uma resposta aqui, etc. "e, em vez disso, considere que eles estão aqui querendo aprender, o que é uma coisa boa e o objetivo deste site. Use seu tempo ajudando-os, pois tenho certeza de que você já foi ajudado no passado. Se ao longo da história do homem, em vez de compartilhar o conhecimento, a resposta foi "O que ha você não sabe o que ..?!?" Nós todos ainda estar na idade das trevas ..
James

Respostas:

544

Se você pensar nas raízes gregas do termo, ele deve se tornar óbvio.

  • Poli = muitos: polígono = vários lados, poliestireno = muitos estirenos (a) , poliglota = muitos idiomas e assim por diante.
  • Morph = mudança ou forma: morfologia = estudo da forma biológica, Morfeu = o deus grego dos sonhos capaz de assumir qualquer forma.

Portanto, o polimorfismo é a capacidade (em programação) de apresentar a mesma interface para diferentes formas subjacentes (tipos de dados).

Por exemplo, em muitos idiomas, números inteiros e flutuantes são implicitamente polimórficos, pois você pode adicionar, subtrair, multiplicar e assim por diante, independentemente do fato de os tipos serem diferentes. Eles raramente são considerados objetos no termo usual.

Mas, da mesma maneira, uma classe como BigDecimalou RationalouImaginary também pode fornecer essas operações, mesmo que elas operem em diferentes tipos de dados.

O exemplo clássico é a Shapeclasse e todas as classes que podem herdar dela (quadrado, círculo, dodecaedro, polígono irregular, splat e assim por diante).

Com o polimorfismo, cada uma dessas classes terá diferentes dados subjacentes. Uma forma de ponto precisa de apenas duas coordenadas (supondo que esteja em um espaço bidimensional, é claro). Um círculo precisa de um centro e raio. Um quadrado ou retângulo precisa de duas coordenadas para os cantos superior esquerdo e inferior direito e (possivelmente) uma rotação. Um polígono irregular precisa de uma série de linhas.

Ao tornar a classe responsável por seu código e por seus dados, você pode obter polimorfismo. Neste exemplo, toda classe teria sua própria Draw()função e o código do cliente poderia simplesmente:

shape.Draw()

para obter o comportamento correto para qualquer forma.

Isso contrasta com a maneira antiga de fazer coisas nas quais o código era separado dos dados, e você teria funções como drawSquare()e drawCircle().

Orientação a objetos, polimorfismo e herança são conceitos intimamente relacionados e são vitais para conhecer. Houve muitas "balas de prata" durante a minha longa carreira que basicamente acabaram, mas o paradigma OO acabou por ser bom. Aprenda, compreenda, ame - você ficará feliz por ter :-)


(a) Eu escrevi isso originalmente como uma piada, mas acabou sendo correto e, portanto, não tão engraçado. O monômero estireno é produzido a partir de carbono e hidrogênio , e o poliestireno é produzido a partir de grupos disso .C8H8(C8H8)n

Talvez eu devesse ter afirmado que um pólipo era muitas ocorrências da carta p, embora, agora que eu tive que explicar a piada, mesmo isso também não pareça engraçado.

Às vezes, você deve sair enquanto está por trás :-)

paxdiablo
fonte
50
Grego, não latino :) (o 'y' e o 'ph' são os brindes). E em grego, 'morph-' é apenas 'forma', ou 'forma' - o Inglês significado de ' mudança de forma' para 'metamorfose' é um desenvolvimento posterior
AakashM
16
O polimorfismo não está relacionado ao POO, mas o POO está relacionado ao polimorfismo porque o suporta de forma inerente (assumindo que seja uma linguagem OOP decente). Veja o FP para outros exemplos de polimorfismo.
alternativa
9
Estas duas linhas fizeram o truque para mim:Poly = many and Morph = change or form
Jo Smo
3
Pólipo é a abreviação de polypo (u) s. E pous é pé em grego. ;-)
Dirk
2
@ Shaun, acho que você pode estar usando o termo "interface" em um sentido muito literal / constritivo - eu quis dizer isso como um termo em inglês e não como uma definição específica para alguma linguagem arbitrária de computador. Não significa exatamente a mesma função com exatamente os mesmos parâmetros, é simplesmente uma maneira de afetar "objetos" da mesma maneira, independentemente do tipo concreto subjacente. Isso pode incluir sobrecarga de método com diferentes tipos de parâmetros, bem como a forma mais pura de polimorfismo.
precisa saber é o seguinte
250

Polimorfismo é quando você pode tratar um objeto como uma versão genérica de algo, mas quando você o acessa, o código determina qual o tipo exato e chama o código associado.

Aqui está um exemplo em c #. Crie quatro classes dentro de um aplicativo de console:

public abstract class Vehicle
{
    public abstract int Wheels;
}

public class Bicycle : Vehicle
{
    public override int Wheels()
    {
        return 2;
    }
}

public class Car : Vehicle
{
    public override int Wheels()
    {
        return 4;
    }
}

public class Truck : Vehicle
{
    public override int Wheels()
    {
        return 18;
    }
}

Agora crie o seguinte no Main () do módulo para o aplicativo do console:

public void Main()
{
    List<Vehicle> vehicles = new List<Vehicle>();

    vehicles.Add(new Bicycle());
    vehicles.Add(new Car());
    vehicles.Add(new Truck());

    foreach (Vehicle v in vehicles)
    {
        Console.WriteLine(
            string.Format("A {0} has {1} wheels.",
                v.GetType().Name, v.Wheels));
    }
}

Neste exemplo, criamos uma lista da classe base Vehicle, que não sabe quantas rodas cada uma de suas subclasses possui, mas sabe que cada subclasse é responsável por saber quantas rodas possui.

Em seguida, adicionamos uma bicicleta, carro e caminhão à lista.

Em seguida, podemos percorrer cada veículo na lista e tratá-los de forma idêntica; no entanto, quando acessamos a propriedade 'Rodas' de cada veículo, a classe Vehicle delega a execução desse código à subclasse relevante.

Diz-se que esse código é polimórfico, pois o código exato que é executado é determinado pela subclasse que está sendo referenciada no tempo de execução.

Espero que isso ajude você.

Antony Gibbs
fonte
6
Acho que este é um exemplo muito bom para mostrar claramente a interface pai, e que não é até que o objeto é instanciado que uma versão concreta é necessária, ou seja, veículo vs carro
wired00
1
Eu diria que este é o exemplo mais claro, mas se você é um programador PHP esta ligação pode ser mais fácil para rever primeiro, e depois ainda olhar para este um após: code.tutsplus.com/tutorials/...
Oliver Williams
Também (além do escopo do OP), observe que estamos restringindo a análise a objetos conhecidos; não estamos passando um objeto (como um arquivo de importação) e depois determinando que tipo é (Excel, CSV, YAML, SQL, etc. etc.). Para fazer isso, seria necessário algum tipo de classe de fábrica para Class_Excel, Class_CSVser chamado ou ter uma Readerclasse chamada. De qualquer maneira, algum tipo de iterativo se / então / mais precisará ser armazenado em algum lugar.
Oliver Williams
@ Anthony Gibbs: este é realmente um bom exemplo (uma lista dos tipos genéricos) que faz sentido para mim ... caso contrário, qual é o grande problema de cada classe ter suas próprias rodas funcionando sem herdar de uma classe base? Além da lista, existem outros conceitos que seriam bons para polimórficos?
TTT
195

De Compreendendo e aplicando polimorfismo no PHP , Obrigado Steve Guidetti.

Polimorfismo é uma palavra longa para um conceito muito simples.

O polimorfismo descreve um padrão na programação orientada a objetos, na qual as classes têm funcionalidades diferentes ao compartilhar uma interface comum.

A beleza do polimorfismo é que o código que trabalha com as diferentes classes não precisa saber qual classe ele está usando, pois todos eles são usados ​​da mesma maneira. Uma analogia do mundo real para o polimorfismo é um botão. Todo mundo sabe como usar um botão: você simplesmente aplica pressão nele. O que um botão "faz", no entanto, depende do que está conectado e do contexto em que é usado - mas o resultado não afeta como ele é usado. Se o seu chefe diz para você pressionar um botão, você já possui todas as informações necessárias para executar a tarefa.

No mundo da programação, o polimorfismo é usado para tornar os aplicativos mais modulares e extensíveis. Em vez de instruções condicionais confusas que descrevem diferentes cursos de ação, você cria objetos intercambiáveis ​​que seleciona com base em suas necessidades. Esse é o objetivo básico do polimorfismo.

Ajay Patel
fonte
10
a analogia dos botões não está mais relacionada ao conceito de abstração?
thewpfguy
6
Fonte original: code.tutsplus.com/tutorials/…
Alguém
8
@Mantriur: Isso é realmente plagiado, e temos regras contra isso: stackoverflow.com/help/referencing Mas, dada a sua pontuação agora e o fato de que as postagens antigas estão isentas de perda de representantes na exclusão de respostas, não tenho certeza se a excluir agora diretamente iria melhorar qualquer coisa. A próxima melhor alternativa seria apenas editar a atribuição em nome do usuário, mesmo que eu acredite fortemente que os usuários sejam responsáveis ​​por citar fontes em suas próprias respostas.
BoltClock
1
Eu acredito que é incorreto sugerir que o polimorfismo é específico para classes e / ou programação orientada a objetos, vendo como o polimorfismo ad hoc ou o polimorfismo paramétrico não exigem necessariamente classes e / ou objetos. Penso que o que esta resposta está falando é subtipo (também conhecido como polimorfismo de subtipo ou polimorfismo de inclusão).
usar o seguinte
64

Se alguém disser corta para essas pessoas

  1. O cirurgião
  2. O cabeleireiro
  3. O ator

O que vai acontecer?

  • O cirurgião começaria a fazer uma incisão.
  • O cabeleireiro começaria a cortar o cabelo de alguém.
  • O ator deixaria abruptamente de atuar fora da cena atual, aguardando orientação da diretoria.

Então, a representação acima mostra O que é polimorfismo (mesmo nome, comportamento diferente) em OOP.

Se você estiver indo para uma entrevista e o entrevistador solicitar que você conte / mostre um exemplo ao vivo para polimorfismo na mesma sala em que estamos, digamos:

Resposta - Porta / Janelas

Querendo saber como?

Através da porta / janela - uma pessoa pode entrar, o ar pode entrar, a luz pode entrar, a chuva pode entrar, etc.

Para entender melhor e de uma maneira simples, usei o exemplo acima. Se você precisar de referência para o código, siga as respostas acima.

Sanchit
fonte
5
Eu não acho que este seja um ótimo exemplo, porque pode levar pessoas inexperientes a pensar que, se duas classes tiverem um .foo() método, elas devem compartilhar uma interface comum. No entanto, isso não é verdade e leva a abstrações incorretas. Uma interface deve definir um papel a ser desempenhado, que pode ter muitas implementações diferentes, mas todas extraem do mesmo conjunto de entradas e retornam algo do mesmo conjunto de saídas. A entrada x.cut(...)de um cirurgião, estilista ou ator não é a mesma e a saída não é a mesma.
Matt Klein
37

Explicação simples por analogia

O presidente dos Estados Unidos emprega polimorfismo. Quão? Bem, ele tem muitos conselheiros:

  1. Conselheiros Militares
  2. Assessores Jurídicos
  3. Físicos nucleares (como conselheiros)
  4. Consultores médicos
  5. etc etc.

Todos devem ser responsáveis ​​apenas por uma coisa: Exemplo:

O presidente não é especialista em revestimento de zinco ou física quântica. Ele não sabe muitas coisas - mas ele sabe apenas uma coisa: como administrar o país.

É o mesmo com o código: preocupações e responsabilidades devem ser separadas para as classes / pessoas relevantes. Caso contrário, o presidente saberia literalmente tudo no mundo - toda a Wikipedia. Imagine ter toda a wikipedia em uma classe do seu código: seria um pesadelo para manter.

Por que é uma má idéia para um presidente saber todas essas coisas específicas?

Se o presidente dissesse especificamente às pessoas o que fazer, isso significaria que o presidente precisa saber exatamente o que fazer. Se o presidente precisar conhecer coisas específicas, isso significa que, quando você precisar fazer uma alteração, precisará fazer isso em dois lugares, não apenas em um.

Por exemplo, se a EPA alterar as leis de poluição, quando isso acontecer: você terá que fazer uma alteração na classe EPA e também na classe President. Alterar o código em dois lugares e não em um pode ser perigoso - porque é muito mais difícil de manter.

Existe uma abordagem melhor?

Existe uma abordagem melhor: o presidente não precisa conhecer as especificidades de nada - ele pode exigir o melhor conselho, de pessoas especificamente encarregadas de fazer essas coisas.

Ele pode usar uma abordagem polimórfica para administrar o país.

Exemplo - do uso de uma abordagem polimórfica:

Tudo o que o presidente faz é pedir às pessoas que o aconselhem - e é isso que ele realmente faz na vida real - e é isso que um bom presidente deve fazer. todos os conselheiros respondem de maneira diferente, mas todos sabem o que o presidente quer dizer com: Aconselhar (). Ele tem centenas de pessoas entrando no escritório dele. Na verdade, não importa quem eles são. Tudo o que o presidente sabe é que, quando ele pede para "aconselhar", eles sabem como responder de acordo :

public class MisterPresident
{
    public void RunTheCountry()
    {
        // assume the Petraeus and Condi classes etc are instantiated.
        petraeus.Advise(); // # Petraeus says send 100,000 troops to Fallujah
        condolezza.Advise(); // # she says negotiate trade deal with Iran
        healthOfficials.Advise(); // # they say we need to spend $50 billion on ObamaCare
    }
}

Essa abordagem permite que o presidente administre o país literalmente sem saber nada sobre assuntos militares, saúde ou diplomacia internacional: os detalhes são deixados para os especialistas. A única coisa que o presidente precisa saber é: "Aconselhar ()".

O que você NÃO quer:

public class MisterPresident
{
    public void RunTheCountry()
    {
        // people walk into the Presidents office and he tells them what to do
        // depending on who they are.

        // Fallujah Advice - Mr Prez tells his military exactly what to do.
        petraeus.IncreaseTroopNumbers();
        petraeus.ImproveSecurity();
        petraeus.PayContractors();

        // Condi diplomacy advice - Prez tells Condi how to negotiate

        condi.StallNegotiations();
        condi.LowBallFigure();
        condi.FireDemocraticallyElectedIraqiLeaderBecauseIDontLikeHim();

        // Health care

        healthOfficial.IncreasePremiums();
        healthOfficial.AddPreexistingConditions();
    }
}

NÃO! NÃO! NÃO! No cenário acima, o presidente está fazendo todo o trabalho: ele sabe sobre o aumento do número de tropas e condições pré-existentes. Isso significa que, se as políticas do Oriente Médio mudarem, o presidente terá que mudar seus comandos, assim como a classe Petraeus. Só devemos mudar a classe Petraeus, porque o presidente não deveria ter que se atolar nesse tipo de detalhe. Ele não precisa saber sobre os detalhes. Tudo o que ele precisa saber é que, se ele fizer um pedido, tudo será resolvido. Todos os detalhes devem ser deixados para os especialistas.

Isso permite que o presidente faça o que faz de melhor: defina políticas gerais, tenha uma boa aparência e jogue golfe: P.

Como é realmente implementado - através de uma classe base ou uma interface comum

Isso, na verdade, é polimorfismo, em poucas palavras. Como exatamente isso é feito? Através da "implementação de uma interface comum" ou do uso de uma classe base (herança) - veja as respostas acima que detalham isso mais claramente. (Para entender mais claramente esse conceito, você precisa saber o que é uma interface e entender o que é herança. Sem isso, você pode ter dificuldades.)

Em outras palavras, Petraeus, Condi e HealthOfficials seriam classes que "implementam uma interface" - vamos chamá-la de IAdvisorinterface que contém apenas um método:Advise() . Mas agora estamos entrando em detalhes.

Isso seria ideal

    public class MisterPresident
    {
            // You can pass in any advisor: Condi, HealthOfficials,
            //  Petraeus etc. The president has no idea who it will 
            // be. But he does know that he can ask them to "advise" 
            // and that's all Mr Prez cares for.

        public void RunTheCountry(IAdvisor governmentOfficer)
        {             
            governmentOfficer.Advise();              
        }
    }


    public class USA
    {
        MisterPresident president;

        public USA(MisterPresident president)
        {
            this.president = president;
        }

        public void ImplementPolicy()
        {
            IAdvisor governmentOfficer = getAdvisor(); // Returns an advisor: could be condi, or petraus etc.
            president.RunTheCountry(governmentOfficer);
        }
    }

Sumário

Tudo o que você realmente precisa saber é o seguinte:

  • O presidente não precisa saber os detalhes - esses são deixados para os outros.
  • Tudo o que o presidente precisa saber é perguntar a quem entra pela porta para aconselhá-lo - e sabemos que eles saberão absolutamente o que fazer quando solicitados a aconselhar (porque são todos na realidade, conselheiros (ou IAdvisors :))

Eu realmente espero que ajude você. Se você não entender nada, poste um comentário e tentarei novamente.

BKSpurgeon
fonte
4
Exemplo fantástico! Obrigado.
Iman Sedighi
1
Analogia muito interessante. Obrigado.
thanhtang
1
@TTT porque (1) toda vez que você tem um novo consultor, precisa mudar a classe de presidente - você não deseja fazer alterações x2. apenas um. (2) em segundo lugar, se você precisar alterar um consultor existente, poderá ser necessário voltar e alterar uma dessas três chamadas na classe presidente - você realmente deseja fazer apenas uma alteração, não duas. (3) se você tivesse três telefonemas separados, teria que perguntar, dentro da classe presidente: if healthAdvisor? then do this:e if petraus then do that etc.esse padrão precisará ser repetido e isso é desnecessário e complicado. veja acima editar.
precisa saber é o seguinte
1
@TTT sim, você está certo. mas tenho que apresentar lentamente o conceito aos leitores, caso contrário eles não entenderão. Eu adicionei mais alterações. Por favor, informe se são necessários esclarecimentos
BKSpurgeon
1
A classe base @TTT vs interface é uma decisão de projeto que os programadores precisam tomar ao executar o polimorpismo. veja aqui para obter mais detalhes: stackoverflow.com/questions/56867/interface-vs-base-class
BKSpurgeon
24

Polimorfismo é a capacidade de tratar uma classe de objeto como se fosse a classe pai.

Por exemplo, suponha que exista uma classe chamada Animal e uma classe chamada Dog que herda de Animal. Polimorfismo é a capacidade de tratar qualquer objeto Dog como um objeto Animal da seguinte forma:

Dog* dog = new Dog;
Animal* animal = dog;
Tom Dalling
fonte
Pergunto-me como é que esta relacionado com a explicação (popular) que @Ajay Patel deuclasses have different functionality while sharing a common interface
BornToCode
1
@BornToCode A classe pai é / fornece essa interface comum.
grokmann
1
O polimorfismo não requer subtipagem.
Shaun Luttin
22

Polimorfismo:

É o conceito de programação orientada a objetos. A capacidade de diferentes objetos responderem, cada um à sua maneira, a mensagens idênticas é chamada polimorfismo.

O polimorfismo resulta do fato de que toda classe vive em seu próprio espaço para nome. Os nomes atribuídos em uma definição de classe não entram em conflito com os nomes atribuídos a qualquer lugar fora dela. Isso ocorre tanto nas variáveis ​​de instância na estrutura de dados de um objeto quanto nos métodos do objeto:

  • Assim como os campos de uma estrutura C estão em um espaço para nome protegido, o mesmo ocorre com as variáveis ​​de instância de um objeto.

  • Os nomes dos métodos também são protegidos. Ao contrário dos nomes das funções C, os nomes dos métodos não são símbolos globais. O nome de um método em uma classe não pode entrar em conflito com os nomes de métodos em outras classes; duas classes muito diferentes podem implementar métodos nomeados de forma idêntica.

Os nomes dos métodos fazem parte da interface de um objeto. Quando uma mensagem é enviada solicitando que um objeto faça alguma coisa, a mensagem nomeia o método que o objeto deve executar. Como objetos diferentes podem ter métodos com o mesmo nome, o significado de uma mensagem deve ser entendido em relação ao objeto específico que recebe a mensagem. A mesma mensagem enviada para dois objetos diferentes pode chamar dois métodos distintos.

O principal benefício do polimorfismo é que ele simplifica a interface de programação. Ele permite que sejam estabelecidas convenções que podem ser reutilizadas em aula após aula. Em vez de inventar um novo nome para cada nova função adicionada a um programa, os mesmos nomes podem ser reutilizados. A interface de programação pode ser descrita como um conjunto de comportamentos abstratos, além das classes que os implementam.

Exemplos:

Exemplo-1: Este é um exemplo simples escrito em Python 2.x .

class Animal:
    def __init__(self, name):    # Constructor of the class
        self.name = name
    def talk(self):              # Abstract method, defined by convention only
        raise NotImplementedError("Subclass must implement abstract method")

class Cat(Animal):
    def talk(self):
        return 'Meow!'

class Dog(Animal):
    def talk(self):
        return 'Woof! Woof!'

animals = [Cat('Missy'),
           Dog('Lassie')]

for animal in animals:
    print animal.name + ': ' + animal.talk()

Exemplo-2: O polimorfismo é implementado em Java usando sobrecarga de método e substituição de método conceitos de .

Vamos considerar o exemplo do carro para discutir o polimorfismo. Pegue qualquer marca como Ford, Honda, Toyota, BMW, Benz, etc, tudo é do tipo carro.

Mas cada um tem seus próprios recursos avançados e uma tecnologia mais avançada envolvida em seu comportamento de movimentação.

Agora vamos criar um tipo básico de carro

Car.java

public class Car {

    int price;
    String name;
    String color;

    public void move(){
    System.out.println("Basic Car move");
    }

}

Vamos implementar o exemplo do carro Ford.

A Ford estende o tipo Car para herdar todos os seus membros (propriedades e métodos).

Ford.java

public class Ford extends Car{
  public void move(){
    System.out.println("Moving with V engine");
  }
}

A classe Ford acima estende a classe Car e também implementa o método move (). Embora o método de movimentação já esteja disponível para a Ford por meio da Herança, a Ford ainda implementou o método à sua maneira. Isso é chamado de substituição de método.

Honda.java

public class Honda extends Car{
  public void move(){
    System.out.println("Move with i-VTEC engine");
  }
}

Assim como a Ford, a Honda também estende o tipo de carro e implementou o método de movimentação à sua maneira.

A substituição de método é um recurso importante para ativar o polimorfismo. Usando Substituição de método, os Subtipos podem alterar a maneira como os métodos funcionam, disponíveis através da herança.

PolymorphismExample.java

public class PolymorphismExample {
  public static void main(String[] args) {
    Car car = new Car();
    Car f = new Ford();
    Car h = new Honda();

    car.move();
    f.move();
    h.move();

  }
}

Saída de exemplo de polimorfismo:

No método principal da classe PolymorphismExample, criei três objetos - Car, Ford e Honda. Todos os três objetos são referidos pelo tipo de carro.

Observe um ponto importante aqui: um tipo de superclasse pode se referir a um tipo de objeto de subclasse, mas o vice-verso não é possível. O motivo é que todos os membros da superclasse estão disponíveis para a subclasse usando herança e, durante o tempo de compilação, o compilador tenta avaliar se o tipo de referência que estamos usando tem o método que ele está tentando acessar.

Portanto, para as referências carro, f e h no exemplo do polimorfismo, o método de movimentação existe no tipo Carro. Portanto, o compilador passa no processo de compilação sem problemas.

Mas quando se trata da execução em tempo de execução, a máquina virtual chama os métodos nos objetos que são subtipos. Portanto, o método move () é chamado de suas respectivas implementações.

Portanto, todos os objetos são do tipo Car, mas durante o tempo de execução, a execução depende do objeto no qual a chamada ocorre. Isso é chamado de polimorfismo.

Tony Stark
fonte
O conceito de sobrecarga não tem nada a ver com herança e polimorfismo.
SRK
A sobrecarga do método @srk é uma maneira de implementar o polimorfismo. Geralmente é classificado como polimorfismo estático ou ad hoc. Você está
aqui
12

Geralmente, isso se refere à capacidade de um objeto do tipo A se comportar como um objeto do tipo B. Na programação orientada a objetos, isso geralmente é alcançado por herança. Alguns links da wikipedia para ler mais:

EDIT: links quebrados corrigidos.

JesperE
fonte
10
"a capacidade de um objeto do tipo A se comportar como um objeto do tipo B" - não é uma definição precisa. Eu diria que é mais como a capacidade de tratar um objeto do tipo A como se fosse um objeto do tipo B.
Artem Barger
Sim. Talvez essa seja uma frase melhor.
JesperE
Para completar, muitas linguagens implementam polimorfismo através da digitação de pato, por exemplo, Python.
ilya n.
Pergunto-me como é que esta relacionado com a explicação (popular) que @Ajay Patel deuclasses have different functionality while sharing a common interface
BornToCode
9

Polimorfismo é o seguinte:

class Cup {
   int capacity
}

class TeaCup : Cup {
   string flavour
}

class CoffeeCup : Cup {
   string brand
}

Cup c = new CoffeeCup();

public int measure(Cup c) {
    return c.capacity
}

você pode passar apenas uma copa em vez de uma instância específica. Isso ajuda em geral, porque você não precisa fornecer uma instância de measure () específica para cada tipo de copo

Vinko Vrsalovic
fonte
2
Isso é especificamente polimorfismo de subtipo.
Shaun Luttin
@ vinko-vrsalovic: como é o desenvolvimento de software na América rural?
TTT
8

Sei que esta é uma pergunta antiga com muitas respostas boas, mas gostaria de incluir uma resposta de uma frase:

Tratar um tipo derivado como se fosse do tipo base.

Existem muitos exemplos acima que mostram isso em ação, mas acho que essa é uma boa resposta concisa.

Abe Miessler
fonte
2
Isso é subtipagem, que é apenas um tipo de polimorfismo.
Shaun Luttin 29/01
@ ShaunLuttin, você pode me indicar algum recurso para aprender mais sobre os outros tipos de polimorfismo?
Abe Miessler 29/01
São "polimorfismo ad hoc" e "polimorfismo paramétrico", além de "polimorfismo de subtipo".
Shaun Luttin 29/01
8

(Eu estava navegando em outro artigo sobre algo completamente diferente ... e o polimorfismo apareceu ... Agora eu pensava que sabia o que era o polimorfismo ... mas aparentemente não dessa maneira bonita explicada .. Queria escrevê-lo em algum lugar .. melhor ainda vai compartilhar ...)

http://www.eioba.com/a/1htn/how-i-explained-rest-to-my-wife

leia a partir desta parte:

..... polimorfismo. Essa é uma maneira nerd de dizer que substantivos diferentes podem ter o mesmo verbo aplicado a eles.

Kcats Wolfrevo
fonte
5

De um modo geral, é a capacidade de interagir com vários tipos diferentes de objetos usando a mesma API ou uma API superficialmente semelhante. Existem várias formas:

  • Sobrecarga de função: definindo várias funções com o mesmo nome e diferentes tipos de parâmetros, como sqrt (float), sqrt (double) e sqrt (complex). Na maioria dos idiomas que permitem isso, o compilador selecionará automaticamente o correto para o tipo de argumento que está sendo passado para ele, portanto, esse é um polimorfismo em tempo de compilação.

  • Métodos virtuais em OOP: um método de uma classe pode ter várias implementações personalizadas para as especificidades de suas subclasses; Diz-se que cada um deles substitui a implementação fornecida na classe base. Dado um objeto que pode ser da classe base ou de qualquer uma de suas subclasses, a implementação correta é selecionada em tempo real, portanto, esse é o polimorfismo em tempo de execução.

  • Modelos: um recurso de algumas linguagens OO nas quais uma função, classe etc. pode ser parametrizada por um tipo. Por exemplo, você pode definir uma classe de modelo genérica de "lista" e instancia-la como "lista de números inteiros", "lista de cadeias", talvez até "lista de listas de cadeias" ou similares. Geralmente, você escreve o código uma vez para uma estrutura de dados do tipo arbitrário de elemento e o compilador gera versões para os vários tipos de elementos.

Stewart
fonte
4

O termo polimorfismo vem de:

poly = many

morfismo = a capacidade de mudar

Na programação, o polimorfismo é uma "técnica" que permite "olhar" para um objeto como sendo mais de um tipo de coisa. Por exemplo:

Um objeto de aluno também é um objeto de pessoa. Se você "olhar" (ou seja, elenco) para o aluno, provavelmente poderá solicitar a identificação do aluno. Você nem sempre pode fazer isso com uma pessoa, certo? (uma pessoa não é necessariamente um aluno, portanto, pode não ter um ID do aluno). No entanto, uma pessoa provavelmente tem um nome. Um aluno também.

Resumindo, "olhar" para o mesmo objeto de diferentes "ângulos" pode fornecer diferentes "perspectivas" (ou seja, propriedades ou métodos diferentes)

Portanto, essa técnica permite criar coisas que podem ser "vistas" de diferentes ângulos.

Por que usamos polimorfismo? Para iniciantes ... abstração. Neste ponto, deve haver informações suficientes :)

tzup
fonte
3

Vamos usar uma analogia. Para um determinado roteiro musical, todo músico que o toca dá seu próprio toque na interpretação.

O músico pode ser abstraído com interfaces, o gênero ao qual o músico pertence pode ser uma classe abstrac que define algumas regras globais de interpretação e todo músico que toca pode ser modelado com uma classe concreta.

Se você é um ouvinte da obra musical, você tem uma referência ao roteiro, por exemplo, 'Fuga e Tocata', de Bach, e todo músico que a executa faz polimorficamente à sua maneira.

Este é apenas um exemplo de um design possível (em Java):

public interface Musician {
  public void play(Work work);
}

public interface Work {
  public String getScript();
}

public class FugaAndToccata implements Work {
  public String getScript() {
    return Bach.getFugaAndToccataScript();
  }
}

public class AnnHalloway implements Musician {
  public void play(Work work) {
    // plays in her own style, strict, disciplined
    String script = work.getScript()
  }
}

public class VictorBorga implements Musician {
  public void play(Work work) {
    // goofing while playing with superb style
    String script = work.getScript()
  }
}

public class Listener {
  public void main(String[] args) {
    Musician musician;
    if (args!=null && args.length > 0 && args[0].equals("C")) {
      musician = new AnnHalloway();
    } else {
      musician = new TerryGilliam();
    }
    musician.play(new FugaAndToccata());
}
Boris Pavlović
fonte
1
AnnHallowaye VictorBorgaparece que eles deveriam ser objetos e não classes - seu exemplo seria melhor com, por exemplo. public class Pianist implements Musiciane victorBorge = new Pianist();etc.
Przemek D
3

Forneci uma visão geral de alto nível do polimorfismo para outra pergunta:

Polimorfismo em c ++

Espero que ajude. Um extrato...

... ajuda a começar com um teste simples e a definição de [polimorfismo]. Considere o código:

Type1 x;
Type2 y;

f(x);
f(y);

Aqui, f()é realizar alguma operação e está sendo dado os valores xe ycomo entradas. Para ser polimórfico, f()deve ser capaz de operar com valores de pelo menos dois tipos distintos (por exemplo, inte double), localizando e executando o código apropriado ao tipo.

(continuação em polimorfismo em c ++ )

Tony Delroy
fonte
3

Polimorfismo é uma habilidade do objeto que pode ser tomada de várias formas. Por exemplo, na classe humana, um homem pode agir de várias formas quando falamos de relacionamentos. EX: Um homem é pai de seu filho e ele é marido de sua esposa e ele é professor de seus alunos.

Rohit
fonte
3

Polimorfismo é a capacidade de um objeto assumir várias formas. O uso mais comum do polimorfismo no POO ocorre quando uma referência de classe pai é usada para se referir a um objeto de classe filho. Neste exemplo, escrito em Java, temos três tipos de veículo. Criamos três objetos diferentes e tentamos executar o método de rodas:

public class PolymorphismExample {

    public static abstract class Vehicle
    {
        public int wheels(){
            return 0;
        }
    }

    public static class Bike extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 2;
        }
    }

    public static class Car extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 4;
        }
    }

    public static class Truck extends Vehicle
    {
        @Override
        public int wheels()
        {
            return 18;
        }
    }

    public static void main(String[] args)
    {
        Vehicle bike = new Bike();
        Vehicle car = new Car();
        Vehicle truck = new Truck();

        System.out.println("Bike has "+bike.wheels()+" wheels");
        System.out.println("Car has "+car.wheels()+" wheels");
        System.out.println("Truck has "+truck.wheels()+" wheels");
    }

}

O resultado é:

O resultado

Para mais informações, visite https://github.com/m-vahidalizadeh/java_advanced/blob/master/src/files/PolymorphismExample.java . Espero que ajude.

Mohammad
fonte
Sim, mas você não explicou quais são os benefícios do polimorfismo. Obviamente, existe um código mais curto, no qual você excluiria a classe Vehicle, e ainda funcionaria (com uma declaração de objeto diferente, é claro).
Cornelius
Não expliquei, pois a pessoa que fez a pergunta não perguntou sobre os benefícios. Ele perguntou: "O que é polimorfismo, para que serve e como é usado?". Sobre o código, se você puder fazê-lo melhor, poste sua resposta. Assim, nossa comunidade pode usá-lo. Obrigado por seu comentário.
Mohammad
Desculpe, não queria parecer rude, outros não explicaram também. Pelo menos você se preocupou em digitar o código. De qualquer forma, ele perguntou para que serve, mas nenhum dos exemplos desta página explica para que serve. Todos vocês apenas apresentam uma maneira complexa de obter os mesmos resultados: s28.postimg.org/jq8vl6031/Poly.jpg e nenhum se importou em explicar por que alguém iria querer usar o polimorfismo, qual é o seu ganho ou objetivo, o que não poderia ter foi feito se não foi usado? Tudo o que vejo nesta página é uma proposta para subir ao seu apartamento usando escadas e não um elevador. #
Cornelius
.. sem perceber que alguém carrega um mastro grande demais para caber no elevador. Eu não sei como postar código, então eu não posso ser de muita ajuda ...
Cornelius
2

Polimorfismo é a capacidade do programador de escrever métodos com o mesmo nome que fazem coisas diferentes para diferentes tipos de objetos, dependendo das necessidades desses objetos. Por exemplo, se você estivesse desenvolvendo uma classe chamada Fractione uma classe chamada ComplexNumber, ambos poderiam incluir um método chamado display(), mas cada um deles implementaria esse método de maneira diferente. No PHP, por exemplo, você pode implementá-lo assim:

//  Class definitions

class Fraction
{
    public $numerator;
    public $denominator;

    public function __construct($n, $d)
    {
        //  In real life, you'd do some type checking, making sure $d != 0, etc.
        $this->numerator = $n;
        $this->denominator = $d;
    }

    public function display()
    {
        echo $this->numerator . '/' . $this->denominator;
    }
}

class ComplexNumber
{
    public $real;
    public $imaginary;

    public function __construct($a, $b)
    {
        $this->real = $a;
        $this->imaginary = $b;
    }

    public function display()
    {
        echo $this->real . '+' . $this->imaginary . 'i';
    }
}


//  Main program

$fraction = new Fraction(1, 2);
$complex = new ComplexNumber(1, 2);

echo 'This is a fraction: '
$fraction->display();
echo "\n";

echo 'This is a complex number: '
$complex->display();
echo "\n";

Saídas:

This is a fraction: 1/2
This is a complex number: 1 + 2i

Algumas das outras respostas parecem sugerir que o polimorfismo é usado apenas em conjunto com a herança; por exemplo, talvez Fractione ComplexNumberambos implementem uma classe abstrata chamada Numberque possui um método display(), que Fraction e ComplexNumber são obrigados a implementar. Mas você não precisa herança para tirar proveito do polimorfismo.

Pelo menos em linguagens dinamicamente tipadas como PHP (não sei C ++ ou Java), o polimorfismo permite que o desenvolvedor chame um método sem necessariamente conhecer o tipo de objeto com antecedência e confiando que a implementação correta do método ser chamado. Por exemplo, digamos que o usuário escolha o tipo de Numbercriado:

$userNumberChoice = $_GET['userNumberChoice'];

switch ($userNumberChoice) {
    case 'fraction':
        $userNumber = new Fraction(1, 2);
        break;
    case 'complex':
        $userNumber = new ComplexNumber(1, 2);
        break;
}

echo "The user's number is: ";
$userNumber->display();
echo "\n";

Nesse caso, o display()método apropriado será chamado, mesmo que o desenvolvedor não possa saber antecipadamente se o usuário escolherá uma fração ou um número complexo.

Alex Basson
fonte
2
Isso não é polimorfismo. São duas classes com métodos com o mesmo nome. Eles precisariam ser vinculados por uma classe base ou interface chamada "displayable" ou algo semelhante, e outros métodos simplesmente se importariam que o objeto fosse do tipo "displayable" em vez de Complex ou Fraction.
Pod
Eu sempre pensei que o polimorfismo era "duas classes tendo métodos com o mesmo nome". De fato, para citar Stephan Kochan (de quem sou descarado rasgando este exemplo de Fração / Complexo), "a capacidade de compartilhar o mesmo nome de método em diferentes classes é conhecida como polimorfismo". (de Programming_In_Objective-C ) Ele não menciona a necessidade de vincular classes através de uma classe base. Talvez seja diferente em diferentes idiomas, sinceramente não sei.
Alex Basson
Por mais difícil que essa definição seja citada em um livro publicado, eu ainda argumentaria que ela está incorreta. Especialmente porque parece colidir com todos os outros, a definição agnóstica de linguagem do polimorfismo. E, embora o resultado final seja o mesmo do polimorfismo, eu argumentaria que é a tipagem dinâmica que permite ao programador promover que a implementação correta de um método entre outros métodos nomeados semelhantes esteja sendo chamada.
vipirtti
2

Na programação orientada a objetos, polimorfismo refere-se à capacidade de uma linguagem de programação de processar objetos de maneira diferente, dependendo do tipo ou classe de dados . Mais especificamente, é a capacidade de redefinir métodos para classes derivadas.

sjith
fonte
2

Polimorfismo significa literalmente, múltiplas formas. (ou várias formas): objeto de classes diferentes e método com o mesmo nome, mas os fluxos de trabalho são diferentes. Um exemplo simples seria:

Considere uma pessoa X.

Ele é apenas uma pessoa, mas age como muitos. Você pode perguntar como:

Ele é filho da mãe dele. Um amigo para os amigos dele. Um irmão para sua irmã.

Shourob Datta
fonte
2

Polimorfismo no POO significa que uma classe pode ter tipos diferentes; a herança é uma maneira de implementar o polimorfismo.

por exemplo, Shape é uma interface, possui os subtipos Square , Circle , Diamond . agora você tem um objeto Square, você pode elevar o Square para Shape automaticamente, porque Square é um Shape. Mas quando você tenta fazer o downcast de Shape to Square, você deve fazer uma conversão de tipo explícita, porque não pode dizer que Shape é Square, também pode ser Circle. então você precisa convertê-lo manualmente com código como Square s = (Square)shape, e se a forma for Circle, você receberá java.lang.ClassCastException, porque Circle não é Square.

Frank Zhang
fonte
2

Polimorfismo:

Execução diferente de acordo com a instância da classe, não o tipo de variável de referência.

Uma variável de referência do tipo de interface pode se referir a qualquer uma das instâncias de classe que implementam essa interface.

Hassan Tareq
fonte
1

Polimorfismo é a capacidade de usar um objeto em uma determinada classe, em que todos os componentes que compõem o objeto são herdados pelas subclasses da classe especificada. Isso significa que, uma vez que este objeto é declarado por uma classe, todas as subclasses abaixo dele (e suas subclasses e assim por diante até chegar à subclasse mais distante / mais baixa) herdam o objeto e seus componentes (maquiagem).

Lembre-se de que cada classe deve ser salva em arquivos separados.

O código a seguir exemplifica o polimorfismo:

A SuperClasse:

public class Parent {
    //Define things that all classes share
    String maidenName;
    String familyTree;

    //Give the top class a default method
    public void speak(){
         System.out.println("We are all Parents");
    }
}

O pai, uma subclasse:

public class Father extends Parent{
    //Can use maidenName and familyTree here
    String name="Joe";
    String called="dad";

    //Give the top class a default method
    public void speak(){
        System.out.println("I am "+name+", the father.");
    }
}

A criança, outra subclasse:

public class Child extends Father {
    //Can use maidenName, familyTree, called and name here

    //Give the top class a default method
    public void speak(){
        System.out.println("Hi "+called+". What are we going to do today?");
    }
}

O método de execução, referencia a classe Parent para iniciar:

public class Parenting{
    public static void main(String[] args) {
        Parent parents = new Parent();
        Parent parent = new Father();
        Parent child = new Child();

        parents.speak();
        parent.speak();
        child.speak();
    }
}

Observe que cada classe precisa ser declarada em arquivos * .java separados. O código deve compilar. Observe também que você pode usar continuamente o nome de solteira e a árvore da família mais abaixo. Esse é o conceito de polimorfismo. O conceito de herança também é explorado aqui, onde uma classe pode ser usada ou é definida posteriormente por uma subclasse.

Espero que isso ajude e deixe claro. Vou postar os resultados quando encontrar um computador que possa ser usado para verificar o código. Obrigado pela paciência!

Midimistro
fonte
2
observe que nem todo filho é pai, portanto essa estrutura está errada. A classe superior deve ser Child (se você não está apenas começando com "Person"), o que sempre será verdadeiro, exceto Adam. Você pode definir o parent_id como null, já que o Criador não pode ser definido com nenhuma construção do intelecto humano.
9119 Yehosef
1

O polimorfismo permite que a mesma rotina (função, método) atue em tipos diferentes.

Como muitas respostas existentes conflitam subtipagem com polimorfismo, aqui estão três maneiras (incluindo subtipagem) de implementar o polimorfismo.

  • Polimorfismo paramétrico (genérico) paramétrico permite que uma rotina aceite um ou mais parâmetros de tipo, além dos parâmetros normais, e execute-se nesses tipos.
  • O polimorfismo de subtipo permite que uma rotina atue em qualquer subtipo de seus parâmetros.
  • O polimorfismo ad hoc geralmente usa sobrecarga de rotina para garantir comportamento polimórfico, mas também pode se referir a outras implementações de polimorfismo.

Veja também:

http://wiki.c2.com/?CategoryPolymorphism

https://en.wikipedia.org/wiki/Polymorphism_(computer_science)

Shaun Luttin
fonte
0

Nas linguagens orientadas a objetos, o polimorfismo permite o tratamento e o manuseio de diferentes tipos de dados através da mesma interface. Por exemplo, considere a herança em C ++: a classe B é derivada da classe A. Um ponteiro do tipo A * (ponteiro para a classe A) pode ser usado para manipular um objeto da classe A E um objeto da classe B.

Eran Rehavi
fonte
0

Polimorfismo em termos de codificação é quando seu objeto pode existir como vários tipos por herança, etc. Se você criar uma classe chamada "Shape", que define o número de lados que seu objeto possui, poderá criar uma nova classe que o herda, como "Square". " Quando você cria uma instância de "Quadrado" posteriormente, é possível convertê-lo para frente e para trás de "Forma" para "Quadrado", conforme necessário.

Brian Scott
fonte
0

O polimorfismo oferece a capacidade de criar um módulo chamando outro e ainda assim ter o ponto de dependência do tempo de compilação em relação ao fluxo de controle em vez de com o fluxo de controle.

Usando o polimorfismo, um módulo de alto nível não depende do módulo de baixo nível. Ambos dependem de abstrações. Isso nos ajuda a aplicar o princípio de inversão de dependência ( https://en.wikipedia.org/wiki/Dependency_inversion_principle ).

Foi aqui que encontrei a definição acima. Cerca de 50 minutos após o vídeo, o instrutor explica o acima. https://www.youtube.com/watch?v=TMuno5RZNeE

Raghav Navada
fonte
0

O que é polimorfismo?

Polimorfismo é a capacidade de:

  • Invoque uma operação em uma instância de um tipo especializado, conhecendo apenas seu tipo generalizado ao chamar o método do tipo especializado e não o do tipo generalizado: é um polimorfismo dinâmico .

  • Defina vários métodos com o nome save, mas com parâmetros diferentes: é polimorfismo estático .

A primeira se a definição histórica e a mais importante.

Para que é utilizado o polimorfismo?

Ele permite criar consistência fortemente tipada da hierarquia de classes e fazer algumas coisas mágicas, como gerenciar listas de objetos de tipos diferentes sem conhecer seus tipos, mas apenas um de seu tipo pai, bem como ligações de dados.

Digitação forte e fraca

Amostra

Aqui estão algumas formas como Ponto, Linha, Retângulo e Círculo, com a operação Draw () assumindo nada ou um parâmetro para definir um tempo limite para apagá-lo.

public class Shape
{
 public virtual void Draw()
 {
   DoNothing();
 }
 public virtual void Draw(int timeout)
 {
   DoNothing();
 }
}

public class Point : Shape
{
 int X, Y;
 public override void Draw()
 {
   DrawThePoint();
 }
}

public class Line : Point
{
 int Xend, Yend;
 public override Draw()
 {
   DrawTheLine();
 }
}

public class Rectangle : Line
{
 public override Draw()
 {
   DrawTheRectangle();
 }
}

var shapes = new List<Shape> { new Point(0,0), new Line(0,0,10,10), new rectangle(50,50,100,100) };

foreach ( var shape in shapes )
  shape.Draw();

Aqui, a classe Shape e os métodos Shape.Draw () devem ser marcados como abstratos.

Eles não são para fazer entender.

Explicação

Sem polimorfismo, usando substituição abstrata-virtual, enquanto analisa as formas, é apenas o método Spahe.Draw () que é chamado como o CLR não sabe qual método chamar. Por isso, chama o método do tipo em que atuamos, e aqui o tipo é Shape por causa da declaração da lista. Portanto, o código não faz nada.

Com o polimorfismo, o CLR é capaz de inferir o tipo real do objeto em que atuamos usando o que é chamado de tabela virtual. Por isso, chama o método good , e aqui chama Shape.Draw () se Shape for Point chama Point.Draw (). Então o código desenha as formas.

Mais leituras

C # - Polimorfismo (nível 1)

Polimorfismo em Java (Nível 2)

Polimorfismo (Guia de Programação em C #)

Tabela de método virtual

Olivier Rogier
fonte