So, I was trying to make a finagle server, talk to sentry (not important), and stumbled upon a case, where I needed to inherit from two classes (not traits) at the same time, let's call them class SentryHandler extends Handler and class TwitterHandler extends Handler, and assume, that I need to create MyHandler, that inherits from both of them.
After a moment of stupidity, when I thought it was impossible without using a dreaded "delegation pattern", I found a solution:
trait SentryTrait extends SentryHandler class MyHandler extends TwitterHandler with SentryTrait Now, this got me thinking: what is the purpose of having the notion of "trait" to being with? If the idea was to enforce that you can inherit from multiple traits but only a single class, it seems awfully easy to get around. It kinda sounds like class is supposed to be the "main" line of inheritance (that you "extend a class with traits", but that isn't true either: you can extend a trait with (or without) a bunch of other traits, and no class at all.
You cannot instantiate a trait, but the same holds for an abstract class ...
The only real difference I can think of is that a trait cannot have constructor parameters. But what is the significance of that? I mean, why not? What would the problem with something like this?
class Foo(bar: String, baz: String) extends Bar(bar) with Baz(baz)
trait Handler; class SentryHandler extends Handler; class TwitterHandler extends Handler; trait SentryTrait extends SentryHandler; class MyHandler extends TwitterHandler with SentryTraitthis doesn't compile on the REPL.Eitheris a class, butFutureis a trait (while "has a Future" doesn't even make any sense).Optionis a class, butMapis a trait ("has-a Map"???).Listis a class, butSeqis a trait ... etc. Clearly, the decision of whether the type you are designing should be a class or a trait is based on a plethora of considerations other than "is-a" vs. "has-a" dilemma, which is rather philosophical (in a bad sense, as in having no practical significance).