Qual é a diferença entre uma função abstrata e uma função virtual? Em quais casos é recomendável usar virtual ou abstrato? Qual é a melhor abordagem?
oop
programming-languages
abstract
virtual-functions
Moran Helman
fonte
fonte
Respostas:
Uma função abstrata não pode ter funcionalidade. Você está basicamente dizendo que qualquer classe filho DEVE fornecer sua própria versão desse método, no entanto, é muito geral para tentar implementar na classe pai.
Uma função virtual , basicamente, está dizendo olha, aqui está a funcionalidade que pode ou não ser boa o suficiente para a classe filho. Portanto, se for bom o suficiente, use esse método, se não, substitua-me e forneça sua própria funcionalidade.
fonte
Uma função abstrata não tem implementação e só pode ser declarada em uma classe abstrata. Isso força a classe derivada a fornecer uma implementação.
Uma função virtual fornece uma implementação padrão e pode existir em uma classe abstrata ou em uma classe não abstrata.
Então, por exemplo:
fonte
MyBase
classe não precisa implementar a classe abstrata , de alguma forma? Eu não faço isso frequentemente, então posso estar enganado. Não vejo isso no seu exemplo.abstract
classes podem terabstract
membros.abstract
classe que herda de umaabstract
classe deve teroverride
seusabstract
membros.abstract
membro é implicitamentevirtual
.abstract
membro não pode fornecer nenhuma implementação (abstract
é chamadopure virtual
em alguns idiomas).fonte
virtual
ou nãovirtual
. Umabstract
membro (ou seja, propriedade abstrata, método abstrato) é como um método virtual, ou seja, você pode substituí-lo, exceto que ele não carrega consigo uma implementação padrão.Você sempre deve substituir uma função abstrata.
Portanto:
fonte
Função abstrata:
Função Virtual:
fonte
Método abstrato: quando uma classe contém um método abstrato, essa classe deve ser declarada como abstrata. O método abstrato não tem implementação e, portanto, as classes que derivam dessa classe abstrata devem fornecer uma implementação para esse método abstrato.
Método virtual: uma classe pode ter um método virtual. O método virtual tem uma implementação. Ao herdar de uma classe que possui um método virtual, você pode substituir o método virtual e fornecer lógica adicional ou substituir a lógica por sua própria implementação.
Quando usar o quê: Em alguns casos, você sabe que certos tipos devem ter um método específico, mas não sabe qual implementação esse método deve ter.
Nesses casos, você pode criar uma interface que contenha um método com esta assinatura. No entanto, se você tiver esse caso, mas sabe que os implementadores dessa interface também terão outro método comum (para o qual você já pode fornecer a implementação), você pode criar uma classe abstrata. Essa classe abstrata contém o método abstrato (que deve ser substituído) e outro método que contém a lógica 'comum'.
Um método virtual deve ser usado se você tiver uma classe que possa ser usada diretamente, mas para a qual deseja que os herdeiros possam alterar determinado comportamento, embora isso não seja obrigatório.
fonte
explicação: com analogias. espero que ajude você.
Contexto
Eu trabalho no 21º andar de um prédio. E eu sou paranóico sobre o fogo. De vez em quando, em algum lugar do mundo, um fogo queima um arranha-céu. Mas, felizmente, temos um manual de instruções em algum lugar aqui sobre o que fazer em caso de incêndio:
Saída de incêndio()
Este é basicamente um método virtual chamado FireEscape ()
Método virtual
Este plano é muito bom para 99% das circunstâncias. É um plano básico que funciona. Mas existe uma chance de 1% de que a escada de incêndio esteja bloqueada ou danificada. Nesse caso, você estará completamente ferrado e ficará torrado, a menos que tome alguma ação drástica. Com métodos virtuais, você pode fazer exatamente isso: você pode substituir o plano básico FireEscape () por sua própria versão do plano:
Em outras palavras, os métodos virtuais fornecem um plano básico, que pode ser substituído, se necessário . As subclasses podem substituir o método virtual da classe pai, se o programador considerar apropriado.
Métodos abstratos
Nem todas as organizações são bem treinadas. Algumas organizações não fazem exercícios de fogo. Eles não têm uma política geral de fuga. Todo homem é para si mesmo. A gerência está interessada apenas na existência dessa política.
Em outras palavras, cada pessoa é forçada a desenvolver seu próprio método FireEscape (). Um cara vai sair pela escada de incêndio. Outro cara vai de pára-quedas. Outro cara usará a tecnologia de propulsão de foguetes para fugir do prédio. Outro cara vai rapel. A gerência não se importa com a maneira como você escapa, desde que você tenha um plano básico FireEscape () - se não o fizerem, você pode ter certeza de que a OHS cairá sobre a organização como uma tonelada de tijolos. É isso que se entende por método abstrato.
Qual é a diferença entre os dois novamente?
Método abstrato: as subclasses são forçadas a implementar seu próprio método FireEscape. Com um método virtual, você tem um plano básico esperando por você, mas pode optar por implementar o seu próprio se não for bom o suficiente.
Agora isso não foi tão difícil, foi?
fonte
Um método abstrato é um método que deve ser implementado para criar uma classe concreta. A declaração está na classe abstrata (e qualquer classe com um método abstrato deve ser uma classe abstrata) e deve ser implementada em uma classe concreta.
Um método virtual é um método que pode ser substituído em uma classe derivada usando a substituição, substituindo o comportamento na superclasse. Se você não substituir, você obtém o comportamento original. Se o fizer, você sempre obtém o novo comportamento. Isso é contrário aos métodos não virtuais, que não podem ser substituídos, mas podem ocultar o método original. Isso é feito usando o
new
modificador.Veja o seguinte exemplo:
Quando instancia
DerivedClass
e ligoSayHello
, ouSayGoodbye
recebo "Olá" e "Até mais". Se eu ligarHelloGoodbye
, recebo "Olá" e "Até mais". Isso ocorre porqueSayGoodbye
é virtual e pode ser substituído por classes derivadas.SayHello
está apenas oculto; portanto, quando chamo isso da minha classe base, obtenho meu método original.Métodos abstratos são implicitamente virtuais. Eles definem o comportamento que deve estar presente, mais como uma interface.
fonte
Métodos abstratos são sempre virtuais. Eles não podem ter uma implementação.
Essa é a principal diferença.
Basicamente, você usaria um método virtual se tiver a implementação 'padrão' e desejar permitir que os descendentes alterem seu comportamento.
Com um método abstrato, você força os descendentes a fornecer uma implementação.
fonte
Simplifiquei isso ao fazer algumas melhorias nas seguintes classes (de outras respostas):
fonte
A ligação é o processo de mapear um nome para uma unidade de código.
A associação tardia significa que usamos o nome, mas adiamos o mapeamento. Em outras palavras, criamos / mencionamos o nome primeiro e deixamos que algum processo subsequente lide com o mapeamento de código para esse nome.
Agora considere:
Portanto, a resposta curta é:
virtual
é uma instrução de ligação tardia para a máquina (tempo de execução) enquanto queabstract
é a instrução de ligação tardia para o humano (programador)Em outras palavras,
virtual
significa:"Caro tempo de execução , vincule o código apropriado a esse nome, fazendo o que você faz de melhor: pesquisando "
Considerando que
abstract
significa:"Caro programador , vincule o código apropriado a esse nome, fazendo o que você faz de melhor: inventando "
Por uma questão de exaustividade, sobrecarregar significa:
“Caro compilador , vincule o código apropriado a esse nome, fazendo o que você faz de melhor: classificando ”.
fonte
Você basicamente usa um método virtual quando deseja que os herdeiros estendam a funcionalidade, se assim o desejarem.
Você usa métodos abstratos quando deseja que os herdeiros implementem a funcionalidade (e, neste caso, eles não têm escolha)
fonte
Método virtual :
Virtual significa que podemos substituí-lo.
Função Virtual tem uma implementação. Quando herdamos a classe, podemos substituir a função virtual e fornecer nossa própria lógica.
função na classe filho (que pode ser dita como um conceito de
Shadowing).
Método abstrato
Resumo significa que DEVE substituí-lo.
Uma função abstrata não tem implementação e deve estar em uma classe abstrata.
Só pode ser declarado. Isso força a classe derivada a fornecer a implementação dela.
Um membro abstrato é implicitamente virtual. O resumo pode ser chamado como virtual puro em alguns idiomas.
fonte
Já vi em alguns lugares que o método abstrato é definido como abaixo. **
** Eu senti que é assim.
Não é necessário que um método abstrato seja implementado em uma classe filho, se a classe filho também for abstrata .
1) Um método abstrato não pode ser um método privado. 2) Um método abstrato não pode ser implementado na mesma classe abstrata.
Eu diria ... se estamos implementando uma classe abstrata, você deve substituir os métodos abstratos da classe abstrata base. Porque .. A implementação do método abstrato é feita com a substituição da palavra-chave. Semelhante ao método Virtual.
Não é necessário que um método virtual seja implementado em uma classe herdada.
fonte
A maioria dos exemplos acima usa código - e eles são muito, muito bons. Não preciso acrescentar o que eles dizem, mas a seguir é uma explicação simples que utiliza analogias em vez de termos técnicos / de código.
Explicação simples - Explicação usando analogias
Método abstrato
Pense em George W. Bush. Ele diz a seus soldados: "Vá lutar no Iraque". E é isso. Tudo o que ele especificou é que a luta deve ser feita. Ele não especifica como exatamente isso vai acontecer. Mas quero dizer, você não pode simplesmente sair e "brigar": o que isso significa exatamente? eu luto com um B-52 ou meu derringer? Esses detalhes específicos são deixados para outra pessoa. Este é um método abstrato.
Método virtual
David Petraeus está no alto do exército. Ele definiu o que significa luta:
O problema é que é um método muito geral. É um bom método que funciona, mas às vezes não é específico o suficiente. O bom para Petraeus é que suas ordens têm margem de manobra e escopo - ele permitiu que outras pessoas mudassem sua definição de "luta", de acordo com seus requisitos particulares.
O Private Job Bloggs lê a ordem de Petraeus e recebe permissão para implementar sua própria versão da luta, de acordo com seus requisitos particulares:
Nouri al Maliki também recebe as mesmas ordens de Petraeus. Ele também deve lutar. Mas ele é um político, não um homem de infantaria. Obviamente, ele não pode sair por aí atirando na cabeça de seus inimigos políticos. Como Petraeus deu a ele um método virtual, Maliki pode implementar sua própria versão do método de luta, de acordo com suas circunstâncias particulares:
Em outras palavras, um método virtual fornece instruções padrão - mas essas são instruções gerais, que podem ser mais específicas pelas pessoas da hierarquia do exército, de acordo com suas circunstâncias particulares.
A diferença entre os dois
George Bush não prova nenhum detalhe de implementação. Isso deve ser fornecido por outra pessoa. Este é um método abstrato.
Petraeus, por outro lado , fornece detalhes de implementação, mas ele deu permissão para que seus subordinados substituíssem seus pedidos com sua própria versão, se puderem encontrar algo melhor.
espero que ajude.
fonte
Função abstrata (método):
● Um método abstrato é um método declarado com a palavra-chave resumo.
● Não possui corpo.
● Deve ser implementado pela classe derivada.
● Se um método é abstrato, a classe deve abstrair.
função virtual (método):
● Um método virtual é o método declarado com a palavra-chave virtual e pode ser substituído pelo método de classe derivada usando a palavra-chave override.
● Cabe à classe derivada substituí-la ou não.
fonte
A resposta foi fornecida várias vezes, mas a pergunta sobre quando usar cada uma é uma decisão em tempo de design. Eu consideraria uma boa prática tentar agrupar definições de métodos comuns em interfaces distintas e colocá-las em classes em níveis de abstração apropriados. O despejo de um conjunto comum de definições de métodos abstratos e virtuais em uma classe torna a classe não confiável, quando for melhor definir uma classe não abstrata que implemente um conjunto de interfaces concisas. Como sempre, depende do que melhor se adapte às necessidades específicas de seus aplicativos.
fonte
A função abstrata não pode ter um corpo e DEVE ser substituída por classes filho
A Função Virtual terá um corpo e poderá ou não ser substituída por classes filho
fonte
Da visão geral orientada a objetos:
Com relação ao método abstrato : Quando você coloca um método abstrato na classe pai, na verdade você está dizendo para as classes filho: Ei, observe que você tem uma assinatura de método como esta. E se você quiser usá-lo, deve implementar o seu!
Em relação à função virtual : Quando você coloca um método virtual na classe pai, está dizendo às classes derivadas: Ei, há uma funcionalidade aqui que faz algo por você. Se isso for útil, basta usá-lo. Caso contrário, substitua isso e implemente seu código, mesmo você pode usar minha implementação em seu código!
esta é uma filosofia sobre diferente entre esses dois conceitos no General OO
fonte
Uma função abstrata é "apenas" uma assinatura, sem uma implementação. É usado em uma interface para declarar como a classe pode ser usada. Ele deve ser implementado em uma das classes derivadas.
Função virtual (método realmente), é uma função que você declara também e deve ser implementada em uma das classes de hierarquia de herança.
As instâncias herdadas dessa classe também herdam a implementação, a menos que você a implemente, em uma classe de hierarquia mais baixa.
fonte
Se uma classe deriva dessa classe abstrata, ela é forçada a substituir o membro abstrato. Isso é diferente do modificador virtual, que especifica que o membro pode opcionalmente ser substituído.
fonte
Não há nada chamado classe virtual em C #.
Para funções
Você pode decidir com sua exigência.
fonte
O método abstrato não possui uma implementação. Ele é declarado na classe pai. A classe filho é responsável por implementar esse método.
O método virtual deve ter uma implementação na classe pai e facilita a classe filho a optar por usar essa implementação da classe pai ou ter uma nova implementação para esse método na classe filho.
fonte
De um plano de fundo do C ++, o C # virtual corresponde ao C ++ virtual, enquanto os métodos abstratos do C # correspondem à função virtual pura do C ++
fonte
Uma função ou método abstrato é um "nome de operação" público exposto por uma classe; seu objetivo, juntamente com as classes abstratas, é principalmente fornecer uma forma de restrição no design de objetos em relação à estrutura que um objeto precisa implementar.
De fato, as classes que herdam de sua classe abstrata precisam dar uma implementação a esse método, geralmente os compiladores geram erros quando não o fazem.
O uso de classes e métodos abstratos é importante principalmente para evitar que, concentrando-se nos detalhes da implementação ao projetar classes, a estrutura de classes esteja muito relacionada às implementações, criando assim dependências e acoplamentos entre as classes que colaboram entre elas.
Uma função ou método virtual é simplesmente um método que modela o comportamento público de uma classe, mas que podemos deixá-lo livre para modificá-lo na cadeia de herança, porque pensamos que as classes filho podem precisar implementar algumas extensões específicas para esse comportamento.
Ambos representam uma forma de polimorfismo no paradigma de orientação a objetos.
Podemos usar métodos abstratos e funções virtuais juntos para suportar um bom modelo de herança.
Projetamos uma boa estrutura abstrata dos principais objetos de nossa solução, em seguida, criamos implementações básicas, localizando aquelas mais propensas a especializações adicionais e as tornamos virtuais, finalmente, especializamos nossas implementações básicas, eventualmente "substituindo" as virtuais herdadas.
fonte
Aqui estou escrevendo um código de exemplo, esperando que este seja um exemplo bastante tangível para ver os comportamentos das interfaces, classes abstratas e classes comuns em um nível muito básico. Você também pode encontrar esse código no github como um projeto, se quiser usá-lo como uma demonstração: https://github.com/usavas/JavaAbstractAndInterfaceDemo
fonte
Para meu entendimento:
Resumo Métodos:
Somente a classe abstrata pode conter métodos abstratos. Além disso, a classe derivada precisa implementar o método e nenhuma implementação é fornecida na classe.
Métodos virtuais:
Uma classe pode declarar isso e também fornecer a implementação do mesmo. Além disso, a classe derivada precisa implementar o método para substituí-lo.
fonte