Child packages can be seen as an extension for their parent.
It can be used, for example, to provide functionalities that are not directly linked to your base package.
The typical example is the Input-Output package.
Imagine the following package :
package Temperature is
type Kelvin_Temp is private;
type Celsius_Temp is private;
function build (temp : Positive) return Kelvin_Temp;
function build (temp : Integer) return Celsius_Temp;
function to_celsius (temp : in Kelvin_Temp) return Celsius_Temp;
function to_kelvin (temp : in Celsius_Temp) return Kelvin_Temp;
private
type Kelvin_Temp is 0.0 .. 10_000.0;
type Celsius_Temp is -273.0 .. 10_000.0;
end Temperature;
This package provides basic operations directly linked to the types defined.
What if you want to extend it to provide I/O in text format ?
You can decide to put operations inside the Temperature package but if you want to add other types of I/O such as database I/O, you will have a lot of functions that are not directly linked to your types inside the same file.
You can define
package Temperature.Text_IO is
procedure Put(temp : Celsius_Temp);
procedure Put(temp : Kelvin_Temp);
end Temperature.Text_IO;
and
package Temperature.Database_IO is
procedure insert (Temp : in Celsius_Temp);
procedure insert (Temp : in Kelvin_Temp);
end Temperature.Database_IO;
That's exactly what is done with IO in the standard library
From an encapsulation point of view, your private types will remain private outside of the package hierarchy so you don't break encapsulation.