В чем разница между абстрактной функцией и виртуальной функцией? - PullRequest
1470 голосов
/ 24 декабря 2008

В чем разница между абстрактной функцией и виртуальной функцией? В каких случаях рекомендуется использовать виртуальный или абстрактный? Какой из них лучший?

Ответы [ 26 ]

6 голосов
/ 13 августа 2017

Привязка - это процесс сопоставления имени с единицей кода.

Позднее связывание означает, что мы используем имя, но откладываем сопоставление. Другими словами, мы сначала создаем / упоминаем имя и позволяем некоторому последующему процессу обрабатывать сопоставление кода с этим именем.

Теперь рассмотрим:

  • По сравнению с людьми, машины действительно хороши в поиске и сортировке
  • По сравнению с машинами люди действительно хороши в изобретательстве и инновациях

Итак, краткий ответ: virtual - это команда позднего связывания для машины (время выполнения), тогда как abstract - это команда позднего связывания для человека (программиста)

Другими словами, virtual означает:

«Уважаемый время выполнения , привяжите соответствующий код к этому имени, выполняя то, что вы делаете лучше всего: поиск »

Принимая во внимание, что abstract означает:

«Уважаемый программист , пожалуйста, свяжите соответствующий код с этим именем, выполняя то, что вы делаете лучше всего: изобретаете »

Для полноты перегрузка означает:

«Уважаемый компилятор , привяжите соответствующий код к этому имени, выполняя то, что вы делаете лучше всего: сортировка ».

3 голосов
/ 05 августа 2015

Я видел в некоторых местах абстрактный метод, определенный ниже. **

«Абстрактный метод должен быть реализован в дочернем классе»

** Я чувствовал, что это похоже.

Нет необходимости, чтобы абстрактный метод был реализован в дочернем классе, , если дочерний класс также является абстрактным ..

1) Абстрактный метод не может быть закрытым методом. 2) Абстрактный метод не может быть реализован в том же абстрактном классе.

Я бы сказал .. если мы реализуем абстрактный класс, вы должны переопределить абстрактные методы из базового абстрактного класса. Потому что .. Реализация абстрактного метода осуществляется с помощью переопределения ключевого слова. Аналогично Виртуальному методу.

Виртуальный метод не обязательно должен быть реализован в унаследованном классе.

                                 ----------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();
    }
}
3 голосов
/ 25 марта 2018

Виртуальный метод :

  • Виртуальный означает, что мы МОЖЕМ переопределить его.

  • Виртуальная функция имеет реализацию. Когда мы наследуем класс, мы может переопределить виртуальную функцию и предоставить нашу собственную логику.

  • Мы можем изменить тип возвращаемого значения Виртуальной функции при реализации
    функция в дочернем классе (что можно сказать как понятие
    Затенение).

Абстрактный метод

  • Аннотация означает, что мы ДОЛЖНЫ переопределить его.

  • Абстрактная функция не имеет реализации и должна находиться в абстрактном классе.

  • Может быть объявлено только. Это заставляет производный класс обеспечить его реализацию.

  • Абстрактный член неявно виртуален. В некоторых языках реферат можно назвать чисто виртуальным.

    public abstract class BaseClass
    { 
        protected abstract void xAbstractMethod();
    
        public virtual void xVirtualMethod()
        {
            var x = 3 + 4;
        }
    } 
    
3 голосов
/ 16 апреля 2009

В основном вы используете виртуальный метод, когда хотите, чтобы наследники расширяли функциональность, ЕСЛИ они хотят.

Вы используете абстрактные методы, когда хотите, чтобы наследники реализовали функциональность (и в этом случае у них нет выбора)

2 голосов
/ 31 мая 2016

Абстрактная функция (метод):

● Абстрактный метод - это метод, который объявлен с ключевым словом abstract.

● У него нет тела.

● Должен быть реализован производным классом.

● Если метод является абстрактным, тогда класс должен абстрагироваться.

виртуальная функция (метод):

● Виртуальный метод - это метод, который объявлен с ключевым словом virtual, и его можно переопределить методом производного класса, используя ключевое слово override.

● Производный класс должен переопределять его или нет.

