подпись абстрактного метода, наследование, и "Делают" соглашение о присвоении имен

Я узнаю о шаблонах разработки, и в примерах кода я видел конвенцию, где абстрактный класс объявляет метод, например:

public abstract class ServiceBase {
... 

public virtual object GetSomething();

и затем

protected abstract object DoGetSomething();

Мой вопрос идет, почему эти два метода существуют, так как они, кажется, служат той же цели. Это то, так, чтобы базовый класс GetSomething () логика метода не мог быть переопределен наследованными классами? Но с другой стороны, метод отмечен виртуальный, таким образом, он может быть переопределен так или иначе. Какова полноценность здесь в требовании, чтобы реализаторы производного класса реализовали абстрактный метод, когда виртуальный метод можно назвать так или иначе?

5
задан T. Webster 18 March 2010 в 21:23
поделиться

2 ответа

Одной из распространенных причин является наложение стандартной обработки на абстрактный метод. Например, возможно, абстрактный метод может быть вызван только в определенных обстоятельствах - скажем, после того, как сплайны были структурированы. В этом случае имеет смысл проверять _areSplinesReticulated в одном месте - общедоступном методе GetSomething - вместо того, чтобы требовать, чтобы каждая реализация абстрактного метода выполняла свою собственную проверку. Или, может быть, GetSomething на 90% является шаблоном, но требует немного дополнительной логики или важной информации, которую могут предоставить только производные классы.

Это форма шаблона Template Method .

Невиртуальный GetSomething означает, что каждый производный класс получает стандартную обработку и может участвовать только через свою собственную версию DoGetSomething. Если GetSomething является виртуальным, это означает, что производные классы могут обойти стандартную обработку, если захотят. Любой из них является жизнеспособной стратегией в зависимости от того, является ли стандартная обработка GetSomething неотъемлемой частью логики класса (например, инвариантов) или от того, хочет ли базовый класс предоставить максимальную гибкость производным классам.

4
ответ дан 15 December 2019 в 00:57
поделиться

Я не видел описанной вами версии, где "GetSomething ()" является виртуальным, но я видел (и писал) такие классы:

public abstract class Foo
{
    protected abstract void DoBar();

    public void Bar()
    {
        // do stuff that has to happen regardless of how 
        // DoBar() has been implemented in the derived
        // class
        DoBar();
        // do other stuff
    }
}

Поскольку «Бар» не является виртуальным (и я полагаю, вы также можете запечатать его, чтобы убедиться), у вас есть шанс «ввести» код до и после вызова метода «DoBar». Это очень удобно.

0
ответ дан 15 December 2019 в 00:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: