class

Definition.
Reflection.
Extending a Java class.
Implementing Java interfaces.
Overloading operators and functions.
Definition of a class

A class may be defined in Mathnium to encapsulate a set of data objects and functions in objects which are instances of the class.

The simplest example of a class is a bean which is a collection of properties ( which are attributes/fields of the instances of the class).

class Car
  var make;    
  var model;  
  var year;
  function Car() // Constructor
  end
  function toString()
    return sprintf("%s %s made in %d\n",make,model,year)
  end
end
Here we have added a toString method to the class which is called by the interpreter to construct a string representation of instances of the class for display. Once the class Car has been defined, preferably in a file Car.m, its instances may be created by calling its constructor and setting the properties.
>>mycar=new Car();
>>mycar.setMake("toyota")
>>mycar.setModel("camry")
>>mycar.setYear(2010);
>>"My car is a ",mycar
  My car is a toyota camry made in 2010.
>>mycar.getYear()
  2010

Here the getter and setter methods setMake, setModel, getModel etc., even though not explicity implemented in the class definition, have been added to the class by the interpreter for each of the attributes of the class.

In summary, a class definition may include the following:

A class can be extended as follows:

class FancyCar extends Car
   var maximumSpeed
   function FancyCar()
   end
   function toString()
	return super.toString()+" can go up to "+maximumSpeed+ " mph."
   end
end

As in Java, a class may not extend more than a single class.

The new class inherits the properties and methods of its parent.
>>a=new FancyCar()
>>a.setModel("Super Racer")
>>a.setMake("Millenium")
>>a.setYear(2015)
>>a.setMaximumSpeed(350)
>>a
Millenimum Super Racer made in 2015
 can go up to 350 mph.

Reflection


The following functions may be used to elicit information about classes that are defined

The outputs of the last three functions may be used to invoke the methods/constructor of a class by specifying appropriate inputs.

>>class A
>var x
>function A(x);this.x=x;end
>function add(y);return new A(x+y);end
>static function addab(a,b);return new A(a.x+b.x);end
>end
>> // invoke the constructor
>> // Equivalent to a=new A(2)
>>a=constructors(A.class)[1](2)
>>a
x:
         2
>>method(A.class,"add")
Method ($returnValue) =A.add(y)
>>// Equivalent to a.add(10)
>>method(A.class,"add")(a,10)
x:
        12
>>// Equivalent to A.addab(new A(10),new A(12))
>>method(A.class,"addab")(new A(10),new A(12))
x:
        22

Extending a Java class


Mathnium classes that extend Java classes may also be defined. The following class extends the Java Swing frame.
class MyFrame extends JFrame
import javax.swing.*;
  var name
  var address
  var ok
  var cancel
  var nameLabel
  var addressLabel
  function MyFrame()
	super()	
	createComponents()
	add(createLayoutPanel())
  end	
  function createComponents()
        // define buttons
	ok=new JButton("OK");
        cancel=new JButton("Cancel");
	ok.addActionListener(@this.okClicked);
	cancel.addActionListener(@this.cancelClicked);
        // define textfields
        name=new JTextField(20)
        address=new JTextField(20)
        // define Labels
        nameLabel=new JLabel("Name")
        addressLabel=new JLabel("Address")
  end
  function createLayoutPanel()
	// Layout is a class that has static cover methods
	// for the methods of pagelayout.EasyCell
	// see http://pagelayout.sourceforge.net/docs/
	// We import the various methods of the class by using the
        // importStatic call.
	importStatic(Layout.class);
        // Row of buttons
	bottomrow=row("right","center",ok,cancel);
	bottomrow.linkWidth(cancel,1,ok)
        // The content panel
	return pagepanel(
		grid("right","center",
			nameLabel,name,eol(),
			addressLabel, address,eol(),
			bottomrow, hspan()));
  end
  function okClicked(e)
    "You entered name as\n"
    "     "+name.getText()+NL+"and address as\n"
    "     "+address.getText()+NL
  end
  function cancelClicked(e)
    "You canceled the entries\n"
  end
end

The following usage of the class leads to the GUI shown below.

>>a=new MyFrame()
>>a.pack()
>>a.show()

Implementing Java interfaces


