Properties


Properties are a type of class member. A property consists of a name together with a get and set accessor. Either the get accessor or the set accessor may be defined (or both accessors may be defined). The name of a property can be used in expressions and assigments like a normal variable but the get and set accessors are invoked when reading or writing the variable. The general form of a property is shown below.

name
{
 get
  {
   // get accessor code
  }
 set
  {
   // set accessor code
  }
}

The name names the property. Any use of the property results in a call to the appropriate accessor. The set accessor automatically recieves a parameter called value that contains the value being assigned to the property.

Properties can be used to assign another name to a variable. For example, the class complex has two fields a and b (the real and imaginary components). It is possible to assign other names to these fields, as the next example shows.

// property_a - properties - real and imaginary

using system

space property_a
{
    class complex
    {
        a
        b

        complex() { a = 0.0 b = 0.0}

        complex(aset) { a = aset b = 0.0 }

        complex(aset  bset) { a = aset b = bset }

        real
        {
            get {return a}
            set { a = value }
        }

        imaginary
        {
            get { return b }
            set { b = value }
        }

        operator string()
        {
            return (string)a + " + i * " + (string)b
        }
    }

    property_a()
    {
        c = complex()
        c.real = 10.0
        c.imaginary = 20.0
        cout << c << "\n"
    }
}

The output of the program is as follows.

10 + i * 20

In this case, the properties real and imaginary merely provide other names for the fields a and b. In the function, values are assigned to the properties real and imaginary and the set accessors for these properties are called. This updates the fields a and b.

It would have been possible for the properties real and imaginary only to provide a get accessor. This would deliver read-only access to the fields a and b. Likewise, only the set accessor could have been defined, delivering write-only access to the fields a and b. Often properties that are associated with a field are used to restrict the range of values that can be assigned to the field.

Not all properties have to be directly associated with a field as for the previous example. Properties are often quantities obtained from a computation. Extending complex, we obtain a number of new properties, which are not associated directly with a field. Added are properties for the modulus and argument of a complex number. These properties are the results of computations and are thus read-only properties.

// property_b - properties - modulus and argument

using system

space property_b
{
    class complex
    {
        a
        b

        complex() { a = 0.0 b = 0.0}

        complex(aset) { a = aset b = 0.0 }

        complex(aset  bset) { a = aset b = bset }

        real
        {
            get {return a}
            set { a = value }
        }

        imaginary
        {
            get { return b }
            set { b = value }
        }

        operator string()
        {
            return (string)a + " + i * " + (string)b
        }

        norm { get { return a * a + b * b } }

        modulus
        {
            get { n = norm return n.square_root() }
        }

        argument
        {
            get
            {
                if (a == 0.0 && b == 0.0)
                    return 0
                else
                {
                    d = b / a
                    return d.arc_tan()
                }
            }
        }

    }

    property_b()
    {
        c = complex()
        
        c.real = 10.0
        c.imaginary = 20.0
        
        cout << c << "\n"

        m = c.modulus
        s = "modulus == " + (string)m
        cout << s << "\n"

        a = c.argument
        s = "argument == " + (string)a
        cout << s << "\n"
    }
}

The output of the program is shown below.

10 + i * 20
modulus == 22.36067977499789805051477742381393909454345703125
argument == 1.10714871779409040897235172451473772525787353515625

The modulus of a complex number is the length of a vector whose base is the origin and whose tip is the complex number (plotted on a 2d coordinate system). Pythagoras' theorem is used to obtain the formula for the modulus of a complex number. The argument of a complex number is the angle it makes with the x-axis. The arctan function is sufficient to calculate the argument.