-->

Monday, January 19, 2015

Encapsulation Test

Lisp orginally had no object oriented features, but it was able to add them in later without changing the language itself through a clever use of macros and closures.

Julia however already has some elements of OOP built in like subtype polymorphism, multiple dispatch, container types with constructors, and methods. One thing Julia currently doesn't have is encapsulation. However, Julia's closures allow us to simulate encapsulation just like they do in Lisp.

First, we create a type with all the members we want private and another one for the ones we want public. Next, we make a class constructor with an object defined inside it with private member type. Then, we write the functions we want to be public - letting them close over the internal private variables/functions. Finally, we assign these functions to the external object.

Class Definition

In [1]:
## Private members
type Rectangle_Private
    width
    height
    area
end
In [2]:
## Public members
type Rectangle
    set_values
    get_area
end
In [3]:
## Class instance
function makeClass(object::Rectangle)
    self = Rectangle_Private(1,1,1) # constructor with default values
    
    # functions below close over internal environment
    function set_values(w, h)
        (self.width, self.height) = (w, h)
        self.area = w*h
    end
    
    function get_area()
        self.area
    end
    
    (object.set_values, object.get_area) = (set_values, get_area)
end
Out[3]:
makeClass (generic function with 1 method)

Instantiation

In [4]:
myRect1 = Rectangle(nothing, nothing) # constructor with empty args
makeClass(myRect1) # actual instantiation
Out[4]:
(set_values,get_area)
In [5]:
myRect2 = Rectangle(nothing, nothing)
makeClass(myRect2)
Out[5]:
(set_values,get_area)

Usage

In [6]:
myRect1.set_values(1, 2)
myRect2.set_values(3, 4)
Out[6]:
12
Note: Separate objects have separate internal members as we expected
In [7]:
myRect1.get_area()
Out[7]:
2
In [8]:
myRect2.get_area()
Out[8]:
12
In [9]:
myRect1 # type info
Out[9]:
Rectangle(set_values,get_area)
Technically speaking the set_values and get_area fields in type Rectangle are different names from the internal ones defined in makeClass. I named them identically for convenience. It would be distracting to see it named something else.
In [10]:
myRect1.get_area
Out[10]:
get_area (generic function with 1 method)

No comments:

Post a Comment