Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lektsii_po_programmirovaniyu_3_semestr.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
2.11 Mб
Скачать

Абстрактные классы.

С наследованием тесно связан еще один важный механизм проектирования семейства классов - механизм абстрактных классов. Дело в том, что, как уже отмечалось выше, можно выделить наиболее общие характеристики нескольких классов и поместить их в один родительский класс, называемый протоклассом. Но создавать экземпляры из протоклассов часто оказывается не всегда имеет смысл только потому, что им не соответствуют никакие реальные объекты. Но иногда полезно создать базовый класс, определяющий только своего рода "пустой бланк", который унаследуют все производные классы, причем каждый из них заполнит этот "бланк" собственной информацией. Такой класс определяет только состав методов, которые производные классы должны реализовать, но сам, при этом, не обеспечивает никакой реализации этих методов. В подобной ситуации используются такие понятия как абстрактные методы.

Абстрактный метод создается с помощью модификатора abstract. Абстрактный метод не имеет тела и, следовательно, не реализуется базовым классом, а производные классы должны его обязательно переопределить. Абстрактный метод автоматически является виртуальным, однако использовать спецификатор virtual не нужно. Более того, если вы попытаетесь использовать два спецификатора одновременно, abstract и virtual, то компилятор выдаст сообщение об ошибке.

Если класс содержит один или несколько абстрактных методов, то его также нужно объявить как абстрактный класс, используя спецификатор abstract перед ключевым словом class. Поскольку абстрактный класс полностью не реализован, то и невозможно будет создать его экземпляр с помощью операции new. Если же производный класс наследует абстрактный класс, то он должен полностью или частично реализовать все абстрактные методы базового класса или также быть объявлен как абстрактный. Спецификатор abstract наследуется до тех пор, пока в производном классе не будут реализованы все абстрактные методы абстрактного класса.

Совершенно очевидно, что в основе любого класса всегда лежит абстракция данных. Но абстрактный класс позволяет описывать эту абстракцию, не вникая в детали ее реализации, ограничиваясь описанием только методов, которые можно выполнять над данными такого класса. Абстрактный класс служит только для порождения потомков. Они могут иметь множество потомков, частично или полностью реализующих абстрактные методы своего родительского класса. Абстрактный метод чаще всего рассматривается как виртуальный метод, переопределяемый потомком, и поэтому к нему применяется стратегия динамического связывания.

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

// Абстрактный класс фигуры

abstract class Figura

{

Color borderColor, // Цвет контура

fillColor; // Цвет закраски

public Figura(){ borderColor=Color.Black; fillColor=Color.Red; } // Конструктор

// Функции доступа к закрытым данным:

public void SetBColor(Color c);

public void SetFColor(Color c);

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

public abstract void Draw(Graphics g);

public abstract void Move(int dx, int dy);

}

class Circle : Figura

{

// Собственные переменные:

Point pnt; // Положение центра окружности

int radius; // Радиус окружности

// Конструктор по умолчанию:

public Circle(){ pnt = new Point(200,200); radius=100; }

// Абстрактные функции базового класса, которые необходимо реализовать:

public override void Draw(Graphics g) //Реализация функции рисования

{

g.DrawCircle(…);

}

public override void Move(int dx, int dy) // Реализация функции перемещения

{ pnt.offset(dx, dy); }

}

class Rect : Figura

{

// Собственные данные:

Point p1, p2; // Положение левой-верхней и правой-нижней вершин прямоугольника

// Конструктор по умолчанию:

public Rect() { p1 = new Point(100,100); p2 = new Point(200,200); }

// Абстрактные функции базового класса, которые необходимо реализовать:

public override void Draw(Graphics g) // Собственная реализация функции рисования

{

g.DrawRectangle(…);

}

public override void Move(int dx, int dy) // Собственная реализация функции перемещения

{ p1.offset(dx, dy); p2.offset(dx, dy); }

}

Как видно из листинга, абстрактный класс фигуры содержит две переменные, конструктор и два абстрактных метода Draw и Move. Этот класс создан для того, чтобы порождать от него другие классы, характеризующие разные геометрические фигуры. В данном случае это классы описания объектов типа окружности и прямоугольника. Поскольку заранее невозможно определить какой из методов будет использоваться порождаемыми классами для своего вырисовывания или перемещения, то в базовом классе фигуры эти методы объявляются абстрактными. Но поскольку класс содержит абстрактные методы, то и сам класс объявляется как абстрактный.

Порождая производные классы окружности и прямоугольника от абстрактного класса фигуры мы с помощью модификатора override переопределяем в каждом из них абстрактные методы Draw и Move, описывая в их телах конкретную реализацию, учитывающую специфику порождаемого класса. Теперь в объявлениях классов окружности и прямоугольника можно убрать спецификатор abstract, сообщая тем самым о том, что теперь они являются полностью определенными классами, которые можно использовать для создания объектов.

Итак, подведем итоги. Класс называется абстрактным, если он имеет, хотя бы один, абстрактный метод. Метод называется абстрактным, если при определении метода задана только его сигнатура и не задана его реализация. Объявление абстрактных методов и абстрактных классов должно сопровождаться модификатором abstract. Поскольку абстрактные классы не являются полностью определенными классами, то нельзя создавать объекты абстрактных классов. При переопределении абстрактного метод базового класса в производном классе необходимо переопределить его с указанием модификатора override.

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