Pergunta

O que é a diferença entre uma função de resumo e uma função virtual? Em que casos é recomendado usar virtual ou abstrato? Qual é a melhor abordagem?

Foi útil?

Solução

Uma função de resumo não pode ter funcionalidade. Você está dizendo basicamente, qualquer classe criança deve dar a sua própria versão deste método, no entanto, é demasiado geral para sequer tentar implementar na classe pai.

Uma função virtual , está basicamente dizendo olhar, aqui é a funcionalidade que pode ou não ser bom o suficiente para a classe infantil. Então, se ele é bom o suficiente, use este método, se não, em seguida, substituir-me, e fornecer a sua própria funcionalidade.

Outras dicas

Uma função abstrato não tem EXECUÇÃO E ele só pode ser declarado em uma classe abstrata. Isso força a classe derivada para fornecer uma implementação.

A função virtual fornece uma implementação padrão e pode existir em qualquer uma classe abstrata ou uma classe não-abstrata.

Assim, por exemplo:

public abstract class myBase
{
    //If you derive from this class you must implement this method. notice we have no method body here either
    public abstract void YouMustImplement();

    //If you derive from this class you can change the behavior but are not required to
    public virtual void YouCanOverride()
    { 
    }
}

public class MyBase
{
   //This will not compile because you cannot have an abstract method in a non-abstract class
    public abstract void YouMustImplement();
}
  1. Apenas as classes abstract pode ter membros abstract.
  2. Uma classe não-abstract que herda de uma classe abstract deve override seus membros abstract.
  3. Um membro abstract é implicitamente virtual.
  4. Um membro abstract não pode fornecer qualquer implementação (abstract é chamado pure virtual em alguns idiomas).

Você deve sempre sobrepor uma função abstrato.

Assim:

  • Sumário funções - quando o herdeiro deve fornecer sua própria implementação
  • Virtual - quando é até o herdeiro de decidir

Função Resumo:

  1. Pode ser declarada somente dentro classe abstrata.
  2. Contém apenas declaração de método não a implementação na classe abstrata.
  3. Deve ser substituído na classe derivada.

Função Virtual:

  1. Pode ser declarada dentro abstrato, bem como classe não abstrata.
  2. Contém implementação do método.
  3. Pode ser substituído.

método Resumo: Quando uma classe contém um método abstrato, que classe deve ser declarada como abstrata. O método abstrato não tem nenhuma implementação e, portanto, classes que derivam de que classe abstrata, deve fornecer uma implementação para este método abstrato.

método virtual: Uma classe pode ter um método virtual. O método virtual tem uma implementação. Quando você herdar de uma classe que tem um método virtual, você pode substituir o método virtual e fornecer lógica adicional, ou substituir a lógica com sua própria implementação.

Quando usar o que: Em alguns casos, você sabe que certos tipos deve ter um método específico, mas, você não sabe o que a implementação deste método deve ter.
Nesses casos, você pode criar uma interface que contém um método com esta assinatura. No entanto, se você tem caso de um, mas você sabe que implementadores de que a interface também terá um outro método comum (para o qual você já pode fornecer a implementação), você pode criar uma classe abstrata. Esta classe abstrata, em seguida, contém o método abstrato (que deve ser anulado), e um outro método que contém a lógica 'comum'.

Um método virtual deve ser usado se você tem uma classe que pode ser usado diretamente, mas para a qual deseja herdeiros para ser capaz de mudar certos comportamentos, embora não seja obrigatório.

explicação: com analogias. espero que ele irá ajudá-lo.

Contexto

Eu trabalho em º andar 21 de um prédio. E eu estou paranóico com fogo. De vez em quando, algum lugar do mundo, um fogo está queimando um arranha-céus. Mas, felizmente, temos um manual de instruções em algum lugar aqui sobre o que fazer em caso de incêndio:

FireEscape ()

  1. DO pertences não recolhe
  2. Walk to escada de incêndio
  3. Saia da construção

Este é basicamente um método virtual chamado FireEscape ()

Virtual Método

Este plano é bom bastante para 99% das circunstâncias. É um plano básico que funciona. Mas há uma chance de 1% de que a escada de incêndio é bloqueado ou danificado, caso em que você está completamente parafusado e você vai se tornar brinde a menos que você tomar algumas medidas drásticas. Com os métodos virtuais que você pode fazer exatamente isso: você pode substituir o plano básico FireEscape () com a sua própria versão do plano:

  1. Executar para a janela
  2. Ir para fora da janela
  3. Pára-quedas com segurança ao fundo

