Полиморфизм и виртуальные функции

April 7, 2010 by admin Комментировать »

Недавно, когда автор программировал музыкальную систему, было принято решение, что в качестве механизмов воспроизведения система должна поддерживать как WinAmp, так и Windows Media Player, однако при этом программный код не должен знать, какой именно механизм используется. Исходя из этого, был определен абстрактный класс (abstract class), то есть класс, функции которого должны быть реализованы в производном классе, и который иногда содержит функции, используемые несколькими потомками.

В этом примере абстрактный класс назывался MusicServer, и в нем определялись обычные для музыкальной системы функции воспроизведения, перехода к следующей записи, приостановки и пр. (Play(), NextSong(), Pause() и т. д.). Все эти функции объявлялись как абстрактные, чтобы каждый производный класс реализовывал эти функции самостоятельно.

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

Вероятно, сказанное лучше пояснить на примере. Наша музыкальная система поддерживает два механизма воспроизведения, WinAmp и Windows Media Player. Примерный вид базовой структуры классов приведен ниже.

using System;

public abstract class MusicServer

{

public abstract void Play();

}

public class WinAmpServer: MusicServer

{

public override void Play()

{

Console.WriteLine("WinAmpServer.Play()");

}

}

public class MediaServer: MusicServer

{

public override void Play()

{

Console.WriteLine("MediaServer.Play()");

}

}

class Test

{

public static void CallPlay(MusicServer ms)

{

ms.Play();

}

public static void Main()

{

MusicServer ms = new WinAmpServer();

CallPlay(ms);

ms = new MediaServer();

CallPlay(ms);

}

}

Программа выдает следующие результаты:

WinAmpServer.Play()

MediaServer.Play()

Полиморфизм и виртуальные функции используются в системе .NET Runtime довольно часто. Например, пусть у базового объекта object имеется виртуальная функция ToString(), преобразующая объект в его строковое представление. Если вызвать функцию ToString() для объекта, не имеющего собственной версии этой функции, будет вызвана версия ToString() класса object[1], которая просто возвращает имя класса. Если вы перегрузите функцию ToString() (то есть создадите собственную версию этой функции), будет вызвана ваша версия, которая делает нечто более осмысленное — например, выводит имя работника, информация о котором содержится в объекте employee. В музыкальной системе это означает перегрузку функций для воспроизведения, приостановки, перехода к следующей записи и т. д.


[1] Если у объекта имеется базовый класс, определяющий функцию ToString(), вызывается версия ToString() базового класса.

Оставить комментарий

микросхемы мощности Устройство импульсов питания пример приемника провода витков генератора выходе напряжение напряжения нагрузки радоэлектроника работы сигнал сигнала сигналов управления сопротивление усилитель усилителя усиления устройства схема теория транзистора транзисторов частоты