If you have ever used inheritance in your AnyLogic models you would probably have also overridden one of the methods. Have you ever got into a situation where you change the parent method or function and then forgot to update all the children classes where you overrode the function?
This is by no means a new problem and one that has already been addressed by Java developers many years ago. But to be able to make use of this nifty piece of functionality you will need to enable a special setting inside AnyLogic.
Let's dive right in with an example!
Warning: Intermediate to advanced modeling ahead
P.S. If you want to learn more about how to use method overriding, inheritance and many other standard Java features inside your AnyLogic model check out our course on Java for AnyLogic here. Contact us for academic discounts.
Rather want to watch the video? Click here
The Situation
We created a very simple logistics model where we have created a vehicle agent and extended it into a truck and a car.
The cool thing about inheritance is that now both the truck and car automatically have the exact code, logic, animation etc that exists inside the Vehicle agent. This is great for a number of reasons, not only preventing duplication of code in multiple objects, but also things like polymorphism. Polymorphism basically means that all trucks and cars are also vehicles, which means that you can store them all in a single list of type `Vehicle`.
Like what we are doing on main.
Also on main, we have two buttons, one to move the car and one to move the truck that both lives on main. Since both of these are vehicles they will simply execute the `move` function they get from the parent.
When we play the model and press on the buttons the vehicles always move to a new random location as provided by the button, even while busy with a current move.
The Complication
Now we want to have some custom move function for the truck where if it is already moving we do not want it to move but rather wait for it to stop moving before we will accept any more commands. The simplest option is to simply override the move function inside the truck with a new function. So we do the following:
We copy the `move` function that is greyed out (It is greyed out because it is inherited from the parent agent. It is available but not editable while in the child agent)
We rename it to exactly the same name `move` as the parent function. (AnyLogic will automatically create a new name for anything you copy, so by default, it will be `move1`
We add our new code `if (isMoving()) return;`
And then we call the parent code by using `super.move(x, y);` (This is great because if we would have duplicated the code from the parent we would have two places to maintain the code if any changes are required)
We test it and it works great!
While the truck is moving it does not change direction until it reaches its final destination.
Many weeks later our model is massively complicated and super awesome... We show this to our colleagues and one of them suggests we change the `move` function to `drive` as it makes more intuitive sense. Which we do... using the auto-code update function (ctrl+enter on Windows and cmd+enter on Mac)
Many weeks later one of our super uses reports a bug... the trucks keep on changing their final destination before they have completed their current task... We search for hours and finally realise that a few weeks ago when we made that change of move -> drive we never updated the function name inside the truck... the one that we overrode with new functionality to prevent trucks from changing course until they completed their current move....
You quickly correct your mistake... but the user is furious! They have made many decisions for the last couple of weeks on this model, and it appears they were all wrong!
How could you have prevented this from happening?
The solution
There are two basic best practices that you could have implemented to prevent this issue:
1) Unit Testing - future post coming but you can read more about basic testing here
2) Using the @Override modifier
You should of course use both best practices, not one or the other. Unit testing will tell you there is a problem but not pinpoint the root cause whereas the @Override modifier will tell you exactly what the problem is, even during compile time... literally you won't even be able to run or export the model, until you fixed the issue, which is great!
But custom modifiers are a more advanced feature and AnyLogic has hidden this (and others) from you by default. To activate it you need to
1) Navigate to the preferences
2) Activate the Library developer mode
Now you will see a new parameter option on variables and functions called "Custom modifiers". A few other things have also appeared (like the static option), but as long as you don't mess with things you don't know what they are going to do if you change them, you will be fine. (As is the case with most things in life!)
Now we simply add a standard modifier to the line, '@Override' and hit compile.
Immediately we will get a nice informative error telling us that we indicated that the function `move` must override a supertype method (i.e. it was supposed to replace a function from its parent) yet it does not.
We change `move` in Truck to `drive` and there we go. Problem solved. Indefinitely!
Conclusion
The @Override modifier is a must-use tool if you override any function, don't build your models without it! You will thank us (and yourself) in the future.
You can download the example model below or access it from the AnyLogic Cloud here
P.S. If you want to learn more about how to use method overriding, inheritance and many other standard Java features inside your AnyLogic model check out our course on Java for AnyLogic here. Contact us for academic discounts.
What next?
If you liked this post, you are welcome to read more posts by following the links above to similar posts. Why not subscribe to our blog or follow us on any of the social media accounts for future updates. The links are in the Menu bar at the top or the footer at the bottom.
If you want to contact us for some advice, maybe a potential partnership or project or just to say "Hi!", feel free to get in touch here and we will get back to you soon!
Thanks for sharing this information! I knew how to do it in Java classes but not inside agents.