Em outras palavras métodos virtuais fornecer um plano básico, que pode ser anulado se você precisa . Subclasses pode substituir a classe pai método virtual se os Deems programador oportuno.

Métodos abstratos

Nem todas as organizações são bem perfurado. Algumas organizações não fazer exercícios de incêndio. Eles não têm uma política global de fuga. Cada homem é para si mesmo. Gestão estão interessados ??apenas em uma tal política existente.

Em outras palavras, cada pessoa é forçada para desenvolver seu próprio método FireEscape (). Um cara vai sair pela escada de incêndio. Outra cara vai pára-quedas. Outro cara vai usar tecnologia de propulsão de foguete para voar para longe do edifício. Outra cara vai rapel fora. Gestão não se importam como você escapar, desde que você tem um plano básico FireEscape () - se você não pode ser garantido OHS descerá sobre a organização como uma tonelada de tijolos. Isto é o que se entende por um método abstrato.

Qual é a diferença entre os dois novamente?

método abstrato: sub classes são forçada para implementar seu próprio método FireEscape. Com um método virtual, você tem um plano básico esperando por você, mas pode escolher para implementar seu próprio , se não é bom o suficiente.

Agora que não foi tão difícil foi?

Um método abstrato é um método que devem ser implementadas para fazer 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 implementado em uma classe concreta.

Um método virtual é um método que pode ser substituído em uma classe derivada usando o override, substituir o comportamento na superclasse. Se você não substituir, você começa o comportamento original. Se fizer isso, você sempre terá o novo comportamento. Esta contrário de métodos não virtuais, que não pode ser substituído, mas pode esconder o método original. Isso é feito usando o modificador new.

Veja o seguinte exemplo:

public class BaseClass
{
    public void SayHello()
    {
        Console.WriteLine("Hello");
    }


    public virtual void SayGoodbye()
    {
        Console.WriteLine("Goodbye");
    }

    public void HelloGoodbye()
    {
        this.SayHello();
        this.SayGoodbye();
    }
}


public class DerivedClass : BaseClass
{
    public new void SayHello()
    {
        Console.WriteLine("Hi There");
    }


    public override void SayGoodbye()
    {
        Console.WriteLine("See you later");
    }
}

Quando eu instanciar DerivedClass e SayHello chamada ou SayGoodbye, eu recebo "Hi There" e "Te vejo mais tarde". Se eu chamar HelloGoodbye, eu recebo "Olá" e "Te vejo mais tarde". Isso ocorre porque SayGoodbye é virtual, e pode ser substituído por classes derivadas. SayHello só é escondido, então quando eu chamo isso de minha classe base para que meu método original.

Sumário métodos são implicitamente virtual. Eles definem o comportamento que deve estar presente, mais como uma interface faz.

Sumário métodos são sempre virtual. Eles não podem ter uma implementação.

Essa é a principal diferença.

Basicamente, você usaria um método virtual se você tiver a implementação 'default' dele e quer permitir que descendentes de mudar o seu comportamento.

Com um método abstrato, você forçar descendentes para fornecer uma implementação.

Eu fiz isso mais simples, fazendo algumas melhorias nas seguintes classes (a partir de outras respostas):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestOO
{
    class Program
    {
        static void Main(string[] args)
        {
            BaseClass _base = new BaseClass();
            Console.WriteLine("Calling virtual method directly");
            _base.SayHello();
            Console.WriteLine("Calling single method directly");
            _base.SayGoodbye();

            DerivedClass _derived = new DerivedClass();
            Console.WriteLine("Calling new method from derived class");
            _derived.SayHello();
            Console.WriteLine("Calling overrided method from derived class");
            _derived.SayGoodbye();

            DerivedClass2 _derived2 = new DerivedClass2();
            Console.WriteLine("Calling new method from derived2 class");
            _derived2.SayHello();
            Console.WriteLine("Calling overrided method from derived2 class");
            _derived2.SayGoodbye();
            Console.ReadLine();
        }
    }


    public class BaseClass
    {
        public void SayHello()
        {
            Console.WriteLine("Hello\n");
        }
        public virtual void SayGoodbye()
        {
            Console.WriteLine("Goodbye\n");
        }

        public void HelloGoodbye()
        {
            this.SayHello();
            this.SayGoodbye();
        }
    }


    public abstract class AbstractClass
    {
        public void SayHello()
        {
            Console.WriteLine("Hello\n");
        }


        //public virtual void SayGoodbye()
        //{
        //    Console.WriteLine("Goodbye\n");
        //}
        public abstract void SayGoodbye();
    }


    public class DerivedClass : BaseClass
    {
        public new void SayHello()
        {
            Console.WriteLine("Hi There");
        }

        public override void SayGoodbye()
        {
            Console.WriteLine("See you later");
        }
    }

    public class DerivedClass2 : AbstractClass
    {
        public new void SayHello()
        {
            Console.WriteLine("Hi There");
        }
        // We should use the override keyword with abstract types
        //public new void SayGoodbye()
        //{
        //    Console.WriteLine("See you later2");
        //}
        public override void SayGoodbye()
        {
            Console.WriteLine("See you later");
        }
    }
}

