At programming greater and challenges a plenty of programmers and their such quantity is required has faced an organizational problem. Object-oriented style of programming allows to use only small quantity of functions and to not know the device of the big system.
At early stages of development there were many versions of such system. Short circuits were as one function with internal variables. The origin of the term "reserve" speaks that reserve remembers static communications of free variables and does not allow to influence them external in relation to the given short circuit to functions. Variable short circuits it is impossible to use from the outside short circuits, and changes of their values from the outside are not visible.
The further development was object-oriented programming where the object is small structure of data which can be used by means of a small amount of functions (methods). Definition of objects is set by means of classes where all objects have identical quantity of internal variables and methods are set in a singular for all objects of the given class.
The object well approaches for programming generators. As the generator understand object from which it is possible to receive new, distinct from former value. By each call the generator generates value of some type which is somewhat the following under the order. Following feature is inherent in generators: values are generated only if necessary and formation of following value is based on previous. We shall give an example:
>(('natural-number defclass)defvar x) ; definition of an internal variable
natural-number
>('natural-number defmethod natural-number() ('x set 0)) ; constructor
(lambda nil((nil BIM(nil,quote) x) set 0))
>('natural-number defmethod next () ; the method which can be caused for all objects
('x set (x + 1)))
(lambda NIL ((NIL quote x) set (x + 1)))
>('number set ('natural-number newobject)) ; new object as a copy of a class
(OBJECT natural-number #((this . …(OBJECT natural-number #((…this . …) (x . 0)))) (x . 0)))
The generator of numbers by means of a method next generates by each call an integer on unit greater, than produced in the previous call.
>(number next)
1
>(number next)
2
It is possible to create various copies of the generator, having set new initial value and named a copy:
>('natural-number defmethod natural-number (x0) ; the constructor has a name of a class and is caused at creation of new object
('x set x0))
(lambda (x0) ((NIL quote x) set x0))
>('another-number set ('natural-number newobject 10))
(OBJECT natural-number #((this . …(OBJECT natural-number #((…this . …) (x . 10)))) (x . 10)))
>(another-number next)
11
>(number next)
3
Greater problem at programming this quantity of the general global variables. If all objects use one set of variables there are many unpleasant surprises, and programming becomes excessively complex. Probably, "only one small global variable" does not become too uncontrollable, but similar style leads to a code which is useless for everything, except for the programmer who has written it.
We can keep convenience of value by default and avoid troubles because of occurrence of a global variable. The variable which is a part of a class, but is not a part of object of this class, refers to as a static member. There is exactly one copy of a static member, in difference from usual members when each object of a class has the independent members.
Let's give an example the constructor of object which uses value by default, using a static member of object:
>('natural-number defstatic initial-value 5)
5
>('natural-number defmethod natural-number ()
('x set initial-value))
(lambda NIL ((NIL quote x) set initial-value))
>('number set ('natural-number newobject))
(OBJECT natural-number #((this . …(OBJECT natural-number #((…this . …) (x . 5)))) (x . 5)))
>(number next)
6
To static members of a class it is possible to address without object. For definition of value the name of the class is used:
>('natural-number getstatic 'initial-value)
5
At realization of methods the reference to itself is set by a variable this. This variable is required for restart of the method inside of a method. Also the given value can be given as value of argument to other functions. The given variable unusual, is not recommended to change its value, basically is used for reading.
It is possible in methods to return itself for convenience of records.
>('natural-number defmethod value () x)
(lambda NIL x)
>(number value)
6
>('natural-number defmethod ++ ()
('x set (x + 1)) this)
(lambda NIL ((NIL quote x) set (x + 1)) this)
>(((number ++) ++) ++)
(OBJECT natural-number #((this . …(OBJECT natural-number #((…this . …) (x . 9)))) (x . 9)))
>(number value)
9
We shall admit create the program processing the information on employees of firm. The following class can be necessary for such program:
>(('employee defclass)defvar name family-name hiring-date department)
employee
Then we can try to define the manager:
>(('manager defclass)defvar emp ; data on the manager as about the employee
group ; subordinates
level)
manager
The manager also is the employee; corresponding data are stored in a member emp object manager. To closely reading person it can be and it is obvious, but here nothing speaks the program, that the manager is at the same time and the employee. The correct approach - obviously to specify, that the manager is the employee.
>(('manager defclass employee)defvar group level)
manager
The class manager is derivative from employee, and employee is a base class for manager. A class manager except for own members (group and level) contains members of a class employee ( name, department, etc.).
Simple classes, such as employee and manager, as a rule do not represent the big interest and are not especially useful. That that is required representation of the information in the form of suitable type with a corresponding set of the operations reflecting the concept to us is. We wish to make it, not penetrating in details of concrete realization. For example:
>(('employee defclass)defvar name family-name …)
employee
>('employee defmethod full-name ()
(name + #\space family-name))
(lambda NIL (name + #\space family-name))
>('employee defmethod writeln ()
(cout writeln (this full-name)))
(lambda NIL (cout writeln (this full-name)))
The member of a derivative class can use methods of a base class as if they are declared in the most derivative class. For example:
('manager defmethod writeln ()
(cout writeln "Name: " (this full-name))
For convenience it is possible to use methods of a base class, using apply:
('manager defmethod writeln ()
(cout write "Name: ") (nil apply this ('employee getmethod 'writeln))
(cout writeln "Level: " level))