Module Imports and the Use of Encapsulation

Get introduced to the protection attributes of module imports and the use of encapsulation.

Module imports are private by default

A module that is imported by import is private to the module that imports it. It would not be visible to other modules that import it indirectly. For example, if a school module imports std.stdio, the modules that further import school cannot automatically use the std.stdio module.

Let’s assume that the school module starts by the following lines:

module school.school;

import std.stdio; // imported for this module's own use... // ...

The following program cannot be compiled because writeln is not visible to it:

import school.school;

void main() {
    writeln("hello"); // ← compilation ERROR 
}

std.stdio must be imported by that module as well:

import school.school; 
import std.stdio;

void main() {
    writeln("hello"); // now compiles 
}

Sometimes, it is desired that a module presents other modules indirectly. For example, it would make sense for a school module to automatically import a student module for its users. This is achieved by marking the import as public:

module school.school;

public import school.student; 

// ...

With that definition, modules that import school can use the definitions that are inside the student module without needing to import it:

import school.school; 

void main() {
    auto student = Student("Tim", Gender.male); 
    
    // ...
}

Although the program above imports only the school module, the student.Student struct is also available to it.

When to use encapsulation

Encapsulation avoids problems similar to the one you saw in the introduction section of this chapter. It is an invaluable tool for ensuring that objects are always in consistent states. Encapsulation helps preserve struct and class invariants by protecting members from direct modifications by the users of the type.

Encapsulation provides freedom of implementation by abstracting implementations away from user code. Otherwise, if users had direct access to School.students, it would be hard to modify the design of the class by changing that array e.g. to an associative array, because this would affect all the user code that has been accessing that member.

Encapsulation is one of the most powerful features of object-oriented programming.


Get hands-on with 1400+ tech skills courses.