ObjectTeams/Java Language Definition - §7.
Concepts of encapsulation
 |
| Protected roles |
A role with visibility protected cannot be externalized, which means its type cannot be used outside the declaring team (§1.2.3)
|
 |
| Confined roles |
Confined roles are encapsulated even stricter than protected roles: the compiler will ensure that by no means any
object outside the enclosing team will ever have a reference to a confined role.
|
 |
| Opaque roles |
Opaque roles build on the guarantees of confined roles but allow to be shared in a limited way such that
no information is exposed.
|
 |
§7.1. Opaque roles
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
Team.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
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 a role class with
a regular super class will widen the
this reference to the
super class when executing a method from this class. Within such
a method a danger of leaking the reference exists, because the inherited method could pass the
this reference to another object. Such leaking of the
this reference would break encapsulation of a role object that should only be accessible within the enclosing team.
Subclasses of
Team.Confined do not inherit any methods
that have the danger of leaking
this.
(a)
Inhibition of overriding
The types
Team.IConfined and
Team.Confined
cannot be overridden (cf.
§1.3.1(c)).
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.
| 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 |
} |
|