Omnis Technical Note TNOO0002 October 2006

Polymorphism in Omnis

For Omnis Studio 3 or above
By Andreas Pfeiffer

One advantage of using encapsulation in Omnis objects is the possibility for objects to react differently on a message, depending on the type of class from which the object was instantiated. Let us look at an example. You have got 3 different customer windows and in a fourth window a list of customers from which the user can choose a record. This event shall send a message to the other customer windows that a new customer has been selected. The windows now should react differently: The customer detail window should display the customer address and other details for this customer. The invoice window should show all invoices for the selected customer, and the third window should display a list of all delivery notes for the customer.

Polymorphism

The easiest way to send a message to all window instances, in this case, to all customer objects, is to first implement the individual behaviour in each window in a public method. To prevent yourself from forgetting to do it for a certain window, you could create a class method called $setCustomer in a common superclass. The method would contain no code except for a comment that this method can be overridden. Then in each customer window subclass the method will be displayed in blue and can be overridden accordingly. The method should contain a parameter "pCustID", and - depending on the window - you can now load the details, invoices or delivery notes of the customer from the database based on the ID passed to the window.

Polymorphism

Now we only need to know how the customer list can send the message to the other customer window instances. For this you can use the "$sendall" method which sends a message to all members of a group, such as all window instances. You can write the following code into the $event() method of the list in the main customer window:

On evClick
  Do $iwindows.$sendall(
     $ref.$setCustomer(ivCustomerList.ID))

After a click on the customer list, a message will be sent to all open window instances to execute the method $setCustomer(), including the ID of the selected customer.

Please note that Omnis may display an error message in the case when one of these window instances may not contain the $setCustomer method. There are several possibilities to eliminate this. The easiest is to turn off this behaviour in Omnis. To do this, go the "Prefs" group of the Library properties and set the property $reportnotationerror to kFalse. There is basically nothing wrong with turning off notation errors: imagine, if you ask a coffee machine what the root of 36 is, you won't get an answer, and also no error message..!

However, if you prefer to leave this property active you have to implement a filter. In this case, the message shall be sent only to those objects that contain a $setCustomer method. To do this, you have to insert an additional parameter into $sendall which behaves like a filter and sends the message only to those instances that have implemented this method:

On evClick
  Do $iwindows.$sendall(
    $ref.$setCustomer(ivCustomerList.ID),$ref.$methods.//$setCustomer//)

Please note the two double backslashes. They tell Omnis that this is the method name that you are looking for.