Icon Scope

The scope (visibility) of a constant, type/class, or function/procedure declaration is determined by where it appears in a unit, class, or function/procedure.

Unit Scope
The scope of declarations in a unit are determined by whether they are declared in the interface or implementation section of a unit:
  • Any declaration in the interface section of a unit is visible to all other declarations or function/procedure implementations in either the interface or implementation sections of the same unit, as well as being visible to the same sections in any units that reference the unit. The interface section of a unit is essentially "public" to everything.


  • Any declaration in the implementation section of a unit is visible to all other declarations in the same implementation section only.
unit Unit1;

interface

// Public to this unit and all referencing units

implementation

// Private to this unit

end.

Function/Procedure Implementation Scope
The implementations of functions and procedures only have one level of scope, and that is the scope of any parameters or local variables, as well as the special Result variable for functions. Parameters and local variables can only be referenced within the function/procedure in which they are declared.

// Parameters are private to the function

function MyFunction(const MyParameter: String): String;
var
   MyVariable: String;  // Variables are private to the function
begin

end;

Class methods (functions or procedures declared as part of a class) add an additional level of scope that is evaluated after any local variables or parameters. Class methods can access any member variables, properties, or methods that are declared anywhere within the same class in which the referencing method is declared. Class methods can also access any protected, public, or published member variables, properties, or methods that are declared within any ancestor classes of the class in which the referencing method is declared.

Information In order to specifically reference the current instance of a class from within a class method, use the special Self keyword.

See below for more information about the various levels of scope (private, protected, public, published) within a class declaration:

interface

type

   TClassA = class
      private
         FMemberVariable: String;
      protected
         procedure DoSomethingMethod;
      public
         property MemberProperty: String read FMemberVariable;
      end;

   TClassB = class(TClassA)
      public
         procedure DoSomethingElseMethod;
      end;

implementation

{ TClassA Implementation }

procedure TClassA.DoSomethingMethod;
begin
   FMemberVariable := 'Test';  // Can access this variable because it is also
                               // declared within the TClassA declaration
end;

{ TClassB Implementation }

procedure TClassB.DoSomethingElseMethod;
begin
   DoSomethingMethod;  // Can access this protected method because it is
                       // declared within the ancestor TClassA declaration
end;

There is one exception to the normal scoping rules of a function/procedure, and that is the with statement. The with statement can introduce an object instance as a new level of scope that overrides the normal scope of any local variables, parameters, or class variables/properties/methods.

Class Scope
A class declaration can have up to four different levels of scope for any member variables, properties, or methods:

ScopeDescription
PrivateAny member variables, properties, or methods declared in this scope are only visible to the properties or methods of the same class declaration.
ProtectedAny member variables, properties, or methods declared in this scope are only visible to the properties or methods of the same class declaration, or any descendant class declarations.
PublicAny member variables, properties, or methods declared in this scope are visible everywhere, subject to the scoping rules of the referencing declaration or code block.
PublishedSame as Public, but in addition, all properties declared in this scope are streamable and will appear in the IDE's component inspector.

Naming Conflicts and Scope
In certain cases, the scoping rules are used by the compiler to resolve naming conflicts. For example, if the implementation of a method uses a local variable that uses the same name as a member variable of the class in which the method is declared, the local variable scope will take precedence and the class member variable will be effectively "hidden" unless qualified with the Self class instance reference:

interface

type

   TMyClass = class
      private
         MyVariable: String;
         procedure MyMethod;
      end;
   
implementation

procedure TMyClass.MyMethod;
var
   MyVariable: String; // This declaration overrides the scope of the class
begin
   MyVariable := 'Test';       // This will be assigned to the local
                               // MyVariable variable
   Self.MyVariable := 'Test';  // This will be assigned to the MyVariable member
                               // variable of the TMyClass class
end;

Certain naming conflicts are impossible because the compiler will not permit them. For example, you cannot give a local variable the same name as a parameter in the same function/procedure declaration, nor can you name a local variable the special "Result" variable name used for returning results from functions.
Image