<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="https://gsbelarus.com:80/gs/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>https://gsbelarus.com:80/gs/wiki/index.php?action=history&amp;feed=atom&amp;title=%D0%9F%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D0%BA_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%B0_%D0%BF%D0%B5%D1%80%D0%B5%D0%BA%D1%80%D1%8B%D1%82%D1%8B%D1%85_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%B2</id>
		<title>Порядок вызова перекрытых методов - История изменений</title>
		<link rel="self" type="application/atom+xml" href="https://gsbelarus.com:80/gs/wiki/index.php?action=history&amp;feed=atom&amp;title=%D0%9F%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D0%BA_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%B0_%D0%BF%D0%B5%D1%80%D0%B5%D0%BA%D1%80%D1%8B%D1%82%D1%8B%D1%85_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%B2"/>
		<link rel="alternate" type="text/html" href="https://gsbelarus.com:80/gs/wiki/index.php?title=%D0%9F%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D0%BA_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%B0_%D0%BF%D0%B5%D1%80%D0%B5%D0%BA%D1%80%D1%8B%D1%82%D1%8B%D1%85_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%B2&amp;action=history"/>
		<updated>2026-07-16T18:05:05Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.19.16</generator>

	<entry>
		<id>https://gsbelarus.com:80/gs/wiki/index.php?title=%D0%9F%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D0%BA_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%B0_%D0%BF%D0%B5%D1%80%D0%B5%D0%BA%D1%80%D1%8B%D1%82%D1%8B%D1%85_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%B2&amp;diff=6020&amp;oldid=prev</id>
		<title>SYSDBA: Новая страница: «Порядок вызова перекрытых методов в случае множественного наследования рассмотрим на т…»</title>
		<link rel="alternate" type="text/html" href="https://gsbelarus.com:80/gs/wiki/index.php?title=%D0%9F%D0%BE%D1%80%D1%8F%D0%B4%D0%BE%D0%BA_%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%B0_%D0%BF%D0%B5%D1%80%D0%B5%D0%BA%D1%80%D1%8B%D1%82%D1%8B%D1%85_%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%B2&amp;diff=6020&amp;oldid=prev"/>
				<updated>2014-06-18T10:46:57Z</updated>
		
		<summary type="html">&lt;p&gt;Новая страница: «Порядок вызова перекрытых методов в случае множественного наследования рассмотрим на т…»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Порядок вызова перекрытых методов в случае множественного наследования рассмотрим на таком примере. Пусть в платформе определен '''ClassA''' -- пользовательский справочник. От него наследуется '''ClassB'''. Для этих классов перекрыт метод '''DoBeforeOpen''' c вызовом '''Inherited'''. У нас на руках экземпляр класса '''ClassB''', который мы пытаемся открыть ('''Open'''), в процессе чего происходит вызов метода '''DoBeforeOpen'''. Тогда последовательность выполнения программного кода будет выглядеть следующим образом:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
http://gsbelarus.com/gs/images/gs/2014/polymorphism.png&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''1''' -- '''ClassA''' и '''ClassB''' -- это исключительно порождения платформы о которых Делфи ничего не известно. Для системы объект имеет тип '''TgdcAttrUserDefined'''.&lt;br /&gt;
&lt;br /&gt;
'''2''' -- Поскольку для '''TgdcAttrUserDefined''' нет метода '''DoBeforeOpen''', через VMT попадаем на метод родителя -- '''TgdcBase.DoBeforeOpen'''.&lt;br /&gt;
&lt;br /&gt;
'''3''' -- Тело метода начинается с кода, который отвечает за вызов перекрытых методов в платформе. На вставке ниже, строки, начинающиеся с комментария: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Delphi&amp;quot;&amp;gt;&lt;br /&gt;
procedure TgdcBase.DoBeforeOpen;&lt;br /&gt;
  {@UNFOLD MACRO INH_ORIG_PARAMS(VAR)}&lt;br /&gt;
  {M}VAR&lt;br /&gt;
  {M}  Params, LResult: Variant;&lt;br /&gt;
  {M}  tmpStrings: TStackStrings;&lt;br /&gt;
  {END MACRO}&lt;br /&gt;
begin&lt;br /&gt;
  {@UNFOLD MACRO INH_ORIG_WITHOUTPARAM('TGDCBASE', 'DOBEFOREOPEN', KEYDOBEFOREOPEN)}&lt;br /&gt;
  {M}  try&lt;br /&gt;
  {M}    if (not FDataTransfer) and Assigned(gdcBaseMethodControl) then&lt;br /&gt;
  {M}    begin&lt;br /&gt;
  {M}      SetFirstMethodAssoc('TGDCBASE', KEYDOBEFOREOPEN);&lt;br /&gt;
  {M}      tmpStrings := TStackStrings(ClassMethodAssoc.IntByKey[KEYDOBEFOREOPEN]);&lt;br /&gt;
  {M}      if (tmpStrings = nil) or (tmpStrings.IndexOf('TGDCBASE') = -1) then&lt;br /&gt;
  {M}      begin&lt;br /&gt;
  {M}        Params := VarArrayOf([GetGdcInterface(Self)]);&lt;br /&gt;
  {M}        if gdcBaseMethodControl.ExecuteMethodNew(ClassMethodAssoc, Self, 'TGDCBASE',&lt;br /&gt;
  {M}          'DOBEFOREOPEN', KEYDOBEFOREOPEN, Params, LResult) then exit;&lt;br /&gt;
  {M}      end else&lt;br /&gt;
  {M}        if tmpStrings.LastClass.gdClassName &amp;lt;&amp;gt; 'TGDCBASE' then&lt;br /&gt;
  {M}        begin&lt;br /&gt;
  {M}          Inherited;&lt;br /&gt;
  {M}          Exit;&lt;br /&gt;
  {M}        end;&lt;br /&gt;
  {M}    end;&lt;br /&gt;
  {END MACRO}&lt;br /&gt;
