На рис. 6.5 обратите внимание на то, что типы Hexagon
Circle расширяют базовый класс Shape. Как и любой базовый класс. Shape определяет набор членов (в данном случае свойство PetName и метод Draw), общих для всех наследников.Во многом подобно иерархии классов для сотрудников вы должны иметь возможность запретить создание экземпляров класса Shape
Shape, его можно определить как абстрактный класс. К тому же с учетом того, что производные типы должны уникальным образом реагировать на вызов метода Draw, пометьте его как virtual и определите стандартную реализацию. Важно отметить, что конструктор помечен как protected, поэтому его можно вызывать только в производных классах.// Абстрактный базовый класс иерархии.
abstract class Shape
{
protected Shape(string name = "NoName")
{ PetName = name; }
public string PetName { get; set; }
// Единственный виртуальный метод.
public virtual void Draw
{
Console.WriteLine("Inside Shape.Draw");
}
}
Обратите внимание, что виртуальный метод Draw
Draw из базового класса Shape. Теперь вспомните, что когда метод помечен ключевым словом virtual, он поддерживает стандартную реализацию, которую автоматически наследуют все производные типы. Если дочерний класс так решит, то он может переопределить такой метод, но он не обязан это делать. Рассмотрим показанную ниже реализацию типов Circle и Hexagon:// В классе Circle метод Draw НЕ переопределяется.
class Circle : Shape
{
public Circle {}
public Circle(string name) : base(name){}
}
// В классе Hexagon метод Draw переопределяется.
class Hexagon : Shape
{
public Hexagon {}
public Hexagon(string name) : base(name){}
public override void Draw
{
Console.WriteLine("Drawing {0} the Hexagon", PetName);
}
}
Полезность абстрактных методов становится совершенно ясной, как только вы снова вспомните, что подклассы
Circle). Следовательно, если создать экземпляры типов Hexagon и Circle, то обнаружится, что Hexagon знает, как правильно "рисовать" себя (или, по крайней мере, выводить на консоль подходящее сообщение). Тем не менее, реакция Circle порядком сбивает с толку.Console.WriteLine("***** Fun with Polymorphism *****\n");
Hexagon hex = new Hexagon("Beth");
hex.Draw;
Circle cir = new Circle("Cindy");
// Вызывает реализацию базового класса!
cir.Draw;
Console.ReadLine;
Взгляните на вывод предыдущего кода:
***** Fun with Polymorphism *****
Drawing Beth the Hexagon
Inside Shape.Draw
Очевидно, что это не самое разумное проектное решение для текущей иерархии. Чтобы вынудить каждый дочерний класс переопределять метод Draw
Shape, т.е. какая-либо стандартная реализация вообще не предлагается. Для пометки метода как абстрактного в C# используется ключевое слово abstract. Обратите внимание, что абстрактные методы не предоставляют никакой реализации:abstract class Shape
{
// Вынудить все дочерние классы определять способ своей визуализации.
public abstract void Draw;
...
}
На заметку!
Абстрактные методы могут быть определены только в абстрактных классах, иначе возникнет ошибка на этапе компиляции.Методы, помеченные как abstrac
Shape информирует производные типы о том, что у него есть метод по имени Draw, который не принимает аргументов и ничего не возвращает. О необходимых деталях должен позаботиться производный класс.Бьёрн Страуструп , Ирина Сергеевна Козлова , Бьерн Страуструп , Валерий Федорович Альмухаметов
Программирование, программы, базы данных / Базы данных / Программирование / Учебная и научная литература / Образование и наука / Книги по IT