2010-03-18 6 views
5

Я учусь о шаблонах проектирования и примеры кода, который я видел соглашение, где абстрактный класс объявляет метод, например:абстрактный метод подписи, наследование и «Do» именовании

public abstract class ServiceBase { 
... 

public virtual object GetSomething(); 

, а затем

protected abstract object DoGetSomething(); 

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

+0

Предполагается, что GetSomething является виртуальным? – JaredPar

+0

Да, это определенно виртуально. –

ответ

4

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

Это форма модели Template Method.

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

0

Я не видел версию вы описываете, где «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». Это очень удобно.

Смежные вопросы