Encadernação é o processo de mapeamento de um nome a uma unidade de código.

ligação tardia meio que usamos o nome, mas adiar o mapeamento. Em outras palavras, criamos / mencionar o nome em primeiro lugar, e deixar alguns posterior identificador de processo de mapeamento de código para esse nome.

Agora, considere:

  • Em comparação com os seres humanos, as máquinas são realmente bons em pesquisa e classificação
  • Em comparação com as máquinas, os humanos são realmente bons em invenção e inovação

Assim, a resposta curta é: virtual é uma instrução de ligação tardia para a máquina (runtime), enquanto abstract é a instrução ligação tardia para o ser humano (programador)

Em outras palavras, significa virtual:

“Querido tempo de execução , vincular o código apropriado para este nome, fazendo o que você faz de melhor: Pesquisar

Considerando que os meios abstract:

“Querido programador , por favor ligam o código apropriado para este nome, fazendo o que você faz de melhor: inventar

Por uma questão de exaustividade, sobrecarga meios:

“Querido compilador , vincular o código apropriado para este nome, fazendo o que você faz de melhor: classificação ”.

Você basicamente usar um método virtual quando você quer os herdeiros para estender a funcionalidade se eles querem.

Você usa métodos abstratos quando você quer os herdeiros para implementar a funcionalidade (e neste caso eles não têm escolha)

Eu vi em alguns lugares o método abstrato é definido como a seguir. **

"um método abstrato deve ter para implementar na classe criança"

** Senti-me como é.

Não é necessário que um método abstrato tem de ser implementado em uma classe criança, se a classe criança também é abstrato ..

1) Um método abstrato não pode ser um método privado. 2) Método Uma Abstract não pode ser implementado na mesma classe abstrata.

Eu diria ..se estamos implementando uma classe abstrata, você deve ter para substituir os métodos abstratos da classe abstrata base. Porque .. A implementação do método abstrato é com override palavra-chave .Similar para o método virtual.

Não é necessário para um método virtual a ser implementado em uma classe herdada.

                                 ----------CODE--------------

public abstract class BaseClass
{
    public int MyProperty { get; set; }
    protected abstract void MyAbstractMethod();

    public virtual void MyVirtualMethod()
    {
        var x = 3 + 4;
    }

}
public abstract class myClassA : BaseClass
{
    public int MyProperty { get; set; }
    //not necessary to implement an abstract method if the child class is also abstract.

    protected override void MyAbstractMethod()
    {
        throw new NotImplementedException();
    }
}
public class myClassB : BaseClass
{
    public int MyProperty { get; set; }
    //You must have to implement the abstract method since this class is not an abstract class.

    protected override void MyAbstractMethod()
    {
        throw new NotImplementedException();
    }
}

Virtual Método :

  • meios virtuais que pode substitui-lo.

  • Função Virtual tem uma implementação. Quando herdar a que classe pode substituir a função virtual e fornecer nossa própria lógica.

  • Nós podemos mudar o tipo de retorno da função virtual durante a implementação do
    função na classe criança (que pode ser dito como um conceito de
    Sombreamento).

método abstrato

  • Sumário significa que temos de substituí-lo.

  • Uma função abstrato não tem nenhuma implementação e deve estar em uma classe abstrata.

  • Ele só pode ser declarada. Isso força a classe derivada para fornecer a implementação do mesmo.

  • Um elemento abstrato é implicitamente virtual. O resumo pode ser chamado como virtual pura em alguns dos idiomas.

    public abstract class BaseClass
    { 
        protected abstract void xAbstractMethod();
    
        public virtual void xVirtualMethod()
        {
            var x = 3 + 4;
        }
    } 
    

Função Resumo não pode ter um corpo e deve ser substituído por classes filhas

