Pragma warning 13 страница
Статические методы GetNextSerialNo и SetNextSerialNo могут обращаться к статическому полю nextSerialNo, однако при непосредственном обращении этих методов к полю экземпляра serialNo возникнет ошибка. В следующем примере показано использование класса Entity. using System; class Test Entity e1 = new Entity(); Console.WriteLine(e1.GetSerialNo()); // Outputs "1000" Обратите внимание, что статические методы SetNextSerialNo и GetNextSerialNo вызываются для класса, а метод экземпляра GetSerialNo — для экземпляра класса. 1.6.6.4 Виртуальные, переопределяющие и абстрактные методы Если объявление метода экземпляра содержит модификатор virtual, метод является виртуальным методом. Если модификатор virtual отсутствует, метод является невиртуальным методом. При вызове виртуального метода тип времени выполнения; экземпляра, для которого осуществляется вызов, определяет фактическую реализацию вызываемого метода. При вызове невиртуального метода определяющим фактором является тип времени компиляции экземпляра. Виртуальный метод может быть переопределен; в производном классе. Если объявление метода экземпляра содержит модификатор override, метод переопределяет унаследованный виртуальный метод с такой же сигнатурой. Объявление виртуального метода определяет; новый метод. Объявление переопределяющего метода уточняет; существующий виртуальный метод, предоставляя его новую реализацию. Абстрактным; называется виртуальный метод без реализации. Объявление абстрактного метода осуществляется с использованием модификатора abstract и допускается только в классе, объявленном как abstract. В каждом неабстрактном производном классе необходимо переопределять абстрактный метод. В следующем примере объявляется абстрактный класс Expression, представляющий узел дерева выражений, а также три производных класса: Constant, VariableReference и Operation, которые реализуют узлы дерева выражений для констант, ссылок на переменные и арифметических операций. (Эти классы похожи на типы дерева выражений, представленные в разделе §4.6. Однако их не следует путать.) using System; public abstract class Expression public class Constant: Expression public Constant(double value) { public override double Evaluate(Hashtable vars) { public class VariableReference: Expression public VariableReference(string name) { public override double Evaluate(Hashtable vars) { public class Operation: Expression public Operation(Expression left, char op, Expression right) { public override double Evaluate(Hashtable vars) { Четыре приведенных выше класса могут использоваться для моделирования арифметических выражений. Например, с помощью экземпляров этих классов выражение x + 3 можно представить следующим образом. Expression e = new Operation( Метод Evaluate экземпляра Expression вызывается для вычисления заданного выражения и возвращает значение типа double. Метод принимает в качестве аргумента параметр Hashtable, содержащий имена переменных (в качестве ключей записей) и значения (в качестве значений записей). Метод Evaluate представляет собой виртуальный абстрактный метод. Это означает, что в производных от него неабстрактных классах необходимо переопределить этот метод и предоставить его фактическую реализацию. Реализация Constant метода Evaluate возвращает хранящееся значение константы. Реализация VariableReference осуществляет поиск имени переменной в хэш-таблице и возвращает значение результата. Реализация Operation сначала выполняет вычисление левого и правого операндов (посредством рекурсивного вызова соответствующих методов Evaluate), а затем выполняет заданную арифметическую операцию. В следующей программе классы Expression используются для вычисления выражения x * (y + 2) с различными значениями x и y. using System; class Test Expression e = new Operation( Hashtable vars = new Hashtable(); vars["x"] = 3; vars["x"] = 1.5; 1.6.6.5 Перегрузка метода; Перегрузка; метода позволяет использовать в одном классе несколько методов с одинаковыми именами и различными сигнатурами. При компиляции вызова перегруженного метода компилятор использует разрешение перегрузки для определения конкретного вызываемого метода. С помощью разрешения перегрузки определяется метод, наиболее подходящий для заданных аргументов, или, если такой метод не найден, возвращается сообщение об ошибке. В следующем примере показано действие разрешения перегрузки. В комментариях к каждому вызову метода Main указывается, какой метод фактически вызывается. class Test static void F(object x) { static void F(int x) { static void F(double x) { static void F<T>(T x) { static void F(double x, double y) { static void Main() { Как показано в примере, конкретный метод всегда можно выбрать посредством явного приведения аргументов к соответствующим типам параметров или явного предоставления аргументов типа. 1.6.7 Другие члены-функции; Члены класса, содержащие исполняемый код, в совокупности называются члены-функции. В предыдущем разделе описаны методы, представляющие собой простые члены-функции. В этом разделе описываются другие типы членов-функций, поддерживаемые в C#: конструкторы, свойства, индексаторы, события, операторы и деструкторы. В следующей таблице описывается универсальный класс List<T>, который реализует расширяемый список объектов. Класс содержит несколько примеров наиболее распространенных типов членов-функций.
|