Qual é a diferença entre uma função abstrata e uma função virtual?


1578

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?


271
Uma função abstrata deve ser substituída, enquanto uma função virtual pode ser substituída.
Jordan Parmer

15
As funções virtuais podem ter uma implementação padrão / genérica na classe base.
Martin

5
A palavra-chave aqui é abstrata ; Eles não existem e são apenas uma vaga idéia do que a função é (assinatura do método)
Cole Johnson

Respostas:


2733

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.


396
E, claro, se você substituir um método virtual, poderá sempre se referir ao método pai chamando base.Foo (...)
Brann

196
Obrigado. Esta é uma explicação muito melhor e mais fácil do que qualquer coisa na documentação do MSDN (tive uma dor de cabeça após cinco minutos lendo isso: msdn.microsoft.com/en-us/library/aa645767(v=vs.71).aspx )
Jake

15
Vindo de Java, eu estava um pouco perplexo por que precisamos para torná-lo virtual em tudo, até que eu leia isto: stackoverflow.com/a/1062126/193634
Rosdi Kasim

4
@MeqDotNet Isso significa que se você gosta de meu uso IMPLEMENTAÇÃO me se não escrever o seu próprio melhor do que eu :)
Usman Younas

16
Isso deve estar na biblioteca de referência da Microsoft, que passei 10 minutos lendo e ainda confusa.
SamChen

303

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:

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();
}

28
Muito útil para ver código de exemplo - ajuda a tornar as várias explicações nas respostas muito mais claras.
Simon Tewsi

2
Revirei a resposta para a versão anterior: as duas classes são apenas exemplos, a primeira classe será compilada, pois está marcada como abstrata, a segunda não. Se o MyBase herda de alguma outra classe ou não é irrelevante.
Dirk

2
Sua MyBaseclasse 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.
Jp2code

2
No exemplo acima, o MyBase está mostrando o que você não pode fazer. Isso é que você não pode ter um método abstrato em uma classe não abstrata
JoshBerke

80
  1. Somente as abstractclasses podem ter abstractmembros.
  2. Uma não abstractclasse que herda de uma abstractclasse deve ter override seus abstractmembros.
  3. Um abstractmembro é implicitamente virtual.
  4. Um abstractmembro não pode fornecer nenhuma implementação ( abstracté chamado pure virtualem alguns idiomas).

O número 3 não faz sentido para mim. Eu acho que você quis dizer "Um membro de uma classe abstrata é implicitamente virtual" (ou seja, você pode fornecer funcionalidade para ele sem precisar especificar que é virtual).
Hobo Spider

5
Não, eu quis dizer exatamente o que escrevi. Um membro de uma classe abstrata pode ser virtualou não virtual. Um abstractmembro (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.
Mehrdad Afshari

Citado "O membro abstrato é" implicitamente "virtual". Mas vi em algum lugar que alguém havia criado membros abstratos adicionando uma palavra-chave "virtual" explicitamente. O que não é necessário e, de fato, fiquei em dúvida até ler sua resposta.
BonCodigo 20/05

Inclua referências de suporte para o ponto 4. E sua postagem não traz mais nada que as anteriores ainda não trouxeram.
Rafael

Este é apenas um monte de declarações sem explicações.
Engenharia reversa

61

Você sempre deve substituir uma função abstrata.

Portanto:

  • Funções abstratas - quando o herdeiro deve fornecer sua própria implementação
  • Virtual - quando cabe ao herdeiro decidir

37

Função abstrata:

  1. Só pode ser declarado dentro da classe abstrata.
  2. Ele contém apenas declaração de método e não a implementação na classe abstrata.
  3. Ele deve ser substituído na classe derivada.

Função Virtual:

  1. Pode ser declarado dentro da classe abstrata e não abstrata.
  2. Ele contém a implementação do método.
  3. Pode ser substituído.

29

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.


29

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()

  1. Não colecione pertences
  2. Caminhe para escapar de incêndio
  3. Sair do prédio

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:

  1. Executar para a janela
  2. Pule pela janela
  3. Pára-quedas com segurança até o fundo

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?


22

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 newmodificador.

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 instancia DerivedClasse ligo SayHello, ou SayGoodbyerecebo "Olá" e "Até mais". Se eu ligar HelloGoodbye, recebo "Olá" e "Até mais". Isso ocorre porque SayGoodbyeé virtual e pode ser substituído por classes derivadas. SayHelloestá 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.


9

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.


9

Simplifiquei isso ao fazer algumas melhorias nas seguintes classes (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");
        }
    }
}

6

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:

  • Comparadas aos humanos, as máquinas são realmente boas em pesquisar e classificar
  • Comparado às máquinas, os seres humanos são realmente bons em invenção e inovação

Portanto, a resposta curta é: virtualé uma instrução de ligação tardia para a máquina (tempo de execução) enquanto que abstracté a instrução de ligação tardia para o humano (programador)

Em outras palavras, virtualsignifica:

"Caro tempo de execução , vincule o código apropriado a esse nome, fazendo o que você faz de melhor: pesquisando "

Considerando que abstractsignifica:

"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 ”.


3

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)


3

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.

  • Podemos alterar o tipo de retorno da função Virtual enquanto implementamos a
    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.

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

2

Já vi em alguns lugares que o método abstrato é definido como abaixo. **

"Um método abstrato deve ser implementado na classe filho"

** 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.

                                 ----------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();
    }
}

2

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:

  1. Encontre o inimigo
  2. Neutralize-o.
  3. Tome uma cerveja depois

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:

  1. Encontre inimigo.
  2. Atire na cabeça dele.
  3. Ir para casa
  4. Tome cerveja.

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:

  1. Encontre inimigo.
  2. Prenda-o com algumas acusações de BS.
  3. Ir para casa
  4. Tome cerveja.

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.


2

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.


1

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.


1

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


1

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


1

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.


1

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.


0

Não há nada chamado classe virtual em C #.

Para funções

  1. A função abstrata tem apenas assinatura, a classe da unidade deve substituir a funcionalidade.
  2. A função virtual mantém a parte da funcionalidade que a classe de unidade pode ou não substituí-la de acordo com o requisito

Você pode decidir com sua exigência.


0

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.


0

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 ++


0

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.


0

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

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(){
    //
    //    }
    }
}

-4

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.