Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSBasicCourse2ndedPodbelsky / CSBasicCourse2ndedPodbelsky.rtf
Скачиваний:
27
Добавлен:
22.03.2016
Размер:
11.9 Mб
Скачать

13.6. Абстрактные методы и абстрактные классы

В ряде случаев класс создается только как базовый, и его автор н

е

предполагает, что кто-то будет создавать объекты этого класса вне наследования.

Например, объекты уже рассмотренного в примерах класса фигур с заданными

габаритами вряд ли пригодны для метода, который вычисляет площадь или периметр

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

габариты. Однако, в базовом классе можно "запланировать" проведение этих

вычислений в производных классах. Для этого в базовый класс добавляют так

называемые абстрактные методы, и класс объявляют абстрактным. Абстрактные

методы задают сигнатуру реальных методов, которые должны быть реализованы в

классах, производных от абстрактного.

Абстрактный метод

"метод:абстрактный метод"

может быть объявлен

только в абстрактном классе "класс:абстрактный класс" . В заголовке абстрактного

метода указывается модификатор abstract. У абстрактного метода после скобки,

ограничивающей спецификацию параметров, помещается символ точка с запятой. У

абстрактного метода не может быть тела в виде блока операторов в фигурных

скобках. Абстрактный метод по умолчанию является виртуальным. Таким образом

добавлять модификатор virtual не требуется.

Для того чтобы класс был определен как абстрактный, в его заголовок

помещают модификатор abstract. Создавать объекты абстрактных классов

невозможно. Если в абстрактном классе объявлены несколько абстрактных

методов, а производный класс содержит реализацию не всех из них, то производный

класс в свою очередь становится абстрактным. В абстрактном классе могут быть

определены любые не абстрактные члены (методы, поля, свойства и т.д.). Кроме

того, класс может быть объявлен абстрактным даже в том случае, если в нём

отсутствуют абстрактные члены.

Продемонстрируем особенности использования абстрактных классов и

абстрактных методов на примере классов, производных от класса "фигура на

плоскости". Превратим этот базовый класс в абстрактный, добавив в него

абстрактный метод для вычисления площади фигуры. Метод вывода сведений о

б

объекте класса также сделаем абстрактным. Для иллюстрации объявим в этом

классе не виртуальный метод, выполняющий сжатие (или увеличение) габаритных

размеров фигуры в заданное число раз. Текст программы с таким классом:

// 13_12.cs - абстрактные методы в абстрактном классе

using System;

abstract class Figure // абстрактный базовый класс

{

protected double dx, dy; // размеры вдоль осей

public abstract void print();

public void compress(double r) { dx *= r; dy *= r; }

abstract public double square();

}

class Rectangle : Figure {

public Rectangle(double xi, double yi)

{ dx = xi; dy = yi; }

public override void print() {

Console.Write("Площадь прямоугольника={0:f2}. \t", square());

Console.WriteLine("Габариты: dx={0:f2}, dy={1:f2}", dx, dy);

}

public override double square()

{ return dx * dy; }

}

class Triangle : Figure {

public Triangle(double xi, double yi)

{ dx = xi; dy = yi; }

public override void print(){

Console.Write("Площадь треугольника={0:f2}. \t", square());

Console.WriteLine("Габариты: dx={0:f2}, dy={1:f2}", dx, dy);

}

public override double square()

{ return dx * dy / 2; }

}

class Program

{

static void Main()

{

Figure fig = new Rectangle(3.0, 4.0);

fig.print();

fig = new Triangle(5.0, 4.0);

fig.print();

fig.compress(2.0);

fig.print();

Triangle tri = new Triangle(8.0, 4.0);

tri.print();

tri.compress(0.25);

tri.print();

}

}

Результат выполнения программы:

Площадь прямоугольника=12,00. Габариты: dx=3,00, dy=4,00

Площадь треугольника=10,00. Габариты: dx=5,00, dy=4,00

Площадь треугольника=22,50. Габариты: dx=7,50, dy=6,00

Площадь треугольника=16,00. Габариты: dx=8,00, dy=4,00

Площадь треугольника=1,00. Габариты: dx=2,00, dy=1,00

В методе Main( ) определены две ссылки fig и tri. Первая имеет тип базового

класса Figure и адресует вначале объект производного класса Rectangle, затем

производного объект класса Triangle. Ссылка fig обеспечивает обращения к

перегруженным методам print() производных классов Rectangle и Triangle. Ссылка

tri может адресовать только объекты класса Rectangle и способна обеспечить вызов

метода print() только этого же производного класса. В то же время для этой ссылки

(и для ссылки fig) доступен метод сompress() базового класса, унаследованный

производными классами. Результаты выполнения программы иллюстрируют

сказанное.

Завершая рассмотрение наследования классов, повторим, что в производном

классе метод по отношению к методу базового класса может быть новым,

перегруженным,

унаследованным,

скрывающим

(экранирующим)

метод

базового класса и реализующим виртуальный или абстрактный метод базового

класса.

Соседние файлы в папке CSBasicCourse2ndedPodbelsky