Adding methods to any class using Scala implicit class

Scala has many useful features – but one of the most useful is the ability to add any method to any class.

I will start with an example from the ATG world as this is a concrete example for me where this facility is extremely useful.
Let’s say you want to add a method called valideBespoke() to GenericFormHandler so that it can be used by any of your bespoke form handlers. Assuming that all the form handlers extend GenericFormHandler, all you need to do is, to create another class BetterGenericFormHandler class which extends GenericFormHandler. Then change all the bespoke formhandlers to extend this class. At this point you can use the method validateBespoke().

However this approach will not work if you extend existing ATG form handlers which in turn extend the origin GenericFormHandler class.

In Scala the solution to this problem is to use implicit classes. An implicit class wraps an existing class and allows an addition of any number of methods. It only works for new methods – not for overriding existing methods.
But still pretty useful. See an example below:

  class GenericFormHandler {
    def originalDoSomething(): String = {
      "this is the original method"
    }
  }
  implicit class BetterGenericFormHandler(frh: GenericFormHandler) {
    def validateMethod(): Boolean = {
      true
    }

    def originalDoSomething(): String = {
      "this is the better method"
    }
  }

  class CustomGenericFormHandler extends GenericFormHandler {
    def doSomething(): Boolean = {
      this.validateMethod
      // do more stuff
    }
  }

There are only a few restrictions:

  • An implicit class needs to be defined inside another class
  • The implicit class only can take one non-implicit argument
  • The implicit class name should not clash with the name of a method, member or object in scope.
  • You need to import the implicit class definition where you need to use it It would be nice if it worked without imports, but it doesn’t. Still a small price to pay.
  • It does not allow to override existing methods in the class.

Please see the following link for more details about implicit classes in Scala:

Note that to solve the problem above you don’t need to use implicit classes. In Scala, a Trait allows to define a method with a body. As long as your custom form handler uses that Trait, in the same way you can access the validateMethod().