Как использовать юнит-файлы в Delphi

Я просто пытаюсь освоить отдельные блоки, чтобы сделать мой код более инкапсулированным. Я пытаюсь разобраться с публичными/приватными объявлениями моих методов, чтобы я мог вызывать их из других модулей, использующих testunit. В этом примере я хочу сделать hellofromotherunit общедоступным, а stickletters закрытым.

unit testunit;    

interface

uses
  Windows, Messages, Dialogs;    

implementation

function stickletters(a,b:string):string;
begin
  result:=a+b;
end;

procedure hellofromotherunit();
begin
 showmessage(stickletters('h','i'));
end;

end.

Кажется, я не мог скопировать частную/общедоступную структуру из других единиц, как в:

Type
private
function stickletters(a,b:inter):integer;
public
procedure hellofromotherunit();
end

person Arthur    schedule 03.04.2009    source источник


Ответы (4)


Структура Unit немного напоминает разделы public/private из объектов, можно сказать, что это их предшественник. Но синтаксис другой.

Вам нужно только объявить заголовок метода в разделе интерфейса, например:

interface
  procedure hellofromotherunit();

implementation
  procedure hellofromotherunit(); begin .. end;

Разрешено только одно из каждого раздела.

person Henk Holterman    schedule 03.04.2009

Частные и общедоступные применяются только к классам.

Что вам нужно сделать, так это поместить копию объявления hellofromotherunit в раздел интерфейса. Однако не кладите туда копию письма с письма.

Все, что появляется в разделе интерфейса, является общедоступным. Все, что есть только в реализации, является частным.

person Loren Pechtel    schedule 03.04.2009

Кроме того,

Каждая единица состоит из двух отдельных частей. Интерфейс и реализация.

Раздел интерфейса содержит все общедоступные определения (типы, заголовки процедур, константы). Раздел реализации содержит все детали реализации.

Когда вы используете модуль (используя предложение uses), вы получаете доступ к общедоступным определениям этого модуля. Этот доступ не является рекурсивным, поэтому, если интерфейс модуля A использует модуль B, а модуль C использует модуль A, вы не получите доступ к модулю B, если не используете его явно.

Секция реализации имеет доступ к интерфейсу, к единице, используемой в обоих разделах использования (интерфейс и реализация).

Сначала компилируются интерфейсы используемых модулей, а потом компилируются остальные. Это имеет то преимущество, что вы можете иметь циклические зависимости внутри реализации:

unit A;
interface
uses B;

unit B;
interface
implementation
uses A;

Что компилируется:

  • попробуйте интерфейс A, не нужен B
  • попробуйте интерфейс B, хорошо!
  • попробуйте интерфейс A, хорошо!
  • попробуйте реализацию А, хорошо!
  • попробуйте реализацию B, хорошо!

Каждый модуль также имеет раздел инициализации (а если он имеет раздел инициализации, он также может иметь раздел финализации). Раздел инициализации используется для инициализации переменных модуля. Разделы финализации используются для очистки. Когда вы используете их, разумно не рассчитывать на инициализацию других модулей. Просто держите их простыми и короткими.

Модуль также является пространством имен. Учтите следующее:

unit A;
interface
const foo = 1;

unit B;
interface
const foo = 2;

unit C;
interface
uses A, B;

const
  f1 = foo;
  f2 = A.foo;
  f3 = B.foo;

Если идентификатор определен в нескольких используемых единицах, берется последняя возможная единица в списке использований. Таким образом, f1 = 2. Но вы можете добавить к нему префикс имени модуля (пространства имен), чтобы решить эту проблему.

С введением .net разрешены пространства имен, состоящие из нескольких частей, что создает другие приятные проблемы:

unit foo;
interface
type
  rec1 = record
    baz : Boolean;
  end;
var
  bar : rec1;

unit foo.bar;
interface
var
  baz : Integer;

uses
  foo, foo.bar;    
begin
  foo.bar.baz := true;
  foo.bar.baz := 1;
end.  

// 1. Which these lines gives an error and why?
// 2. Does the result change if you write uses foo.bar, foo?

В этом случае у вас конфликт. Но это решается путем присвоения именам пространств имен более высокого приоритета. Итак, первая строка не работает.

person Toon Krijthe    schedule 06.04.2009

Просто не объявляйте метод в разделе интерфейса, и он останется приватным.

unit Unit2;

interface
  function MyPublicFunction():Boolean;

implementation

function MyPrivateFunction():Boolean;
begin
  // blah blah
end;

function MyPublicFunction():Boolean;
begin
  // blah blah
end;
end.
person Shadab Mozaffar    schedule 21.09.2016