Qual é a principal diferença entre Herança e Polimorfismo?

172

Fui apresentado com essa pergunta em um exame de livro aberto do final do módulo hoje e me vi perdida. Eu estava lendo Head first Javae as duas definições pareciam exatamente as mesmas. Eu só estava me perguntando qual era a principal diferença para o meu próprio estado de espírito. Eu sei que há várias perguntas semelhantes a isso, mas nenhuma que eu tenha visto fornece uma resposta definitiva.

Darren Burgess
fonte
2
De alguma forma relacionado a esta pergunta: é possível sem o polimorfismo de herança
Edwin Dalorzo

Respostas:

289

A herança é quando uma 'classe' deriva de uma 'classe' existente. Então, se você tem uma Personclasse, então você tem uma Studentclasse que se estende Person, Student herda todas as coisas que Personpossui. Existem alguns detalhes sobre os modificadores de acesso que você coloca nos campos / métodos em Person, mas essa é a ideia básica. Por exemplo, se você tiver um campo privado Person, Studentnão o verá porque seus campos privado e privado não são visíveis para subclasses.

O polimorfismo lida com a forma como o programa decide quais métodos ele deve usar, dependendo do tipo de coisa que possui. Se você tiver um Person, que possui um readmétodo, e um Studentque se estende Person, cuja implementação é própria read, qual método é chamado, é determinado pelo tempo de execução, dependendo se você tem um Personou a Student. Fica um pouco complicado, mas se você fizer algo como

Person p = new Student();
p.read();

o método de leitura no Student é chamado. Esse é o polimorfismo em ação. Você pode fazer essa tarefa porque a Student é a Person , mas o tempo de execução é inteligente o suficiente para saber que o tipo real pé Aluno .

Observe que os detalhes diferem entre os idiomas. Você pode fazer herança em javascript, por exemplo, mas é completamente diferente da maneira como funciona em Java.

hvgotcodes
fonte
9
@ hvgtcodes assim, em poucas palavras, a relação superclasse-subclasse é herança e o conceito de implementação do mesmo método de uma maneira diferente entre a classe pai e suas subclasses e os chama com base na situação é polimorfismo. Estou correcto?
Muhammad Raihan Muhaimin
1
@hvgotcodes, mas digamos que, se Persono readmétodo estiver usando o modificador de acesso público, os Studentobjetos não poderão acessá-los? e então Student s = new Student();não será mais fácil? Na verdade, ainda não recebo os benefícios do polimorfismo.
Scorpiorian83
1
@hvgotcodes Student s = new Student () funcionaria. Mas vamos dizer que depois que você escreveu muito do código usando essa ideia, e mais tarde você percebe que cometeu um erro. A pessoa não é realmente um estudante, é um professor. Então você pode simplesmente mudar de Pessoa p = novo aluno () para Pessoa p = novo professor (), então isso tornará sua vida muito mais simples.
munmunbb
Minha pergunta aqui seria por que você gostaria de usar em Person p = new Student();vez de Student p = new Student();?
PerfectContrast
@PerfectContrast Eu acho que é útil quando você quer ter aluno, motorista, professor etc. como Pessoa e os agrupa em uma Lista ou algo assim. Portanto, quando você chama 'ler' para todos, todos chamam seu próprio método 'ler'.
savante 22/06
205

Herança refere-se ao uso da estrutura e comportamento de uma superclasse em uma subclasse.

Polimorfismo refere-se à alteração do comportamento de uma superclasse na subclasse.

