<< §6 Object Teams API | ↑ Table of Contents ↑ | §8 Join Point Queries >> |
§7 Role Encapsulation
Concepts of encapsulation
protected
cannot be externalized, which means its type
cannot be used outside the declaring team (§1.2.3).
§7.1 Opaque roles↑ §7
The purpose of the two IConfined
interfaces (see §6.2.(a)) is to define
opaque roles: Any role implementing IConfined
can be externalized using this type, such that external clients
cannot access any features of the role. The type IConfined
exposes no features and references of this type cannot be widened
to any type not even to java.lang.Object
.
If the actual role type is furthermore invisible outside the team
(by not declaring it public
), it is perfectly safe to externalize
such roles using type IConfined
(which is a public interface)
and pass them back to the owning team. The encapsulation
of the team is in no way breached by externalizing opaque roles,
which can only be used as a handle into internal state of the team.
The difference between the two mentioned interfaces is that
ITeam.IConfined
requires to use this type or any subtype
as externalized role. Such a reference contains the information of
the enclosing team. Even stricter control can be imposed using the
regular interface IConfined
. Here not even team membership
is visible to clients using a reference of this type.
§7.2 Confined roles↑ §7
Subclassing Team.Confined
with a protected class
yields a role class to which no object outside the team will
ever have a reference.
The point here is that instances of a role class with a regular super class
can be widened to this super class.
Widening can occur either in an assignment or when invoking a method which the role
inherits from the regular super class, where the this
reference is widened.
In both cases the widened reference is no longer protected by the team and can leak out.
This would break encapsulation of a role object that should only be accessible within the enclosing team.
Subclasses of Team.Confined
are not compatible to any class outside their enclosing team (including java.lang.Object
) and do not inherit any methods
that have the danger of leaking this
.
(a) Inhibition of overriding
The types ITeam.IConfined
and Team.Confined
cannot be overridden (cf. §1.3.1.(c)).
(b) Arrays of Confined
For any confined type C
, i.e., a type which is not compatible to Object
, an array of C
is not compatible to an array of Object
nor to Object
itself. This rule ensures that confinement cannot be bypassed by a sequence of compatible assignments and casts.
Upcoming:
Only by widening to a non-role super-type, a role instance can be accessed from outside the team. In the future this can be inhibited by restricted inheritance.Example code (Role Encapsulation):
1 | public team class Company { |
2 | private HashMap<String,Employee> employees; |
3 | ... |
4 | protected class Employee implements IConfined { |
5 | void pay(int amount) { ... } |
6 | ... |
7 | } |
8 | public IConfined getEmployee(String ID) { |
9 | return employees.get(ID); // implicit widening to IConfined |
10 | } |
11 | public void payBonus(IConfined emp, int amount) { |
12 | ((Employee)emp).pay(amount); // explicit narrowing |
13 | } |
14 | } |
15 | public class Main { |
16 | public static void main(String[] args) { |
17 | final Company comp = new Company(); |
18 | IConfined<@comp> emp = comp.getEmployee("emp1"); |
19 | // System.out.println(emp); <– forbidden! |
20 | comp.payBonus(emp, 100); |
21 | } |
22 | } |
<< §6 Object Teams API | ↑ Table of Contents ↑ | §8 Join Point Queries >> |
Effects:
protected
roleEmployee
implements the above described interfaceIConfined
and therefore becomes opaque (line 4).IConfined
(line 8, line 11).IConfined
(line 18).toString()
, will cause a compilation error (line 19).IConfined
and the intrinsic role typeEmployee
may be necessary (line 9 and 12).