public override T item() { return (last.Item); }//item public override bool empty() { return (last == null); }//empty public override void put(T elem) { GenLinkable<T> newitem = new GenLinkable<T>(); newitem.Item = elem; newitem.Next = last; last = newitem; }//put public override void remove() { last = last.Next; }//remove }//class OneLinkStack Посмотрите, что происходит при наследовании от универсального класса. Во-первых, сам потомок также является универсальным классом: public class OneLinkStack<T> : GenStack<T> Во-вторых, если потомок является клиентом некоторого класса, то и этот класс, возможно, также должен быть универсальным, как в нашем случае происходит с классом GenLinkable<T>: GenLinkable<T> last; //ссылка на стек (элемент стека) В-третьих, тип T встречается в тексте потомка всюду, где речь идет о типе элементов, добавляемых в стек, как, например: public override void put(T elem) По ходу дела нам понадобился класс, задающий представление элементов стека в списковом представлении. Объявим его: public class GenLinkable<T> { public T Item; public GenLinkable<T> Next; public GenLinkable() { Item = default(T); Next = null; } } Класс устроен достаточно просто, у него два поля: одно для хранения элементов, помещаемых в стек и имеющее тип T, другое - указатель на следующий элемент. Обратите внимание на конструктор класса, в котором для инициализации элемента используется новая конструкция default(T), которая возвращает значение, устанавливаемое по умолчанию для типа T. Второй потомок абстрактного класса реализует стек по-другому, используя представление в виде массива. Потомок задает стек ограниченной емкости. Емкостью стека можно управлять в момент его создания. В ряде ситуаций использование такого стека предпочтительнее по соображениям эффективности, поскольку не требует динамического создания элементов. Приведу текст этого класса уже без дополнительных комментариев: public class ArrayUpStack<T> : GenStack<T> { int SizeOfStack; |