- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Inheritence of two instances of one trait?
Tue, 2009-09-22, 23:30
I'm constructing a framework. Handles[T] defines that an object can handle
things of type T. I have a handler which can handle both red and blue. I
set up my inheritance as follows:
class Handler extends Handles[Red] with Handles[Blue]
The compiler complains of illegal inheritance: "inherits different type
instances of trait". What is happening behind the scenes that explains why
a Handler cannot be a Handles[Red] and a Handles[Blue] ?
Wed, 2009-09-23, 13:27
#2
Re: Inheritence of two instances of one trait?
Kaddar wrote:
>
> I'm constructing a framework. Handles[T] defines that an object can
> handle things of type T. I have a handler which can handle both red and
> blue. I set up my inheritance as follows:
>
> class Handler extends Handles[Red] with Handles[Blue]
>
> The compiler complains of illegal inheritance: "inherits different type
> instances of trait". What is happening behind the scenes that explains
> why a Handler cannot be a Handles[Red] and a Handles[Blue] ?
>
Just like in Java, you can't inherit two times from the same
class/trait/whatever. E.g when Handles[T] has an abstract method
handle(t:T), how exactly should Handler implement it? You can't have both
handle(b:Blue) and handle(r:Red), "thanks" to type erasure. Probably your
Handler class should use composition instead of inheritance, so that it
"contains" different Handles. There might be more elegant solutions,
though...
Cheers,
Landei
Wed, 2009-09-23, 13:47
#3
Re: Inheritence of two instances of one trait?
Hi,
The following seems to build (per Landei's recommendation)
class Blue{}
class Red{}
class Handles[T] {}
trait BlueHandles extends Handles[Blue]{}
trait RedHandles extends Handles[Red]{}
class Handler extends BlueHandles with RedHandles{}
A bit verbose, but less so than it would be in Java.
On 9/23/09 8:21 AM, Landei wrote:
>
>
> Kaddar wrote:
>
>> I'm constructing a framework. Handles[T] defines that an object can
>> handle things of type T. I have a handler which can handle both red and
>> blue. I set up my inheritance as follows:
>>
>> class Handler extends Handles[Red] with Handles[Blue]
>>
>> The compiler complains of illegal inheritance: "inherits different type
>> instances of trait". What is happening behind the scenes that explains
>> why a Handler cannot be a Handles[Red] and a Handles[Blue] ?
>>
>>
> Just like in Java, you can't inherit two times from the same
> class/trait/whatever. E.g when Handles[T] has an abstract method
> handle(t:T), how exactly should Handler implement it? You can't have both
> handle(b:Blue) and handle(r:Red), "thanks" to type erasure. Probably your
> Handler class should use composition instead of inheritance, so that it
> "contains" different Handles. There might be more elegant solutions,
> though...
>
> Cheers,
> Landei
>
Wed, 2009-09-23, 15:27
#4
Re: Inheritence of two instances of one trait?
On Wed, Sep 23, 2009 at 7:45 AM, Edmund Kohlwey <ekohlwey@gmail.com> wrote:
Hi,
The following seems to build (per Landei's recommendation)
class Blue{}
class Red{}
class Handles[T] {}
trait BlueHandles extends Handles[Blue]{}
trait RedHandles extends Handles[Red]{}
class Handler extends BlueHandles with RedHandles{}
Give it another go, but with this time add a def handle(t: T) to your Handles class (or any other method dealing with T). I think you'll quickly run into the same issue as the OP. As David pointed out, I don't believe there's a way around erasure in this situation.
- Colin
On Tue, Sep 22, 2009 at 3:30 PM, Kaddar wrote:
>
> I'm constructing a framework. Handles[T] defines that an object can handle
> things of type T. I have a handler which can handle both red and blue. I
> set up my inheritance as follows:
>
> class Handler extends Handles[Red] with Handles[Blue]
>
> The compiler complains of illegal inheritance: "inherits different type
> instances of trait". What is happening behind the scenes that explains why
> a Handler cannot be a Handles[Red] and a Handles[Blue] ?
Erasure.
Scala (as a JVM language) erases parametrized types to unparametrized
types. The compiler will end up emitting Handler as extending Handles,
and you can't inherit from the same erased type twice. You can get
around this in a few particular circumstances, but they almost
certainly don't apply here.