Ted Hopp
fonte
5
Esta resposta implica que o polimorfismo requer herança?
jaco0646
6
@ jaco0646 - No contexto de Java, acho que sim. (Em outros idiomas, talvez nem tanto.) Observe que "superclasse" e "subclasse" são usadas livremente aqui. Polimorfismo também pode significar herança de comportamento especificado (mas não implementado) em uma interface.
Ted Hopp
1
@AlirezaRahmani - Eu não entendo o seu comentário. Você quer dizer que herança não envolve herdar propriedades e comportamento? Isso seria contrário ao modo como Java (e a maioria das linguagens orientadas a objetos e baseadas em classe) definem herança. Na Java Language Specification, §8.4.8 : "Uma classe C herda de sua superclasse direta todos os métodos concretos m(ambos statice instance) da superclasse para os quais ..." (seguidos de detalhes sobre herança). Soa como "reutilização de código" para mim.
Ted Hopp #
A herança do @TedHopp é principalmente uma ferramenta polimórfica, mas algumas pessoas, para o seu risco posterior, tentam usá-la como uma maneira de reutilizar / compartilhar código. A lógica é "bem, se eu herdar, recebo todos os métodos de graça", mas ignorando o fato de que essas duas classes potencialmente não têm relacionamento polimórfico.
Alireza Rahmani Khalili
1
@AlirezaRahmani - Em Java (que é o que o OP perguntou especificamente, de acordo com as tags), a herança de classe definitivamente envolve o comportamento de herança. Isso faz parte da definição da linguagem. O fato de que isso pode ser mal utilizado conforme você descreve é ​​um dos pontos fracos do Java. (Uma fraqueza relacionada envolvia declarar classes para implementar interfaces simplesmente para importar as constantes definidas na interface. Eventualmente, os designers de Java introduziram import staticpara eliminar esse uso indevido de interfaces.) Para o polimorfismo puro em Java, a ferramenta a ser usada é interfaces, não herança de classe.
Ted Hopp #
63

Polimorfismo : a capacidade de tratar objetos de diferentes tipos de maneira semelhante. Exemplo: Girafa e Crocodilo são ambos Animais, e os animais podem Move. Se você tiver uma instância de um Animal, poderá ligar Movesem saber ou se importar com o tipo de animal que é.

Herança : Essa é uma maneira de obter o polimorfismo e a reutilização de código ao mesmo tempo.

