Pergunta

Como o polimorfismo pode ser descrito de uma maneira fácil de entender?

Podemos encontrar um monte de informações sobre o assunto na internet e livros, como em Tipo polimorfismo . Mas vamos tentar torná-lo tão simples quanto possível.

Foi útil?

Solução

Isto é de minha resposta de uma pergunta semelhante. Aqui está um exemplo de polimorfismo pseudo-C # / Java:

class Animal
{
    abstract string MakeNoise ();
}

class Cat : Animal {
    string MakeNoise () {
        return "Meow";
    }
}

class Dog : Animal {
    string MakeNoise () {
        return "Bark";
    }
}

Main () {
   Animal animal = Zoo.GetAnimal ();
   Console.WriteLine (animal.MakeNoise ());
}

O método Main () não sabe o tipo do animal e depende do comportamento do método MakeNoise () de uma determinada aplicação.

Outras dicas

Dois objetos respondem à mesma mensagem com comportamentos diferentes; O remetente não precisa se preocupar.

Cada lata com uma tampa pop simples abre da mesma maneira.
Como um ser humano, você sabe que você pode Open () tal você pode encontrar.

Quando abriu, nem todas as latas comportam da mesma maneira.
Alguns contêm nozes, alguns contêm cobras falsas que saem.
O resultado depende de que tipo de lata, se a lata era uma "CanOfNuts" ou um "CanOfSnakes", mas isso não tem qualquer influência sobre como você abri-lo. Você só sabe que você pode abrir qualquer pode, e irá obter algum tipo de resultado que é decidida com base em que tipo de Can que foi que você abriu.

pUnlabledCan-> Open (); // pode dar nozes, pode dar cobras. Não sabemos até que chamá-lo

Open () tem um tipo de retorno genérico de "Conteúdo" (ou podemos decidir nenhum tipo de retorno), para que aberta tem sempre a mesma função assinatura.

Você, o ser humano, é o usuário / chamador.
Open () é a função virtual / polimórfico.
"Can" é a classe base abstrata.
CanOfNuts e CanOfSnakes são os filhos polimórficas do "Can" classe.
Cada lata pode ser aberto, mas o que especificamente ele faz e o laço específico de conteúdo que retorna são definidos por que tipo de pode é.
Tudo o que você sabe quando você vê pUnlabledCan é que você pode open ()-lo, e ele irá retornar o conteúdo. Quaisquer outros comportamentos (como popping cobras em seu rosto) são decididas pelo específica Can.

A descrição mais simples do polimorfismo é que é uma maneira de reduzir, se / switch declarações .

Ele também tem a vantagem de permitir que você estenda seus if / interruptor de declarações (ou aqueles de outras pessoas) sem modificar as classes existentes.

Por exemplo, considere a classe Stream em .NET. Sem polimorfismo seria uma única classe massiva onde cada método implementa uma instrução switch algo como:

public class Stream
{
    public int Read(byte[] buffer, int offset, int count)
    {
        if (this.mode == "file")
        {
            // behave like a file stream
        }
        else if (this.mode == "network")
        {
            // behave like a network stream
        }
        else // etc.
    }
}

Em vez disso, permitir que o tempo de execução para fazer a comutação para nós de uma forma mais eficiente, escolhendo automaticamente a implementação com base no tipo de concreto (FileStream, NetworkStream), por exemplo.

public class FileStream : Stream
{
    public override int Read(byte[] buffer, int offset, int count)
    {
        // behave like a file stream
    }
}

public class NetworkStream : Stream
{
    public override int Read(byte[] buffer, int offset, int count)
    {
        // behave like a network stream
    }
}

Poly: muitos
Morphism: formas / formas

O Ator vs. o caráter (ou papel)

As maçãs e as laranjas são tanto fruto. Fruto pode ser comido. Assim, ambas as maçãs e laranjas pode ser comido.

O kicker? Você comê-los de forma diferente! Você descascar as laranjas, mas não as maçãs.

Assim, os difere de implementação, mas o resultado final é o mesmo, você comer o fruto .

