Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
13
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

1.6.6.4Виртуальные, переопределяющие и абстрактные методы

Если объявление метода экземпляра содержит модификатор virtual, метод является виртуальным методом. Если модификатор virtual отсутствует, метод является невиртуальным методом.

При вызове виртуального метода тип времени выполнения экземпляра, для которого осуществляется вызов, определяет фактическую реализацию вызываемого метода. При вызове невиртуального метода определяющим фактором является тип времени компиляции экземпляра.

Виртуальный метод может быть переопределен в производном классе. Если объявление метода экземпляра содержит модификатор override, метод переопределяет унаследованный виртуальный метод с такой же сигнатурой. Объявление виртуального метода определяет новый метод. Объявление переопределяющего метода уточняет существующий виртуальный метод, предоставляя его новую реализацию.

Абстрактным называется виртуальный метод без реализации. Объявление абстрактного метода осуществляется с использованием модификатора abstract и допускается только в классе, объявленном как abstract. В каждом неабстрактном производном классе необходимо переопределять абстрактный метод.

В следующем примере объявляется абстрактный класс Expression, представляющий узел дерева выражений, а также три производных класса: Constant, VariableReference и Operation, которые реализуют узлы дерева выражений для констант, ссылок на переменные и арифметических операций. (Эти классы похожи на типы дерева выражений, представленные в разделе §4.6. Однако их не следует путать.)

using System; using System.Collections;

public abstract class Expression { public abstract double Evaluate(Hashtable vars); }

public class Constant: Expression { double value;

public Constant(double value) { this.value = value; }

public override double Evaluate(Hashtable vars) { return value; } }

public class VariableReference: Expression { string name;

public VariableReference(string name) { this.name = name; }

public override double Evaluate(Hashtable vars) { object value = vars[name]; if (value == null) { throw new Exception("Unknown variable: " + name); } return Convert.ToDouble(value); } }

public class Operation: Expression { Expression left; char op; Expression right;

public Operation(Expression left, char op, Expression right) { this.left = left; this.op = op; this.right = right; }

public override double Evaluate(Hashtable vars) { double x = left.Evaluate(vars); double y = right.Evaluate(vars); switch (op) { case '+': return x + y; case '-': return x - y; case '*': return x * y; case '/': return x / y; } throw new Exception("Unknown operator"); } }

Четыре приведенных выше класса могут использоваться для моделирования арифметических выражений. Например, с помощью экземпляров этих классов выражение x + 3 можно представить следующим образом.

Expression e = new Operation( new VariableReference("x"), '+', new Constant(3));

Метод Evaluate экземпляра Expression вызывается для вычисления заданного выражения и возвращает значение типа double. Метод принимает в качестве аргумента параметр Hashtable, содержащий имена переменных (в качестве ключей записей) и значения (в качестве значений записей). Метод Evaluate представляет собой виртуальный абстрактный метод. Это означает, что в производных от него неабстрактных классах необходимо переопределить этот метод и предоставить его фактическую реализацию.

Реализация Constant метода Evaluate возвращает хранящееся значение константы. Реализация VariableReference осуществляет поиск имени переменной в хэш-таблице и возвращает значение результата. Реализация Operation сначала выполняет вычисление левого и правого операндов (посредством рекурсивного вызова соответствующих методов Evaluate), а затем выполняет заданную арифметическую операцию.

В следующей программе классы Expression используются для вычисления выражения x * (y + 2) с различными значениями x и y.

using System; using System.Collections;

class Test { static void Main() {

Expression e = new Operation( new VariableReference("x"), '*', new Operation( new VariableReference("y"), '+', new Constant(2) ) );

Hashtable vars = new Hashtable();

vars["x"] = 3; vars["y"] = 5; Console.WriteLine(e.Evaluate(vars)); // Outputs "21"

vars["x"] = 1.5; vars["y"] = 9; Console.WriteLine(e.Evaluate(vars)); // Outputs "16.5" } }

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]