While I was browsing Paul Phillips GitHub repositories I noticed that he often uses a certain structur:
trait A {
// ...
}
object A extends A
For example here: scala-improving, strings
First, comming from Java, I wasn´t aware of having the same name for a trait and an object in the same scope.
And now I am asking what is it good for? What are the advantages over directly defining the object with all the trait members? Ok, I know that the trait can be mixed in, but I assume using only the object in practice.
Classes and objects can extend traits, but traits cannot be instantiated and therefore have no parameters.
In Scala, one trait can inherit another trait by using a extends keyword. Traits support multiple inheritance. In Scala, a class can inherit both normal classes or abstract class and traits by using extends keyword before the class name and with keyword before the trait's name.
A Trait is a concept pre-dominantly used in object-oriented programming, which can extend the functionality of a class using a set of methods. Traits are similar in spirit to interfaces in Java programming language. Unlike a class, Scala traits cannot be instantiated and have no arguments or parameters.
At least one case where this pattern comes in handy is when you're building a library of functions. You can regroup the functions (actually methods, but let's call them functions in this context) into several traits (which can then be seen as modules), say, MyLibA
, MyLibB
, MyLibC
, etc. Then, if for each of them, you define an object implementing it, users of your lib can easily use it by writing, for instance, this:
import mypackage.MyLibA._
(assuming mypackage
is the containing package). Moreover, you can easily provide a way to import all functions of your lib by providing an object MyLib
as follows:
object MyLib extends MyLibA with MyLibB with MyLibC
and then users can simply import mypackage.MyLib._
instead of writing an import for each module separately. Better yet, you could define a package object mypackage extends MyLibA with MyLibB with MyLibC
, and then users would simply write import mypackage._
. And, the bonus is that picky users who would like to import only MyLibA
and MyLibB
in one line are also free to define their own “import object,” possibly even completing it with their own utility functions, or overriding your own:
object UserLibImport extends MyLibA with MyLibB {
def userAdditionalFunction = /* ... */
override def someRedefinedLibAFunction = /* ... */
}
… and then import all of it with import UserLibImport._
So, I'd say, in this case, not only is it good style, it's highly recommended to provide your functions in this way, as it allows for maximal flexibility.
(This was also briefly explained in this answer.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With