При использовании динамики:
procedure InStack(var TopStack:TTopStack, Elem:TElem);
function OutStack(var TopStack:TTopStack, var Elem: TElem) :boolean;
В этих случаях для использования стека программисту нужно: во-первых самому организовать структуры данных, во-вторых, вызывать подпрограммы работы со стеком с нужными переменными (если например стеков несколько). Таким образом никакой независимости от реализации стека у использующей ее программы нет.
Рассмотрим как будут выглядеть объекты реализующие статический и динамический стеки:

Описание объекта не является полным, отсутствуют элементы, отвечающие за создание и уничтожение объекта. Они будут рассмотрены позднее.
.
Описание объекта также не является полным.
Использование:
Var
DSStack:TDObStack;
SStack:TSObStack;
. . .
A:TElem;
Begin
. . .
DStack.InStack(a);
SStack.InStack(a);
. . .
if not (DStack.OutStack(a)) writeln(‘Динамический стек пуст’);
if not (SStack.OutStack(a)) writeln(‘Статический стек пуст’);
. . .
End;
Программисту, использующему любой из этих объектов достаточно создать один или несколько экземпляров объекта (как именно рассмотрим далее) и вызывать нужный метод. Особенности реализации стека при этом остаются скрытыми и не оказывают влияния на написание программы. Связь между конкретным набором данных (конкретным стеком с занесенными в него элементами) и вызываемыми методами, как уже было сказано ранее будет выполняться автоматически за счет того, что при вызове им передается указатель на тот объект, который их вызвал. Рассмотрим далее, что такое свойство.
Правило инкапсуляции утверждает, что для обеспечения надежности нежелателен прямой доступ к полям объекта: чтение и обновление их содержимого должно производиться вызовом соответствующих методов. В языке Object Pascal имеется соответствующая конструкция, которая позволяет запретить прямой доступ к полю - пользователь объекта может быть полностью отгорожен от полей при помощи свойств. Обычно свойство определяется тремя элементами: объявлением собственно свойства и двумя методами, которые осуществляют его чтение и запись:
Type
TAnObject = class(TObject)
Function GetAProperty: TSomeType;
procedure SetAProperty(ANewValue: TSomeType);
property AProperty:TSomeType read GetAProperty write SetAProperty;
end;
Функция, имя которой указывается после директивы read служит для чтения значения свойства. Она не имеет параметров, тип возвращаемого значения совпадает с типом свойства. Процедура, указанная после директивы write служит для установки значения свойства. Она имеет единственный параметр, чей тип совпадает с типом свойства. В приведенном примере доступ к значению свойства AProperty осуществляется через вызов методов GetAProperty и SetAProperty, Однако в обращении к этим методам в явном виде нет необходимости, достаточно написать:
AnObject.AProperty := AValue;
AVariable := AnObject. AProperty;
И компилятор оттранслирует эти операторы в вызовы методов. То есть внешне свойство выглядит в точности как обычное поле, но за всяким обращением к нему могут стоять нужные вам действия. Например, если у вас есть объект, представляющий собой квадрат на экране, и его свойству «цвет» вы присваиваете значение «белый», то произойдет немедленная перерисовка, приводящая реальный цвет на экране в соответствие значению свойства. Можно изменять значения свойств, вызывая соответствующие методы, хотя это и нерационально:
AnObject.SetAProperty(AValue);
AVariable := AnObject.GetAProperty;
Важно отметить следующее, хотя для работы со свойством используется тот же синтаксис что и при работе с обычным полем, это не поле. И память под хранение значения не выделяется. Место для хранения значения свойства программист должен организовать дополнительно. Это может быть поле. Тогда методы чтения и записи свойства должны читать и записывать содержимое этого поля. Это может быть динамически распределяемая память, это может быть файл.
В методах, входящих в состав свойств, может осуществляться проверка устанавливаемой величины на попадание в допустимый диапазон значений и вызов других процедур, зависящих от вносимых изменений. Если потребности в специальных процедурах чтения или записи отсутствуют и для хранения значения свойства используется поле, можно вместо имен методов использовать имя этого поля. Рассмотрим следующий пример:
TScreenElem = class (TOblect)
FColor:TColor;
procedure Paint(C:TColor);
function Correct(C:TColor):Boolean;
procedure SetColor (NewColor:TColor);
property Color:TColor read FColor write SetColor;
end;
. . .
procedure TScreenElem. SetColor (NewColor. - TColor) ;
Begin
if (NewCoIor=FColor) and Correct (NewColor) then
begin
PColor:=NewColor;
Paint(NewColor) ;
end;
End;
В этом примере чтение значения свойства цвета экранного элемента Color означает просто чтение поля FColor. Зато при присвоении значения внутри SetColor вызывается сразу два метода: проверки корректности заданного значения цвета Correct и перерисовки экранного элемента Paint.
Если свойство должно только читаться или только записываться, в его описании может присутствовать только соответствующий метод:
Type
TanObject =class(TObject)
…
property AProperty:TSomeType read GetValue;
end;