Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка для КР по ООП.doc
Скачиваний:
8
Добавлен:
18.04.2019
Размер:
2.47 Mб
Скачать

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

При реализации принципа наследования базовый класс воплощает НАИБОЛЕЕ ОБЩИЕ черты разрабатываемого семейства классов. Поэтому на этапе разработки базового класса часто бывает достаточно лишь обозначить множество функций, которые будут определять основные черты поведения объектов-представителей производных классов.

Если базовый класс объявляется исходя из следующих предпосылок:

  • базовый класс используется исключительно как основа для объявления классов-наследников,

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

  • часть функций-членов (возможно, все) базового класса в обязательном порядке переопределяется в производных классах,

то определение таких функций даже в самых общих чертах (заголовок функции и тело, содержащее вариант оператора return) в базовом классе лишено всякого смысла.

class X

{

public int f0()

{

// Если в соответствии с замыслом разработчика, этот код ВСЕГДА будет недоступен,

// то зачем он в принципе нужен?

return 0;

}

}

class Y:X

{

new public void f0()

{

::::::::::

// Здесь размещается код переопределённой функции.

::::::::::

return 0;

}

}

Такой код никому не нужен и C# позволяет избегать таких странных конструкций. Вместо переопределяемой “заглушки” можно использовать объявление абстрактной функции.

Синтаксис объявления абстрактной функции предполагает использование ключевого слова abstract и полное отсутствие тела. Объявление абстрактной функции завершается точкой с запятой.

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

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

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

abstract class X // Абстрактный класс с одной абстрактной функцией.

{

public abstract int f0();

}

class Y:X

{

// Переопределение абстрактной функции должно

// содержать спецификатор override.

public override void f0()

{

::::::::::

return 0;

}

}

::::::::::

static void Main(string[] args)

{

X x = new X(); // NO!

Y y0 = new Y(125);

// Работает переопределённая абстрактная функция!

y0.f0();

}

Ещё пример

using System;

namespace Interface01

{

// Абстрактный класс.

abstract class aX1

{

public int xVal;

// Его конструкторы могут использоваться при построении

// объектов класов - наследников.

public aX1(int key)

{

Console.WriteLine("aX1({0})...", key);

xVal = key;

}

public aX1()

{

Console.WriteLine("aX1()...");

xVal = 0;

}

public void aX1F0(int xKey)

{

xVal = xKey;

}

public abstract void aX2F0();

}

class bX1:aX1

{

new public int xVal;

public bX1():base(10)

{

xVal = 125;

Console.WriteLine("bX1():base(10)... xVal=={0},base.xVal=={1}...", xVal, base.xVal);

}

public bX1(int key):base(key*10)

{

xVal = key;

Console.WriteLine("bX1({0}):base({1})...", xVal, base.xVal);

}

public override void aX2F0()

{

xVal = xVal*5;

base.xVal = base.xVal*100;

}

}

class Class1

{

static void Main(string[] args)

{

// Ни при каких обстоятельствах не может служить основой для

// построения объектов. Даже если не содержит ни одного объявления

// абстрактной функции.

//aX1 x = new aX1();

bX1 x0 = new bX1();

x0.aX1F0(10); // Вызвали неабстрактную функцию базового абстрактного класса.

bX1 x1 = new bX1(5);

x1.aX2F0();//Вызвали переопределённую функцию. В базовом классе это

// абстрактная функция.

}

}

}