Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лек_ООП_2_8 - 2_9 Реалізація поліморфізму та Ш...doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
291 Кб
Скачать
☆

Абстрактные функции и абстрактные классы

Когда класс содержит хотя бы одну функцию без тела (абстрактную функцию), он называется абстрактным классом, и от него нельзя порождать объекты, хотя можно ему наследовать.

abstract class Figure

{

public string name; // Имя фигуры

protected abstract double Area {get;}; // Расчет площади фигуры

public abstract Figure Rotate(double ang); // Поворот фигуры

public void Print_S()// Вывод площади фигуры на консоль

{ Console.WriteLine("{1}: Площадь = {0:F3}", Area, name); }

}

class Square: Figure

{ protected double x = 10; // Сторона, (мм)

public Square() { name = "Квадрат"; }

protected override double Area{get{ return x * x; }}

public override Figure Rotate(double ang) { return this; }

public void Print_X()

{ Console.WriteLine("{1} со стороной {0:F1} мм ", x, name); }

}

class Rhumb : Square

{ public Rhumb() { name = "Ромб"; }

double a = Math.PI/4; // Угол, (рад)

protected override double Area{get{ return x * x * Math.Sin(a); }}

public new void Print_X()

{ base.Print_X();

Console.WriteLine("{1} с углом {0:F1} град. ", a*180.0/Math.PI, name);

}

}

class Program

{

static void Main()

{

Rhumb r1 = new Rhumb();

r1.Print_X();

r1.Print_S();

Console.ReadKey();

}

}

Зачем это нужно?

Посмотрите на диаграмму классов подвижных объектов. Большая часть функций сосредоточена в первом и последнем классах. Есть ли этому рациональное объяснение?

В действительности, в этой иерархии классов пересекаются две предметные области: физика (механика) и транспорт (логистика).

Физика представлена базовым классом «Движущийся объект». Это самодостаточный класс, от него имеет смысл порождать объекты (материальные точки) для решения задач движения в пространстве.

Транспорт представлен тремя классами: «Наземный движущийся объект», «Автомобиль» и «Грузовой автомобиль». Из них только от последнего имеет смысл порождать объекты для моделирования перевозок. Первые два нужны для последовательной, поэтапной конкретизации объектной модели. А значит, некоторые из используемых в них методов могут и не иметь реализации в собственном (абстрактном) классе, так как на этом уровне абстракции еще не ясно, как их программировать. Поэтому следует запретить порождение объектов от промежуточных классов, объявив их абстрактными. А нереализованные методы обозначить «схематически» с помощью абстрактных функций, и тем самым предписать их обязательную реализацию тем классам-потомкам, от которых будут порождаться объекты.

Классически пример – иерархия классов геометрических фигур.

Конечно, имеет смысл определить общий базовый класс “фигура”. Тогда можно будет представлять наборы разнородных фигур в виде единообразных списков или массивов. Но нет смысла создавать представителей собственно класса “фигура”. Не бывает в мире просто фигур. Фигура – это абстракция.

С другой стороны, каждый конкретный класс фигур должен иметь метод “нарисовать”. Чтобы этот метод был виртуальным, его должен объявлять базовый класс (как виртуальный, естественно). Но что может делать такой метод, если неизвестно, что рисовать? Конечно, можно написать функцию, которая ничего не делает или возвращает состояние ошибки. Но гораздо лучше объявить такую функцию-элемент базового класса как абстрактную. Тем самым будет образована виртуальная база для переопределения в производных классах, а также запрещено явное или неявное создание представителей базового класса.

Виртуальная функция-элемент некоторого класса может быть объявлена абстрактной. Для этого ключевое слово virtual заменяется на abstract:

abstract тип имя функции(список параметров);

Тело у абстрактной функции отсутствует.

Абстрактные функции могут содержаться только в классе, объявленном абстрактным классом – с модификатором abstract.

Абстрактная функция должна переопределяться в классах, производных от абстрактного класса.