In the previous example, the event listeners are assigned to the buttons by using the Mathnium mechanism for the implicit creation of interface proxies if the argument to a Java method that requires an interface with a single method is a Mathnium function. Alternatively, and more transparently, an existing Java interface can be implemented explicitly in a Mathnium class.


class ButtonFrame implements ActionListener
import javax.swing.*;
import java.awt.event.*;
	function ButtonFrame()
		frame=new JFrame();
		button=new JButton("Click me");
		frame.add(pagepanel(Layout.row(button)));	
		button.addActionListener(this);
		frame.pack();
		frame.show();
	end
	function actionPerformed(e)
		"You clicked me\n"
	end
end

Clearly, in this case, the class definition must include methods whose names (and the size of the argument list) are identical to the methods specified by the interface to be implemented.

Overloading functions and operators


Operators and functions may be overloaded for the objects defined by a Mathnium class. The following class is defined to implement the automatic differentiation algorithm for addition, multiplication, and the trigonometric functions sin, and cos.

class MyDeriv
	var f
        var fx
	function MyDeriv(f,fx)	
		this.f=f;
		this.fx=fx;
        end
	// Overload addition: d(p+q)/dx=dp/dx+dq/dx
	function +(other)
		return new MyDeriv(f+other.f,fx+other.fx);
        end
	// Overload multiplication: d(p*q)/dx=q*dp/dx+p*dq/dx
	function *(other)
		return new MyDeriv(f*other.f,fx*other.f+f*other.fx);
        end
	// Overload sin: d(sin(p))/dx=cos(p)*dp/dx
	function sin()
		return new MyDeriv(Main.sin(f),Main.cos(f)*fx)
        end
	// Overload cos: d(cos(p))/dx=-sin(p)*dp/dx
	function cos()
		return new MyDeriv(Main.cos(f),-Main.sin(f)*fx)
        end
	// This method, if defined, is called by the interpreter
	// if one of the operands is not an instance of this class.
	static function convert(x)
          REAL x    # Make sure it's real
          SCALAR x  # Make sure it's a scalar
  	  return new MyDeriv(x,0);
        end
        function toString()
 	   return "["+f+","+fx+"]";
        end
end

Note that a static method has been defined here. Any static method can be defined in a class as in Java (as also static attributes/fields). Also note that it is a good practice to use the prefix Main. for calling the usual Mathnium function from within a class that overloads functions.

>>xv=new MyDeriv(pi/3,1) // x and derivative of x at x=pi/3
>>xv.sin()  // sin(x) and derivative of sin(x) at x=pi/3
[0.866      ,0.5        ]
>>(2*xv).sin() // sin(2*x) and derivative of sin(2*x) at x=pi/3
[0.866      ,-1         ]
>>(xv*xv).cos() // cos(x*x) and derivative of cos(x*x) at x=pi/3
[0.4566     ,-1.8633    ]
>>(xv*xv*xv).cos() // cos(x*x*x) and derivative of cos(x*x*x) at x=pi/3
[0.41       ,-3.0007    ]
>>(xv*xv)      // x*x and derivative of x*x at x=pi/3
[1.0966     ,2.0944     ]
Although the syntax as exemplified above for evaluating the expressions involving objects with overloaded operators and functions is quite adequate, Mathnium has a mechanism that makes the usage much more convenient: a call of the form func(obj,...) is interpreted as obj.func(...) if obj is an instance of a Mathnium class that has a method func. Thus the following expressions have the same values as the corresponding expressions above.
>>xv=new MyDeriv(pi/3,1) // x and derivative of x at x=pi/3
>>sin(xv)  // sin(x) and derivative of sin(x) at x=pi/3
[0.866      ,0.5        ]
>>sin(2*xv) // sin(2*x) and derivative of sin(2*x) at x=pi/3
[0.866      ,-1         ]
>>cos(xv*xv) // cos(x*x) and derivative of cos(x*x) at x=pi/3
[0.4566     ,-1.8633    ]
>>cos(xv*xv*xv) // cos(x*x*x) and derivative of cos(x*x*x) at x=pi/3
[0.41       ,-3.0007    ]
>>(xv*xv)      // x*x and derivative of x*x at x=pi/3
[1.0966     ,2.0944     ]