Função Virtual terá um corpo e pode ou não ser substituído por classes filhas

A maioria dos exemplos acima usam código - e eles são muito, muito bom. Eu não precisa acrescentar ao que eles dizem, mas a seguir é uma explicação simples que faz uso de analogias em vez de código terms / técnicos.

explicação simples - Explicação usando analogias

método abstrato

Pense George W Bush. Ele disse aos seus soldados: "Vai lutar no Iraque". E é isso. Tudo o que ele tem especificado é que a luta deve ser feito. Ele não especifica como exatamente o que vai acontecer. Mas eu quero dizer, você não pode simplesmente sair e "luta": o que isso significa exatamente? posso lutar com um B-52 ou a minha derringer? Esses detalhes específicos são deixados para outra pessoa. Este é um método abstrato.

Virtual Método

David Petraeus é alto no exército. Ele definiu o que lutar meios:

  1. Encontre o inimigo
  2. neutralizá-lo.
  3. Tenha uma cerveja depois

O problema é que é um método muito geral. É um bom método que funciona, mas às vezes não é suficiente específica. Boa coisa para Petraeus é que suas ordens têm margem de manobra e alcance. - Ele permitiu que os outros a mudar a sua definição de "luta", de acordo com suas necessidades específicas

Privada Job Bloggs lê ordem de Petraeus e é dada permissão para implementar sua própria versão de luta, de acordo com suas necessidades específicas:

  1. Encontre inimigo.
  2. Atire na cabeça dele.
  3. Go Home
  4. Tem cerveja.

Nouri al Maliki também recebe as mesmas ordens de Petraeus. Ele é lutar também. Mas ele é um político, não um homem de infantaria. Obviamente, ele não pode sair por aí atirando seus inimigos politican na cabeça. Porque Petraeus deu-lhe um método virtual, em seguida, Maliki pode implementar sua própria versão do método de luta, de acordo com suas circunstâncias particulares:

  1. Encontre inimigo.
  2. prendê-lo com algum BS acusações forjadas.
  3. Go Home
  4. Tem cerveja.

Em outras palavras, um método virtual fornece instruções clichê -. Mas estas são instruções gerais, que podem ser feitos mais específica por pessoas para baixo da hierarquia do exército, de acordo com suas circunstâncias particulares

A diferença entre os dois

  • George Bush não prova quaisquer detalhes de implementação. Este deve ser fornecido por outra pessoa. Este é um método abstrato.

  • Petraeus, por outro lado faz fornecer detalhes de implementação, mas ele deu permissão para que seus subordinados para substituir suas ordens com a sua própria versão, se eles podem vir com algo melhor.

esperança que ajuda.

função Abstract (método):

? Um método abstrato é um método que é declarado com a palavra-chave abstract.

? Ele não tem corpo.

? Deve ser implementada pela classe derivada.

? Se um método é abstrato, em seguida, a classe deve abstrato.

função virtual (método):

? Um método virtual é o método que é declarado com a palavra-chave virtual e pode ser substituído pelo método de classe derivada usando palavra-chave override.

? Cabe à classe derivada se a substituí-lo ou não.

A resposta foi fornecido um número de vezes, mas a pergunta sobre quando usar cada um é uma decisão de tempo de design. Gostaria de vê-lo como uma boa prática para tentar agrupar definições de métodos comuns em interfaces distintas e trazê-los para aulas em níveis de abstração apropriadas. Dumping um conjunto comum de definições de métodos abstratos e virtuais em uma classe torna a classe unistantiable quando ele pode ser melhor para definir uma classe não-abstrata que implementa um conjunto de interfaces concisas. Como sempre, isso depende do que melhor se adapte às suas aplicações necessidades específicas.

De orientada a objetos visão geral:

Quanto método abstrato : Quando você coloca um método abstrato na classe pai, na verdade, você está dizendo para as classes filhas: Ei nota que você tem uma assinatura método como este. E se você quiser usá-lo você deve implementar seu próprio!

Em relação à função virtual : Quando você coloca um método virtual na classe pai que você está dizendo para as classes derivadas: Ei, há uma funcionalidade aqui que fazer alguma coisa para você. Se isso é útil para você apenas usá-lo. Se não, substituir esse e implementar seu código, mesmo que você pode usar minha implementação em seu código!

esta é uma filosofia sobre diferentes entre este conceito de dois em Geral OO

Há nada chamada classe virtual em C #.

