C# для профессионалов. Том II
Шрифт:
Синтаксис деструктора по сути такой же в C#, как и в C++. Отметим, что в C# не требуется объявлять деструктор виртуальным, компилятор будет это подразумевать. Не требуется также предоставлять модификатор доступа:
Хотя метод
Отметим, что приведенный выше код будет компилироваться успешно только если
Наследование
Наследование работает в основном таким же образом в C#, как и в C++, с тем исключением, что множественная реализация наследования не поддерживается. Компания Microsoft считает, что множественное наследование ведет к коду, который хуже структурирован и который труднее сопровождать, и поэтому решила исключить это свойство из C#.
В C++ указатель на класс может дополнительно указывать на экземпляр производного класса. (Виртуальные функции в конце концов зависят от этого факта.) В C# классы доступны через ссылки, но правило остается тем же. Ссылка на класс может ссылаться на экземпляры этого класса или на экземпляры любого производного класса.
Если желательно, чтобы ссылка ссылалась на произвольный объект (эквивалент
Виртуальные и невиртуальные функции
Виртуальные функции поддерживаются в C# таким же образом, как и в C++. Однако в C# существуют некоторые синтаксические отличия, которые созданы, чтобы исключить возможную неоднозначность в C++. Это означает, что некоторые типы ошибок, которые появляются в C++ только во время выполнения, будут идентифицированы в C# во время компиляции.
Отметим также, что в C# классы всегда доступны по ссылке (что эквивалентно доступу через указатель в C++).
Если в C++ требуется, чтобы функция была виртуальной необходимо просто определить ключевое слово
Важный момент этого синтаксиса состоит в том, что он дает понять компилятору, как интерпретировать функцию, и значит, исключается риск таких ошибок, где, например, вводится слегка неправильная сигнатура метода в переопределяемой версии, и поэтому определяется новая функция вместо переопределения существующей. Компилятор будет отмечать ошибку, если функция помечена как
Если функция не является виртуальной, то можно все равно определить версии этого метода в производном классе, в этом случае говорят, что версия производного класса скрывает версию базового класса, а вызываемый метод зависит только от типа ссылки, используемой для доступа к классу, так же как это зависит от типа указателя, используемого для доступа к классу в C++.
В случае, если в C# версия функции в производном классе скрывает соответствующую функцию в базовом классе, можно явно указать это с помощью ключевого слова
Если не пометить новую версию класса явно как
В C# можно объявить абстрактную функцию, также как это делается в C++ (в C++ она называются еще чисто виртуальной функцией), но в C# синтаксис будет отличаться: вместо использования
C++:
C#:
Как и в C++, можно создать экземпляр класса, только если он сам не содержит абстрактных методов и предоставляет реализации всех абстрактных методов, которые были определены в любом из его базовых классов.