Reputation: 3418
I'm just trying to get the hang of separate units to make my code more encapsulated.
I'm trying to get the public/private declarations of my methods sorted out, so I can call them from other units that use testunit
. In this example I want to make hellofromotherunit
public, but stickletters
private.
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.
I could not seem to copy the private/public structure from other units as in:
Type
private
function stickletters(a,b:inter):integer;
public
procedure hellofromotherunit();
end
Upvotes: 2
Views: 8211
Reputation: 119
Simply do not declare method in interface section and it will be kept private.
unit Unit2;
interface
function MyPublicFunction():Boolean;
implementation
function MyPrivateFunction():Boolean;
begin
// blah blah
end;
function MyPublicFunction():Boolean;
begin
// blah blah
end;
end.
Upvotes: 0
Reputation: 53366
In addition,
Each unit has two distinct parts. The interface and the implementation.
The interface section contains all public definitions (types, procedure headings, constants). The implementation section contains all implementation details.
When you use a unit, (using the uses clause) you get access to the public definitions of that unit. This access is not recursive, so if unit A interface uses unit B, and unit C uses unit A, you do not get access to unit B unless you use it explicitly.
The implementation section has access to the interface, to the unit used in both uses clauses (interface and implementation).
The interfaces of used units are compiled first before it continues compiling the rest. This has the advantage that you can have circular dependencies from within the implementation:
unit A;
interface
uses B;
unit B;
interface
implementation
uses A;
Which compiles:
Each unit also has an initialization section (and if it has an initialization section, it could also have a finalization section.) The initialization section is used to initialize the variables of the unit. The finalization sections are used to cleanup. When you use these, its wise not to count on initializations of other units. Just keep them simple and short.
Unit also are namespaces. Considder the following:
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;
If an identifier is defined in multiple used units, the last unit possible in the uses list is taken. So f1 = 2. But you can prefix it with the unit (namespace) name to solve this problem.
With the introduction of .net, multi part namespaces are allowed which introduces other nice problems:
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?
In this case you have a conflict. But that is resolved by giving namespace names higher priority. So the first line fails.
Upvotes: 1
Reputation: 273179
The Unit structure looks a bit like the public/private sections from objects, you could say it is their forerunner. But the syntax is different.
You only have to declare the method header in the interface section, as in:
interface
procedure hellofromotherunit();
implementation
procedure hellofromotherunit(); begin .. end;
Only one of each section allowed.
Upvotes: 6
Reputation: 9083
Private & Public only apply to classes.
What you want to do is put a copy of the declaration of hellofromotherunit into the interface section. Do not put a copy of stickletter's declaration up there, however.
Anything that appears in the interface section is effectively public. Anything that's only down in the implementation is private.
Upvotes: 6