Para funções

  1. função Abstract só tem assinatura só, a classe unidade deve substituir com a funcionalidade.
  2. função Virtual irá realizar a parte da funcionalidade da classe unidade pode ou não pode substituí-lo de acordo com a exigência

Você pode decidir com sua exigência.

doesnt método Abstract ter um implementation.It é declarado na classe pai. A classe criança é resposible à aplicação do referido método.

método virtual deve ter uma implementação na classe pai e facilita a classe criança a fazer a escolha se deseja usar que a implementação da classe pai ou ter uma nova aplicação para si mesmo para que o método na classe infantil.

Uma função de resumo é "apenas" uma assinatura, sem uma implementação. Ele é usado em uma interface para declarar como a classe pode ser usado. Ele deve ser implementado em uma das classes derivadas.

Função Virtual (método na verdade), é uma função de declarar, bem como, e deve implementado em uma das classes de hierarquia de herança.

As instâncias herdadas dessa classe, herdar a implementação, bem como, a menos que você implementá-lo, em uma classe de hierarquia inferior.

A partir de um fundo C ++, C # corresponde virtuais para C ++ virtuais, enquanto o C # Métodos corresponde abstratas para função virtual pura C ++

Uma função abstrato ou método é um "nome da operação" pública exposta por uma classe, o seu objectivo, juntamente com classes abstratas, é principalmente fornecer uma forma de restrição no projeto de objetos contra a estrutura que um objeto tem de implementar.

Na verdade, as classes que herdam de sua classe abstrata tem que dar uma implementação para este método, geralmente compiladores erros levantam quando não o fazem.

Usando classes abstratas e métodos é importante principalmente para evitar que, ao focar em detalhes de implementação ao projetar as classes, a estrutura de classes de ser também relacionada com as implementações, de modo a criar dependências e acoplamento entre as classes que colaboram entre eles.

A função virtual ou método é simplesmente um método que modela um comportamento público de uma classe, mas que podemos deixar livre para modificá-lo na cadeia de herança, porque pensamos que as classes criança poderia ter necessidade de implementar algumas extensões específicas para esse comportamento.

Ambos representam uma forma de polymorpfhism no objeto paradigma de orientação.

Podemos usar métodos abstratos e funções virtuais junto para apoiar uma boa modelo de herança.

Nós projetamos uma boa estrutura abstrata das principais objetos da nossa solução, em seguida, criar implementações básicas, localizando os mais propensos a novas especializações e fazemos estes queridos como virtuals, finalmente, nos especializamos nossas implementações básicas, eventyually "substituir" os virtuais herdados .

Aqui eu estou escrevendo um código de exemplo esperando que este pode ser 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 você quiser usá-lo como uma demonstração: https: // github .com / usavas / JavaAbstractAndInterfaceDemo

public interface ExampleInterface {

//    public void MethodBodyInInterfaceNotPossible(){
//    }
    void MethodInInterface();

}

public abstract class AbstractClass {
    public abstract void AbstractMethod();

    //    public abstract void AbstractMethodWithBodyNotPossible(){
    //
    //    };

    //Standard Method CAN be declared in AbstractClass
    public void StandardMethod(){
        System.out.println("Standard Method in AbstractClass (super) runs");
    }
}

public class ConcreteClass
    extends AbstractClass
    implements ExampleInterface{

    //Abstract Method HAS TO be IMPLEMENTED in child class. Implemented by ConcreteClass
    @Override
    public void AbstractMethod() {
        System.out.println("AbstractMethod overridden runs");
    }

    //Standard Method CAN be OVERRIDDEN.
    @Override
    public void StandardMethod() {
        super.StandardMethod();
        System.out.println("StandardMethod overridden in ConcreteClass runs");
    }

    public void ConcreteMethod(){
        System.out.println("Concrete method runs");
    }

    //A method in interface HAS TO be IMPLEMENTED in implementer class.
    @Override
    public void MethodInInterface() {
        System.out.println("MethodInInterface Implemented by ConcreteClass runs");

    //    Cannot declare abstract method in a concrete class
    //    public abstract void AbstractMethodDeclarationInConcreteClassNotPossible(){
    //
    //    }
    }
}

Para o meu entendimento:

Sumário Métodos:

Somente a classe abstrata pode conter métodos abstratos. Também a necessidade classe derivada para implementar o método e nenhuma implementação é fornecida na classe.

métodos virtuais:

A classe pode declarar estes últimos e também fornecer a implementação do mesmo. Também a necessidade classe derivada para implementar o método para substituí-lo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top