Книга: C# для профессионалов. Том II
Виртуальные и невиртуальные функции
Виртуальные и невиртуальные функции
Виртуальные функции поддерживаются в C# таким же образом, как и в C++. Однако в C# существуют некоторые синтаксические отличия, которые созданы, чтобы исключить возможную неоднозначность в C++. Это означает, что некоторые типы ошибок, которые появляются в C++ только во время выполнения, будут идентифицированы в C# во время компиляции.
Отметим также, что в C# классы всегда доступны по ссылке (что эквивалентно доступу через указатель в C++).
Если в C++ требуется, чтобы функция была виртуальной необходимо просто определить ключевое слово virtual
в базовом и производном классах. В противоположность этому в C# необходимо объявить функцию как virtual
в базовом классе и как override
в версиях производных классов.
class MyBaseClass {
public virtual void DoSomething(int X) {
// и т.д.
}
// и т.д.
}
class MyClass : MyBaseClass {
public override void DoSomething(int X) {
// и т.д.
}
// и т.д.
}
Важный момент этого синтаксиса состоит в том, что он дает понять компилятору, как интерпретировать функцию, и значит, исключается риск таких ошибок, где, например, вводится слегка неправильная сигнатура метода в переопределяемой версии, и поэтому определяется новая функция вместо переопределения существующей. Компилятор будет отмечать ошибку, если функция помечена как override
, и компилятор не сможет идентифицировать ее версию в каком-либо базовом классе.
Если функция не является виртуальной, то можно все равно определить версии этого метода в производном классе, в этом случае говорят, что версия производного класса скрывает версию базового класса, а вызываемый метод зависит только от типа ссылки, используемой для доступа к классу, так же как это зависит от типа указателя, используемого для доступа к классу в C++.
В случае, если в C# версия функции в производном классе скрывает соответствующую функцию в базовом классе, можно явно указать это с помощью ключевого слова new
.
class MyBaseClass {
public void DoSomething(int X) {
// и т.д.
}
// и т.д.
}
class MyClass : MyBaseClass {
public new void DoSomething(int X) {
// и т.д.
} и т.д.
}
Если не пометить новую версию класса явно как new
, то код по-прежнему будет компилироваться, но компилятор будет выдавать предупреждение. Предупреждение служит для защиты от любых трудноуловимых ошибок, возникающих во время выполнения. Например, когда написана новая версия базового класса, в которой добавлен метод, имеющий, оказывается, такое же имя, как и существующий метод в производном классе.
В C# можно объявить абстрактную функцию, также как это делается в C++ (в C++ она называются еще чисто виртуальной функцией), но в C# синтаксис будет отличаться: вместо использования =0
в конце определения применяется ключевое слово abstract
.
C++:
public:
virtual void DoSomething(int X) = 0;
C#:
public abstract void Dosomething(int X);
Как и в C++, можно создать экземпляр класса, только если он сам не содержит абстрактных методов и предоставляет реализации всех абстрактных методов, которые были определены в любом из его базовых классов.
- Аргументы функции в Python
- 3. Функции
- Новые функции API для работы с Blob и массивами
- 4. Виртуальные атрибуты
- Математические функции
- Размытые функции
- 7.3. Финансовые функции
- Глава 2 Виртуальные машины Virtual PC 2004
- Глава 3 Виртуальные машины VMware Workstation
- Глава 4 Виртуальные машины Parallels Workstation
- 4.3. Логические функции и таблицы истинности
- B1.7. Функции обработки ошибок