Partly from chapter 4 of Abadi and Cardelli's book A Theory of Objects (Springer 1996).
type CellType {
int val;
int getVal();
void setVal(int n);
}
CellType myCell = new Object {
int val = 0;
int getVal() { return val; }
void setVal(int n) { val = n; }
}
CellType makeCell(Integer n) {
return new Object {
int val = n;
int getVal() { return val; }
void
setVal(int n) { val = n; }
}
}
CellType myCell2 = clone(myCell);
myCell2.value = 10; // no impact on myCell.value
myCell2.setVal =
function(int n) {
if (0 <= val) this.val := n;
}
type MemCellType extends CellType {
int cache;
void restore();
}
Inherited features (methods and attributes) must be designated by the host.
All features are automatically inherited by the host.
Embedding means the host contains a copy of the donor's attributes. This makes it easier to interpret self.
MemCellType myCell3 = new Object extends myCell {
int cache;
void setVal(int n) { // override
this.cache
= this.val;
this.val
= n;
}
void restore() {
this.val
= this.cache;
}
}
MemCellType myCell4 = new Object {
int val;
int
cache;
void setVal(int n) {
this.cache
= this.val;
embed
myCell.set(n); // this = this, not myCell
}
int getVal() {
return
embed myCell.getVal();
}
void restore() {
this.val
:= this.cache;
}
}
Delegation means the host forwards unrecognized messages to the donor.
MemCellType myCell3 = new Object childOf myCell {
int cache;
void setVal(int n) { // override
this.cache
= this.val;
delegate
myCell.setVal(n);
}
void restore() {
this.val
= this.cache;
}
}