By Jon Rafkind (jon at rafkind dot com)
Keywords: _class_ _java_
The class system that is part of mzlib, (require (lib "class.ss")), is complex
and contains many features not available in other existing class frameworks.
JClass is a subset of mzlib's class system that tries to mimic Java's class
structure as much as possible, making it easy for new-comers to scheme to
start working with classes without too much trouble.
Class and Interface definitions
To define a class use `jclass'. There are 4 possible forms for it:
> (jclass (constructor args body ...) body ...)
Will create a vanilla class that extends the base object class, object%.
> (jclass extends <base> (constructor args body ...) body ...)
Will create a class that extends <base>.
> (jclass implements (<interface> ...) (constructor args body ...) body ...)
Will create a class that implements all the interfaces <interface> ...
> (jclass extends <base> implements (<interface> ...)
(constructor args body ...) body ...)
Will create a class that extends <base> and implements all the interfaces
;; define a class that accepts 1 argument in the constructor
(define my-class (jclass (constructor (x)
(printf "Constructed with ~a\n" x))
(public-method (hello) (void))))
;; define a class that extends the first class
;; overrides the hello method to return 2 instead of void
(define my-class2 (jclass (constructor (x)
(printf "In child class constructor\n"))
(override-method (hello) 2)))
> (constructor (args) [super-constructor] body ...)
The constructor expression defines a method that is executed immediately
following an instantiation of this class with `new'. To pass parameters to a
super constructor, which is mandatory when there is one, use
;; plain constructor
(constructor (x) (printf "X is ~a\n" x))
;; pass x to the super constructor
(printf "X is ~a\n" x))
The constructor is executed after the rest of the body, so any fields with
initialization expressions can be overridden in the constructor.
> (new class arg ...)
Create a new class that was defined with jclass and pass arg ... to the
> (jinterface method ...)
Define an interface with methods method ...
> (jinterface extends (<interface> ...) method ...)
Define an interface that extends the interfaces <interface> ... and has its
own methods method ...
(define my-interface (jinterface fun1 fun2 fun3))
(define another-interface (my-interface) (jinterface fun4))
Fields and methods
Fields and methods can be private or public, there is no protected. private
fields can only be accessed by the class that declared them. public fields can
be accessed and overriden by anyone.
> (private-field id [expr])
Defines a field with an optional expression to initialize it with. If expr is
left out it defaults to #f
(private-field my-field 3)
> (private-fields id ...)
Defines all id ... as private fields.
> (public-field id [expr])
Exactly like private-field but the field is public instead of private.
> (public-fields id ...)
Defines all id ... as public fields.
> (private-method (name args ...) body ...)
Just like (define (name args) ...) except the method is private to this class.
> (public-method (name args ...) body ...)
Just like (define (name args) ...) except the method is accessible to
> (override-method (name args ...) body ...)
Lets a sub-class override a parent class's method. You cannot simply redeclare
a method with public-method to override its functionality, you must call
override-method. Inside override-method you can use `super' to call the parent
;; override a method `hello'. print a string and then call the super method
(define my-class (jclass extends base
(constructor () (super-constructor))
(printf "Hello from the child class\n")
> (get-field id object)
Return the value of a field declared with public-field named by id from
(printf "X is ~a\n" (get-field x some-class-with-x-in-it))
> (set-field id object expr)
Set the value of a field declared with public-field named by id from `object'.
(set-field x some-class-with-x-in-it 9)
> (send object method arg ...)
Call `method' in object passing parameters arg ...
-> is an alias for send so you can use it in a pseudo-java way
(object . -> . my-method arg1 arg2)
This works becuase of the double-dot notation in mzscheme.
The following identifiers are exported from jclass as well which are defined
exactly the same way in class.ss.
jclass.ss and class.ss can be mixed cleanly, jclass is just a wrapper around
the class system.