Data-hiding is accomplished in E at the module level.
This means, effectively, that it is wise to define classes in separate modules (or at least only closely related classes together in a module), taking care to EXPORT only the definitions that you need to.
You can also use the PRIVATE keyword in the definition of any OBJECT to hide all the elements following it from code which uses the module (although this does not affect the code within the module).
The PUBLIC keyword can be used in a similar way to make the elements which follow visible (i.e., accessible) again, as they are by default.
For instance, the following OBJECT definition makes x, y, a and b private (so only visible to the code within the same module), and p, q and r public (so visible to code external to the module, too).
OBJECT rec p:INT PRIVATE x:INT y PUBLIC q r:PTR TO LONG PRIVATE a:PTR TO LONG, b ENDOBJECT
For the set class you would probably want to make all the data private and all the methods public. In this way you force programs which use this module to use the supplied interface, rather than fiddling with the set data structures themselves. The following example is the complete code for a simple, inefficient set class, and can be compiled to a module.
OPT MODULE -> Define class 'set' in a module
OPT EXPORT -> Export everything
/* The data for the class */
OBJECT set PRIVATE -> Make all the data private
elements:PTR TO LONG
maxsize, size
ENDOBJECT
/* Creation constructor */
/* Minimum size of 1, maximum 100000, default 100 */
PROC create(sz=100) OF set
DEF p:PTR TO LONG
self.maxsize:=IF (sz>0) AND (sz<100000) THEN sz ELSE 100 -> Check size
self.elements:=NEW p[self.maxsize]
ENDPROC
/* Copy constructor */
PROC copy(oldset:PTR TO set) OF set
DEF i
self.create(oldset.maxsize) -> Call create method!
FOR i:=0 TO oldset.size-1 -> Copy elements
self.elements[i]:=oldset.elements[i]
ENDFOR
self.size:=oldset.size
ENDPROC
/* Destructor */
PROC end() OF set
DEF p:PTR TO LONG
IF self.maxsize<>0 -> Check that it was allocated
p:=self.elements
END p[self.maxsize]
ENDIF
ENDPROC
/* Add an element */
PROC add(x) OF set
IF self.member(x)=FALSE -> Is it new? (Call member method!)
IF self.size=self.maxsize
Raise("full") -> The set is already full
ELSE
self.elements[self.size]:=x
self.size:=self.size+1
ENDIF
ENDIF
ENDPROC
/* Test for membership */
PROC member(x) OF set
DEF i
FOR i:=0 TO self.size-1
IF self.elements[i]=x THEN RETURN TRUE
ENDFOR
ENDPROC FALSE
/* Test for emptiness */
PROC empty() OF set IS self.size=0
/* Union (add) another set */
PROC union(other:PTR TO set) OF set
DEF i
FOR i:=0 TO other.size-1
self.add(other.elements[i]) -> Call add method!
ENDFOR
ENDPROC
/* Print out the contents */
PROC print() OF set
DEF i
WriteF('{ ')
FOR i:=0 TO self.size-1
WriteF('\d ', self.elements[i])
ENDFOR
WriteF('}')
ENDPROC
This class can be used in another module or program, as below:
MODULE '*set'
PROC main() HANDLE
DEF s=NIL:PTR TO set
NEW s.create(20)
s.add(1)
s.add(-13)
s.add(91)
s.add(42)
s.add(-76)
IF s.member(1) THEN WriteF('1 is a member\n')
IF s.member(11) THEN WriteF('11 is a member\n')
WriteF('s = ')
s.print()
WriteF('\n')
EXCEPT DO
END s
SELECT exception
CASE "NEW"
WriteF('Out of memory\n')
CASE "full"
WriteF('Set is full\n')
ENDSELECT
ENDPROC
Go to the Next or Previous section, the Detailed Contents, or the Amiga E Encyclopedia.