2 голосов
/ 06 мая 2016

В большинстве приведенных выше примеров используется код - и они очень, очень хороши. Мне не нужно добавлять к тому, что они говорят, но ниже приводится простое объяснение, которое использует аналогии, а не код / ​​технические термины.

Простое объяснение - Объяснение с использованием аналогий

Абстрактный метод

Подумайте, Джордж Буш. Он говорит своим солдатам: «Идите воевать в Ирак». И это все. Все, что он указал, - то, что борьба должна быть сделана. Он не указывает , как именно именно это произойдет. Но я имею в виду, вы не можете просто выйти и «бороться»: что это значит точно? я бьюсь с B-52 или моим деррингером? Эти конкретные детали оставлены кому-то еще. Это абстрактный метод.

Виртуальный метод

Дэвид Петреус в армии. Он определил, что означает бой:

  1. Найди врага
  2. Нейтрализовать его.
  3. Выпей пива потом

Проблема в том, что это очень общий метод. Это хороший метод, который работает, но иногда он недостаточно конкретен. Хорошая вещь для Петреуса в том, что его приказы имеют свободу действий и объем - он позволил другим изменить его определение «бой», в соответствии с их конкретными требованиями.

Private Job Bloggs читает приказ Петреуса и получает разрешение на реализацию своей версии боя в соответствии с его конкретными требованиями:

  1. Найди врага.
  2. Стреляй ему в голову.
  3. Иди домой
  4. Есть пиво.

Нури аль Малики также получает те же приказы от Петреуса. Он также должен бороться. Но он политик, а не человек пехоты. Очевидно, он не может стрелять в своих политических врагов в голову. Поскольку Петреус предоставил ему виртуальный метод, Малики может реализовать свою собственную версию метода боя в соответствии с его конкретными обстоятельствами:

  1. Найди врага.
  2. Арестуйте его с некоторыми сфабрикованными обвинениями.
  3. Домой
  4. Есть пиво.

Другими словами, виртуальный метод предоставляет типовые инструкции - но это общие инструкции, которые могут быть сделаны более конкретными людьми в иерархии армии, в зависимости от их конкретных обстоятельств.

Разница между двумя

  • Джордж Буш не доказывает никаких деталей реализации. Это должно быть предоставлено кем-то еще. Это абстрактный метод.

  • Петреус, с другой стороны, не предоставляет подробности реализации, но он дал разрешение своим подчиненным переопределить его приказы своей собственной версией, если они могут придумать что-то лучшее.

надеюсь, это поможет.

2 голосов
/ 12 января 2016

Абстрактная функция не может иметь тела и ДОЛЖНА быть переопределена дочерними классами

Виртуальная функция будет иметь тело и может или не может быть переопределена дочерними классами

1 голос
/ 27 июля 2018

Абстрактная функция - это просто подпись без реализации. Он используется в интерфейсе, чтобы объявить, как может использоваться класс. Он должен быть реализован в одном из производных классов.

Виртуальная функция (фактически метод) - это также функция, которую вы объявляете и должна быть реализована в одном из классов иерархии наследования.

Унаследованные экземпляры такого класса также наследуют реализацию, если вы ее не реализуете, в классе более низкой иерархии.

1 голос
/ 05 июня 2018

Абстрактный метод не имеет реализации. Он объявлен в родительском классе. Дочерний класс ответственен за реализацию этого метода.

Виртуальный метод должен иметь реализацию в родительском классе, и это облегчает дочернему классу возможность выбирать, использовать ли эту реализацию родительского класса или иметь новую реализацию для этого метода в дочернем классе.

1 голос
/ 19 августа 2013

Ответ был предоставлен несколько раз, но вопрос о том, когда использовать каждый из них, является решением времени разработки. Я бы посчитал целесообразным объединить определения общих методов в отдельные интерфейсы и вывести их в классы на соответствующих уровнях абстракции. Выгрузка общего набора абстрактных и виртуальных определений методов в класс делает класс невозможным, когда лучше всего определить неабстрактный класс, который реализует набор кратких интерфейсов. Как всегда, это зависит от того, что лучше всего соответствует вашим потребностям.

...