Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a good style having a trait and an equally named object extending that trait?

Tags:

scala

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.

like image 776
Peter Schmitz Avatar asked May 09 '11 09:05

Peter Schmitz


People also ask

Can an object extend a trait?

Classes and objects can extend traits, but traits cannot be instantiated and therefore have no parameters.

Can a trait extend another trait Scala?

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.

What is trait in Scala with example?

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.


1 Answers

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.)

like image 158
Jean-Philippe Pellet Avatar answered Sep 19 '22 17:09

Jean-Philippe Pellet