Unlike many other object-oriented languages (Java is a notable exception), Sather separates the notion of inheritance into the two separate notions of code inclusion and subtyping. In Sather, the unqualified term "inheritance" means subtyping. In this section we will deal with the issue of code inclusion. Later, we will deal with abstract types and the notion of subtyping.
Code inclusion is the re-use of code from a parent concrete class (say PARENT) in child concrete class (say CHILD). Including code is a purely syntactic operation in Sather; you could retype the code from PARENT in the class CHILD and it would have exactly the same effect. Code inclusion reduces duplication of code that is common to many classes, thus simplifying maintenance. Routines that are redefined in CHILD over-ride the corresponding routines in PARENT. For instance suppose I wanted to define a new kind of EMPLOYEE - a MANAGER, who has a number of subordinates.
class MANAGER is
include EMPLOYEE
create->private oldcreate;
-- Include the employee code and rename its create to ``oldcreate''
readonly attr numsubordinates: INT; -- Public attribute
create(aname: STR, aid: INT,awage: INT,nsubs: INT): SAME is
-- Create a new manager with the name ``aname'' and the id ``aid''
-- and number of subordinates = ``nsubs''
res ::= oldcreate(aname,aid,awage);
res.numsubordinates := nsubs;
return res;
end;
end;
The MANAGER class is defined by including code from the EMPLOYEE
class. The create routine is extended by first renaming and then calling
the old routine. The old create routines are made "private" and renamed
to "oldcreate" (all overloaded routines are renamed at the same time -
it is not possible to rename them individually). This allows the
oldcreate to only be called within "MANAGER" and not from
outside. Hence, a manager cannot be created without specifying the
number of subordinates.
It is also possible to include a class and make all routines private, or some selectively public
class MANAGER is
private include EMPLOYEE; -- Makes all included routines private
class MANAGER is
private include EMPLOYEE id->id; -- Makes the "id" routine public.
-- and others stay private
class MANAGER is
include EMPLOYEE id->; -- Undefine the "id" routine altogether
Sather permits inclusion of code from multiple source classes. The order of inclusion does not matter, but all conflicts between classes must be resolved by renaming.
class BASE is
attr a: INT;
create: SAME is return new.init; end;
private init: SAME is a := 42; return self; end;
end;
class BASE2 is
attr c: INT;
create: SAME is return new.init end;
private init: SAME is c := 72 end;
a: INT is return c+10; end;
end;
class DERIVED is
include BASE init-> BASE_init;
include BASE2 init-> BASE2_init, a->; -- Rename init and undefine "a"
attr b: INT;
create: SAME is return new.BASE_init.BASE2_init.init end;
private init:SAME is b := 99; return self; end;
end;
Sather will eventually have partial classes, which support mixin
style programming much better.