Outras formas de polimorfismo : Há outra maneira de obter polimorfismo, como interfaces, que fornecem apenas polimorfismo, mas não reutilizam código (às vezes o código é bem diferente, como Movepara uma cobra seria bem diferente de Moveum cachorro, nesse caso uma interface seria a melhor escolha polimórfica neste caso.

Em outras linguagens dinâmicas, o polimorfismo pode ser alcançado com o Duck Typing, ou seja, as classes nem precisam compartilhar a mesma classe ou interface base, apenas precisam de um método com o mesmo nome. Ou ainda mais dinâmico, como o Javascript, você nem precisa de classes, apenas um objeto com o mesmo nome de método pode ser usado polimorficamente.

Davy8
fonte
17

A principal diferença é que o polimorfismo é um resultado específico da herança. Polimorfismo é o local em que o método a ser chamado é determinado em tempo de execução com base no tipo do objeto. Essa é uma situação que resulta quando você tem uma classe herdando de outra e substituindo um método específico. No entanto, em uma árvore de herança normal, você não precisa substituir nenhum método e, portanto, nem todas as chamadas de método precisam ser polimórficas. Isso faz sentido? É um problema semelhante ao de todos os veículos Ford serem automóveis, mas nem todos os automóveis são Ford (embora não exatamente ...).

Além disso, o polimorfismo lida com a invocação de método, enquanto a herança também descreve membros de dados, etc.

Chris Thompson
fonte
12

Em Java, os dois estão intimamente relacionados. Isso ocorre porque o Java usa uma técnica para chamada de método chamada "despacho dinâmico". Se eu tiver

public class A {
  public void draw() { ... }
  public void spin() { ... }
}

public class B extends A {
  public void draw() { ... }
  public void bad() { ... }
}

...

A testObject = new B();

testObject.draw(); // calls B's draw, polymorphic
testObject.spin(); // calls A's spin, inherited by B
testObject.bad(); // compiler error, you are manipulating this as an A

Então vemos que B herda spinde A. No entanto, quando tentamos manipular o objeto como se fosse um tipo A, ainda temos o comportamento de B para draw. O drawcomportamento é polimórfico.

Em algumas línguas, polimorfismo e herança não são tão intimamente relacionados. No C ++, por exemplo, funções não declaradas virtuais são herdadas, mas não serão despachadas dinamicamente, portanto você não terá esse comportamento polimórfico, mesmo quando usar a herança.

Em javascript, todas as chamadas de funções são despachadas dinamicamente e você tem digitação fraca. Isso significa que você pode ter um monte de objetos não relacionados, cada um com o seu draw, ter uma função iterar sobre eles e chamar a função, e cada um se comportaria bem. Você teria seu próprio desenho polimórfico sem precisar de herança.

ccoakley
fonte
12

Polimorfismo: Suponha que você trabalhe para uma empresa que vende canetas. Então você cria uma classe muito boa chamada "Caneta" que lida com tudo o que você precisa saber sobre uma caneta. Você escreve todos os tipos de classes para cobrança, remessa, criação de faturas, todas usando a classe Caneta. Um chefe do dia chega e diz: "Ótimas notícias! A empresa está crescendo e estamos vendendo livros e CDs agora!" Não é uma ótima notícia, porque agora você precisa alterar todas as classes que usam a Caneta para também usar o Livro e o CD. Mas e se você tivesse criado originalmente uma interface chamada "SellableProduct", e Pen implementasse essa interface. Então você poderia ter escrito todas as suas classes de remessa, faturamento etc. para usar essa interface em vez da Caneta. Agora tudo o que você precisa fazer é criar uma nova classe chamada Book & CompactDisc, que implementa a interface SellableProduct. Por causa do polimorfismo, todas as outras classes poderiam continuar trabalhando sem alterações! Faz sentido?

Então, isso significa usar a Herança, que é uma das formas de alcançar o polimorfismo.

Polimorfismo pode ser possível em uma classe / interface, mas Herança sempre entre 2 OU mais classes / interfaces. A herança sempre conforma a relação "é-a", enquanto nem sempre é com o polimorfismo (que pode conformar a relação "é-a" / "tem-a").

AmitK
fonte
6

A herança é mais uma coisa estática (uma classe se estende a outra), enquanto o polimorfismo é uma coisa de dinâmica / tempo de execução (um objeto se comporta de acordo com seu tipo de dinâmica / tempo de execução e não com seu tipo de declaração / estática).

Por exemplo

// This assignment is possible because B extends A
A a = new B();
// polymorphic call/ access
a.foo();

-> Embora o tipo estático / de declaração de a seja A, o tipo dinâmico / de tempo de execução real é B e, portanto, a.foo () executará foo conforme definido em B e não em A.

Puce
fonte
3

Polimorfismo é uma abordagem para expressar um comportamento comum entre tipos de objetos que possuem características semelhantes. Ele também permite que variações dessas características sejam criadas por meio de substituição. A herança é uma maneira de obter polimorfismo por meio de uma hierarquia de objetos em que os objetos expressam relacionamentos e comportamentos abstratos. Porém, não é a única maneira de obter polimorfismo. Protótipo é outra maneira de expressar polimorfismo diferente de herança. JavaScript é um exemplo de uma linguagem que usa protótipo. Eu imagino que existem outras maneiras também.

Laz
fonte
3

Herança é um conceito relacionado à reutilização de código. Por exemplo, se eu tiver uma classe pai say Animale ela contiver certos atributos e métodos (neste exemplo, say makeNoise()and sleep()) e eu criar duas classes filho chamadas Doge Cat. Como cães e gatos dormem da mesma maneira (eu diria), não há necessidade de adicionar mais funcionalidade ao sleep()método nas subclasses Doge nas Catsubclasses fornecidas pela classe pai Animal. No entanto, um Doglatido e um Catmiado, embora oAnimalA classe pode ter um método para fazer barulho, um cachorro e um gato fazem barulhos diferentes em relação um ao outro e a outros animais. Portanto, é necessário redefinir esse comportamento para seus tipos específicos. Assim, a definição de polimorfismo. Espero que isto ajude.

avenger12
fonte
3

A documentação da Oracle citou a diferença com precisão.

herança: Uma classe herda campos e métodos de todas as suas superclasses, sejam diretas ou indiretas. Uma subclasse pode substituir os métodos herdados ou ocultar campos ou métodos herdados . (Observe que ocultar campos geralmente é uma prática ruim de programação.)

polimorfismo: polimorfismo refere-se a um princípio em biologia no qual um organismo ou espécie pode ter muitas formas ou estágios diferentes. Esse princípio também pode ser aplicado à programação orientada a objetos e linguagens como a linguagem Java. As subclasses de uma classe podem definir seus próprios comportamentos exclusivos e ainda compartilhar algumas das mesmas funcionalidades da classe pai.

polimorfismo não é aplicável a campos.

Post relacionado:

Polimorfismo vs Substituição vs Sobrecarga

Ravindra babu
fonte
1

Polimorfismo é um efeito de herança . Isso só pode acontecer em classes que se estendem. Ele permite que você chame métodos de uma classe sem saber o tipo exato da classe. Além disso, o polimorfismo acontece em tempo de execução .

Por exemplo, exemplo de polimorfismo Java:

insira a descrição da imagem aqui

A herança permite que classes derivadas compartilhem interfaces e códigos de suas classes base. Isso acontece no momento da compilação .

Por exemplo, todas as classes na plataforma Java são descendentes de objetos (imagem cortesia da Oracle):

insira a descrição da imagem aqui

Para saber mais sobre herança e polimorfismo Java

Johnny
fonte
0

A herança é quando a classe A herda todos os métodos / campos públicos / não estáticos protegidos de todos os seus pais até Obj.

Cosmin Cosmin
fonte
0

Se você usa JAVA, é tão simples quanto isto:

O polimorfismo está usando métodos herdados, mas "sobrescrevendo" eles para fazer algo diferente (ou o mesmo se você chamar de super, não seria tecnicamente polimórfico).

Corrija-me se eu estiver errado.

Oliver Dixon
fonte
0

O principal objetivo do polimorfismo : Criar variável de referência para superclasse e manter o objeto da subclasse => um objeto pode executar vários comportamentos .

Na herança , a subclasse herda as propriedades da superclasse .

satya
fonte
0

herança é uma espécie de polimorfismo; exatamente, de fato, herança é o polimorfismo dinâmico. Portanto, quando você remove a herança, não pode mais substituir.

Alireza Rahmani Khalili
fonte
0

Com Herança, a implementação é definida na superclasse - portanto, o comportamento é herdado.

class Animal
{
  double location;
  void move(double newLocation)
  {
    location = newLocation;
  }
}

class Dog extends Animal;

Com o polimorfismo, a implementação é definida na subclasse - portanto, apenas a interface é herdada.

interface Animal
{
  void move(double newLocation);
}

class Dog implements Animal
{
  double location;
  void move(double newLocation)
  {
    location = newLocation;
  }
}
mherzl
fonte
0

O polimorfismo é obtido pela herança em Java.

├── Animal
└── (instances)
    ├── Cat
    ├── Hamster
    ├── Lion
    └── Moose

├── interface-for-diet
   ├── Carnivore
   └── Herbivore
├── interface-for-habitat
   ├── Pet
   └── Wild

public class Animal {
    void breath() {
    };
}

public interface Carnivore {
    void loveMeat();
}

public interface Herbivore {
    void loveGreens();
}

public interface Pet {
    void liveInside();
}

public interface Wild {
    void liveOutside();
}

public class Hamster extends Animal implements Herbivore, Pet {

    @Override
    public void liveInside() {
        System.out.println("I live in a cage and my neighbor is a Gerbil");
    }

    @Override
    public void loveGreens() {
        System.out.println("I eat Carrots, Grapes, Tomatoes, and More");
    }
}

public class Cat extends Animal implements Carnivore, Pet {
    @Override
    public void liveInside() {
        System.out.println("I live in a cage and my neighbr is a Gerbil");
    }

    @Override
    public void loveMeat() {
        System.out.println("I eat Tuna, Chicken, and More");
    }
}

public class Moose extends Animal implements Herbivore, Wild {

    @Override
    public void liveOutside() {
        System.out.println("I live in the forest");
    }

    @Override
    public void loveGreens() {
        System.out.println("I eat grass");
    }
}

public class Lion extends Animal implements Carnivore, Wild {

    @Override
    public void liveOutside() {
        System.out.println("I live in the forest");
    }

    @Override
    public void loveMeat() {
        System.out.println("I eat Moose");
    }
}

Hamsterclasse herda a estrutura de Animal, Herbivoree Petpara expor o behaviorismo polimórfica de um animal doméstico.

Catclasse herda a estrutura de Animal, Carnivoree Petpara também apresentam behaviorismo polimórfica de um animal doméstico.

nabster
fonte