, заключаемым при реализации полиморфизма. О полиморфизме говорилось достаточно много в предыдущих лекциях. Тем не менее, позволю напомнить суть дела. Родитель может объявить свой метод виртуальным, в этом случае в контракте на метод потомку разрешается переопределить реализацию, но он не имеет права изменять сигнатуру виртуального метода. Когда некоторый метод родителя Q вызывает виртуальный метод F, то, благодаря позднему связыванию, реализуется полиморфизм и реально будет вызван не метод родителя F, а метод F, который реализован потомком, вызвавшим родительский метод Q. Ситуация в точности напоминает раскрутку и вызов обратных функций. Родительский метод Q находится во внутреннем слое, а потомок с его методом F определен во внешнем слое. Когда потомок вызывает метод Q из внутреннего слоя, тот, в свою очередь, вызывает метод F из внешнего слоя. Сигнатура вызываемого метода F в данном случае задается не делегатом, а сигнатурой виртуального метода, которую, согласно контракту, потомок не может изменить. Давайте вернемся к задаче вычисления интеграла и создадим реализацию, основанную на наследовании и полиморфизме. Идея примера такова. Вначале построим родительский класс, метод которого будет вычислять интеграл от некоторой подынтегральной функции, заданной виртуальным методом класса. Далее построим класс-потомок, наследующий родительский метод вычисления интеграла и переопределяющий виртуальный метод, в котором потомок задаст собственную подынтегральную функцию. При такой технологии, всякий раз, когда нужно вычислить интеграл, нужно создать класс-потомок, в котором переопределяется виртуальный метод. Приведу пример кода, следующего этой схеме: class FIntegral { //базовый класс, в котором определен метод вычисления //интеграла и виртуальный метод, задющий базовую //подынтегральную функцию public double EvaluateIntegral(double a, double b, double eps) { int n=4; double I0=0, I1 = I( a, b, n); for( n=8; n < Math.Pow(2.0,15.0); n*=2) { I0 =I1; I1=I(a,b,n); if(Math.Abs(I1-I0)<eps)break; |