Se ele anda como um pato e grasna como um pato, então você pode tratá-lo como um pato em qualquer lugar você precisa de um pato.

Este é um artigo melhor realmente

O polimorfismo permite que objetos "Look" o mesmo, mas se comportam de maneiras diferentes. O exemplo mais comum é a tomar uma classe base animal com um fala (o) Método, Uma subclasse cão emitiria um Bark ao passo que uma subclasse porco emitiria um oink.

Os 5 segunda resposta curta maioria das pessoas usam para que outros desenvolvedores possam obter a sua cabeça em torno de Polimorfismo está sobrecarregando e substituindo

mesma sintaxe, semântica diferente.

Maneira mais simples para descrevê-lo:. Um verbo que pode aplicar a mais de um tipo de objeto

Tudo o resto, como disse Hillel, é apenas comentário.

O polimorfismo é tratar as coisas abstratamente, baseando-se no conhecimento de um "pai" comum (acho heirarchies como animal como um pai de cães e gatos).

Por exemplo, todos os animais podem respirar oxigênio, e enquanto eles podem cada um fazer isso de forma diferente que você poderia projetar uma instalação que fornece oxigênio para os animais respiram, suportando tanto cães e gatos.

Como um pouco mais, você pode fazer isso mesmo que animal é um identificador "abstrato" (não há nenhuma coisa real "Animal", apenas tipos de animais).

O polimorfismo é o armazenamento de valores de mais do que um tipo de uma localização de um único tipo.

Note que a maioria das outras respostas para essa pergunta, no momento da minha escrita, estão realmente descrevendo expedição dinâmica, não polimorfismo.

expedição dinâmico requer polimorfismo, mas o inverso não é verdadeiro. Pode-se imaginar uma língua muito semelhante ao Java ou C #, mas cuja System.Object não tinha membros; typecasting seria necessário antes de fazer qualquer coisa com o valor. Nesta língua nocional, não haveria polimorfismo, mas não necessariamente os métodos virtuais, ou quaisquer outros mecanismos de despacho dinâmico.

expedição dinâmica é o conceito relacionado mas distinto, muito bem descrito na maioria das outras respostas. No entanto, a forma como ele funciona normalmente em linguagens orientadas a objetos (selecionar uma função com base no primeiro ( 'this' ou 'auto') Tipo de argumento) não é a única maneira que ele possa trabalhar. despacho múltiplo também é possível, se a selecção for aplicada através dos tipos de todos os argumentos.

De modo semelhante, a resolução de sobrecarga e envio múltiplo são análogos exactas de um outro; resolução de sobrecarga é múltiplo expedição aplicar aos tipos estáticos, enquanto múltiplos expedição é a resolução de sobrecarga aplicar aos tipos de tempo de execução armazenados em locais polimórficos.

O polimorfismo é dividir o mundo em caixas com base em propriedades comuns e tratar os itens em um determinado caixa como intercambiáveis ??quando você só quer usar essas propriedades comuns.

O polimorfismo é a capacidade de tratar diferente as coisas como se fossem o mesma coisa através da criação de uma identidade compartilhada entre eles, em seguida, explorá-lo.

O polimorfismo é que você começa quando o mesmo método se aplica a várias classes. Por exemplo, tanto uma String e uma lista pode ter métodos de "reverso". Ambos os métodos têm o mesmo nome ( "Reverse"). Ambos os métodos de fazer algo muito semelhante (reverso todos os personagens ou inverter a ordem dos elementos na lista). Mas a implementação de cada método "reverso" é diferente e específico para sua classe. (Em outras palavras, a seqüência inverte-se como uma corda, e a Lista inverte-se como uma lista.)

Para usar uma metáfora, você poderia dizer "fazer o jantar" a um chef francês ou um chef japonês. Cada iria realizar "fazer o jantar" à sua maneira característica.

O resultado prático é que você pode criar um "Motor Inverter", que aceita um objeto e chama de "reverso" nele. Enquanto o objeto tem um método reverso, seu Invertendo Motor vai funcionar.

