Section 7.4 - Encapsulation

The ``Figures'' and ``Critters'' examples we've seen are excessively public. What does that mean? Those examples permitted all their clients (the ``public'') to see exactly how their types were defined. Thus, any user of those packages can read or change any of the data in those types. Sometimes that's appropriate, but usually it isn't - this makes it more difficult to change things later.

Ada provides a number of mechanisms to ``hide'' information from the users (``clients'') of a given type. Making information inaccessible to others who should not use it is called encapsulation. Encapsulation improves a program's maintainability and reliability.

In the lesson on types we saw how Ada permits types to be declared as ``private.'' This works with tagged types as well, so you can declare tagged types as ``private'' and then hide the implementation details from everyone who uses the type. Ada provides a number of variations on this theme to provide control over what information is visible and what is not.

The most common way to hide implementation details is to define a type publicly in a package declaration as ``tagged private'' (if you don't want the user to know about its parent) or ``new parent_name with private'' (if you want the user to know what its parent is). Follow each type declaration with declarations of subprograms that operate on the type. In the ``private'' part of the package declaration, define the type.

Here's another example. Let's create a type called a `File' with a file name, and a derived type called an `Ada_File' which also stores whether or not the file has been compiled. Both have a ``View'' subprogram. Here's how that might look:

  package File_System is
    type File is tagged private;
    procedure View(F : File);

    type Ada_File is new File with private;
    procedure View(F : Ada_File);

  private
    type File is tagged
     record
       -- We'll discuss strings later in Lovelace
       Name : String(1..20);
     end record;

    type Ada_File is new File with
     record
       Compiled : Boolean := False;
     end record;
  end File_System;

You would then create a package body to define the subprograms:

  package body File_System is
    procedure View(F : File) is
    begin
      -- ...
    end View;

    procedure View(F : Ada_File) is
    begin
      -- ...
    end View;
  end File_System;

In general, in Ada you'd define a package with a set of types inside it. The package declaration would contain a set of types declared as ``tagged private'' or ``new Parent_Type with private''. In the private part of the package declaration you'd define the type ``for real''. In the package body you'd define the subprograms.


Quiz:

Given procedure Try_Stuff:

  with File_System;
  procedure Try_Stuff is
   My_Ada_File : File_System.Ada_File;
  begin
   -- To be done.
  end Try_Stuff;

Let's say that at the line labelled ``To be done'' you'd like to set My_Ada_File's ``Compiled'' value to ``True''. How could you do this?

  1. Replace the line with My_Ada_File.Compiled := True;
  2. Replace the line with Compiled := True;
  3. I couldn't - it can't be done using the material presented so far.

You may also:

PREVIOUS Go back to the previous section

NEXT     Skip to the next section

OUTLINE  Go up to lesson 7 outline

David A. Wheeler (dwheeler@dwheeler.com)

The master copy of this file is at "http://www.adahome.com/Tutorials/Lovelace/s7s4.htm".