&lt;br /&gt;
  if (not CanView) and (not IBLogin.IsUserAdmin) then&lt;br /&gt;
  begin&lt;br /&gt;
    if SubType &amp;gt; '' then&lt;br /&gt;
      raise EgdcUserHaventRights.CreateFmt(strHaventRights,&lt;br /&gt;
        [strView, ClassName, SubType, GetDisplayName(SubType)])&lt;br /&gt;
    else&lt;br /&gt;
      raise EgdcUserHaventRights.CreateFmt(strHaventRightsShort,&lt;br /&gt;
        [strView, ClassName])&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  if not FSQLInitialized then&lt;br /&gt;
    InitSQL;&lt;br /&gt;
&lt;br /&gt;
  if HasSubSet('ByID') and (FID &amp;gt; -1) then&lt;br /&gt;
    ParamByName(GetKeyField(SubType)).AsInteger := FID&lt;br /&gt;
  else if HasSubSet('ByName') and (FObjectName &amp;gt; '') then&lt;br /&gt;
    ParamByName(GetListField(SubType)).AsString := FObjectName;&lt;br /&gt;
&lt;br /&gt;
  inherited DoBeforeOpen;&lt;br /&gt;
&lt;br /&gt;
  {@UNFOLD MACRO INH_ORIG_FINALLY('TGDCBASE', 'DOBEFOREOPEN', KEYDOBEFOREOPEN)}&lt;br /&gt;
  {M}  finally&lt;br /&gt;
  {M}    if (not FDataTransfer) and Assigned(gdcBaseMethodControl) then&lt;br /&gt;
  {M}      ClearMacrosStack2('TGDCBASE', 'DOBEFOREOPEN', KEYDOBEFOREOPEN);&lt;br /&gt;
  {M}  end;&lt;br /&gt;
  {END MACRO}&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Именно здесь вступает в силу '''Подтип''' нашего объекта и система начинает понимать, что мы имеем дело с экземпляром '''TgdcAttrUserDefined&amp;lt;span style=&amp;quot;color: red;&amp;quot;&amp;gt;ClassB&amp;lt;/span&amp;gt;''', а не '''TgdcAttrUserDefined'''. В базе данных отыскивается скрипт-функция перекрытого метода, загружается в скрипт-контрол и запускается на выполнение.&lt;br /&gt;
&lt;br /&gt;
'''4''' -- По магическому слову '''Inherited''' мы снова оказываемся в движке платформы. Для класса '''TgdcAttrUserDefinedClassB''' будет найден родитель -- '''TgdcAttrUserDefinedClassA'''. Для него загружена скрипт-функция перекрытого метода и запущена на выполнение.&lt;br /&gt;
&lt;br /&gt;
'''5''' -- Снова вызов '''Inherited''' из скрипт-функции. На этот раз родитель -- делфовский класс '''TgdcAttrUserDefined'''. Для него нет метода '''DoBeforeOpen''' и мы возвращаемся в '''TgdcBase.DoBeforeOpen'''. Служебный код, отвечающий за связь Делфи с VBScript, закончился. Начинается логика метода '''DoBeforeOpen'''.&lt;br /&gt;
&lt;br /&gt;
'''6, 7''' -- По вызову '''inherited''' перейдем на уровень родителя -- '''TCustomIBDataSet.DoBeforeOpen'''. По завершении -- вернемся обратно.&lt;br /&gt;
&lt;br /&gt;
'''8''' -- Собственно, логика метода '''DoBeforeOpen''' закончилась. Снова служебный код, который сращивает статичный, однажды откомпилированный код Делфи и динамичный, интерпретируемый код из VBScript. Возращаемся в место вызова -- '''TgdcAttrUserDefinedClassA.DoBeforeOpen''', сразу после слова '''Inherited'''.&lt;br /&gt;
&lt;br /&gt;
'''9''' -- Когда выполнение скрипт-функции перекрытого метода закончится, движок платформы вернет нас к прерванному '''TgdcAttrUserDefinedClassB.DoBeforeOpen'''.&lt;br /&gt;
&lt;br /&gt;
'''A, B, C''' -- Скрипты закончились. Завершаем метод '''TgdcBase.DoBeforeOpen'''. Затем, минуя несуществующий '''TgdcAttrUserDefined.DoBeforeOpen''', возвращаемся к продолжению программы.&lt;br /&gt;
&lt;br /&gt;
[[Category:Бизнес-объект]]&lt;br /&gt;
[[Category:Руководство разработчика]]&lt;br /&gt;
[[Category:VBScript]]&lt;/div&gt;</summary>
		<author><name>SYSDBA</name></author>	</entry>

	</feed>