Para estender a analogia chef, você poderia construir um "Waiterbot" que diz chefs para "fazer o jantar". O Waiterbot não tem que saber que tipo de jantar vai ser feita. Ele nem sequer tem que se certificar de que está falando com um chef. Tudo o que importa é que o "chef" (ou bombeiro, ou máquina de venda automática, ou dispensador pet food) sabe o que fazer quando é dito para "fazer o jantar".

Esta compra-lhe como um programador é menos linhas de código e qualquer tipo-segurança ou ligação tardia. Por exemplo, aqui está um exemplo com segurança de tipo e ligação antecipada (em uma c-like linguagem que eu estou fazendo como eu ir):

class BankAccount {
    void SubtractMonthlyFee
}

class CheckingAccount : BankAccount {}

class SavingsAccount : BankAccount {}

AssessFee(BankAccount acct) {
    // This will work for any class derived from
    //   BankAccount; even classes that don't exist yet
    acct.SubtractMonthlyFee
}

main() {

    CheckingAccount chkAcct;
    SavingsAccount saveAcct;

    // both lines will compile, because both accounts
    //   derive from "BankAccount". If you try to pass in
    //   an object that doesn't, it won't compile, EVEN
    //   if the object has a "SubtractMonthlyFee" method.
    AssessFee(chkAcct);
    AssessFee(saveAcct);
}

Aqui está um exemplo sem a segurança de tipos, mas com ligação tardia:

class DatabaseConnection {
    void ReleaseResources
}

class FileHandle {
    void ReleaseResources
}

FreeMemory(Object obj) {
    // This will work for any class that has a 
    //   "ReleaseResources" method (assuming all
    //   classes are ultimately derived from Object.
    obj.ReleaseResources
}

main() {

    DatabaseConnection dbConn;
    FileHandle fh;

    // You can pass in anything at all and it will
    //   compile just fine. But if you pass in an
    //   object that doesn't have a "ReleaseResources"
    //   method you'll get a run-time error.
    FreeMemory(dbConn);
    FreeMemory(fh);
    FreeMemory(acct); //FAIL! (but not until run-time)
}

Para um excelente exemplo, olhar para o método .NET ToString (). Todas as classes têm-lo porque todas as classes são derivadas da classe Object. Mas cada classe pode implementar ToString () de uma maneira que faz sentido para si.

EDIT: Simples = curto, IMHO

O polimorfismo é a funcionalidade linguagem permitindo que o código algorítmico de alto nível para operar inalterada em vários tipos de dados.

Isto é feito, garantindo as operações de invocar a aplicação certa para cada tipo de dados. Mesmo em um contexto OOP (como por tag desta questão), este "implementação correta" pode ser resolvido em tempo de compilação ou de tempo de execução (se a sua linguagem suporta ambos). Em algumas linguagens como C ++, suporte do compilador fornecido para o polimorfismo em tempo de execução (ou seja virtual expedição) é específico para OOP, enquanto que outros tipos de polimorfismo também pode operar em tipos de dados que não são objetos (ou seja, não struct ou casos class, mas pode ser incorporado tipos como int ou double).

(Os tipos de polimorfismo C ++ suportes são listados e contrastada na minha resposta: Polimorfismo em C ++ - mesmo se você programar outras línguas, é potencialmente instrutivo)

A forma como eu tentar e pensar sobre isso é algo que tem a mesma aparência, mas pode ter funcionalidade diferente dependendo do caso. Então você pode ter um tipo

interface IJobLoader

mas dependendo de como ele é usado pode ter funcionalidade diferente enquanto ainda está procurando o mesmo. Você pode ter instâncias para BatchJobLoader, NightlyJobLoader etc

Talvez eu esteja longe.

O polimorfismo termo também pode ser aplicado a funções sobrecarga. Por exemplo,

string MyFunc(ClassA anA);
string MyFunc(ClassB aB);

é um exemplo não orientado para o objecto de polimorfismo.

É a capacidade que os objetos têm de responder à mesma mensagem de maneiras diferentes.

Por exemplo, em linguagens como Smalltalk, Ruby, Objective-C, você só tem que enviar a mensagem e eles vão responder.

 dao  = XmlDao.createNewInstance()    #obj 1
 dao.save( data )

 dao = RdbDao.createNewnewInstance()  #obj 2
 dao.save( data )

Neste exemplo, dois objetos diferentes, respondeu de maneiras diferentes para as mesmas mensagens: "createNewInstance () e save (obj)"

Eles agem de maneiras diferentes, para a mesma mensagem. Nos idiomas acima, as classes pode até não estar na mesma hierarquia de classes, é o suficiente para que eles respondem à mensagem.

Em linguagens como Java, C ++, C #, etc. A fim de atribuir o objeto de uma referência de objeto, eles devem compartilhar a mesma hierarquia de tipo, quer através da implementação da interface ou por ser subclasse de uma classe comum.

fácil .. e simples.

O polimorfismo é, de longe, a característica mais importante e relevante de programação orientada a objeto.

É uma maneira de tratar coisas diferentes que podem fazer algo algo semelhante, da mesma forma, sem cuidar como eles fazem isso.

Vamos dizer que você tem um jogo com um monte de diferentes tipos de veículos dirigindo ao redor, como carro, caminhão, skate, Avião, etc ... todos eles podem parar, mas cada veículo pára em uma maneira diferente. Alguns veículos podem precisar de se deslocar para baixo engrenagens, e alguns podem ser capazes de chegar a uma parada fria. Polymophism permite fazer isso

foreach (Vehicle v in Game.Vehicles)
{
   v.Stop();
}

A maneira que parada é implementado é adiada para os diferentes veículos para que o seu programa não precisa se preocupar com isso.

É apenas uma maneira de obter frio velho para chamar novo código. Você escreve um aplicativo que aceita alguma interface "Shape" com métodos que outros devem implementar (exemplo - getArea). Se alguém surge com uma nova forma whiz-bang para implementar essa interface seu código antigo pode chamar esse novo código através do método getArea.

A capacidade de um objecto de algum tipo (por exemplo, um carro) para agir (por exemplo freio) como um de outro tipo (por exemplo, um veículo) que normalmente sugere ancestralidade comum (por exemplo, de automóveis é um subtipo de veículo) a um ponto em a hierarquia de tipo.

O polimorfismo é a solução Orientada a Objetos para o problema de passar de uma função para outra função. Em C você pode fazer

 void h() { float x=3.0; printf("%f", x); }
 void k() { int y=5; printf("%i", y); }
 void g(void (*f)()) { f(); }
 g(h);  // output 3.0
 g(k);  // output 5

Em C as coisas ficam complicadas se a função depende de parâmetros adicionais. Se a funções h e k dependem de diferentes tipos de parâmetros que você está em apuros e você deve usar casting. Tem para armazenar os parâmetros de uma estrutura de dados, e passar um ponteiro para que a estrutura de dados de g que passa para H ou k. h e k converter o ponteiro para um apontador para a estrutura correcta e desempacotar os dados. Muito confuso e muito inseguro devido a possíveis falhas de fundição:

 void h(void *a) { float* x=(float*)a; printf("%f",*x); }
 void k(void *a) { int* y=(int*)a; printf("%i",*y); }
 void g(void (*f)(void *a),void *a) { f(a); }
 float x=3.0;
 int y=5;
 g(h,&x); // output x
 g(k,&y); // output y

Então eles inventaram polimorfismo. h e k são promovidos a classes e as funções reais para os métodos, os parâmetros variáveis ??são membros da classe respectiva, H ou k. Em vez de passar a função ao redor, você passar uma instância da classe que contém a função que deseja. A instância contém seus próprios parâmetros.

class Base { virtual public void call()=0; }
class H : public Base { float x; public void call() { printf("%f",x);} } h;
class K : public Base { int y; public void call() { printf("%i",y);} } k;
void g(Base &f) { f.call(); };
h.x=3.0;
k.y=5;
g(h); // output h.x
g(k); // output k.x
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top