- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
What is the expected behavior for Trait that extend Class?
Thu, 2009-03-05, 03:00
Hi,
I was working on a way to compose behavior to a base class using Traits to defined behavior, and I ran into something I didn't expect. I think I was expecting something wrong but I wanted to get a better understanding of why.
I define a class and a trait that should be a mixin (assuming I understood correctly).
class Alpha
trait Beta extends Alpha // The mixin trait
Note: Beta inherits form Alpha because I want the trait to access some of the Alpha fields and methods.
If I do this:
class Echo extends Beta
scala> var x:Alpha = new Echo
x: Alpha = Echo@eabd2f
So I expected the Beta trait to be a mixin only for a class that is an Alpha to start with. But in doing `class Echo extends Beta` will promote Echo to be subclass of Alpha. I did not expect that.
If I do this:
scala> class Delta extends AnyRef with Beta
<console>:6: error: illegal inheritance; superclass Object
is not a subclass of the superclass Alpha
of the mixin trait Beta
class Delta extends AnyRef with Beta
^
Which is what I expected on the general case.
This brings me to the following question. How can I make the Beta trait mixable with only sub-classes of Alpha, instead of promoting the class it get mixed in as a subclass of Alpha?
Should I as a best practice for mixin traits always explicitly declare it as a sub-class of AnyRef (it it's not inheriting from another class)?
Thomas
I was working on a way to compose behavior to a base class using Traits to defined behavior, and I ran into something I didn't expect. I think I was expecting something wrong but I wanted to get a better understanding of why.
I define a class and a trait that should be a mixin (assuming I understood correctly).
class Alpha
trait Beta extends Alpha // The mixin trait
Note: Beta inherits form Alpha because I want the trait to access some of the Alpha fields and methods.
If I do this:
class Echo extends Beta
scala> var x:Alpha = new Echo
x: Alpha = Echo@eabd2f
So I expected the Beta trait to be a mixin only for a class that is an Alpha to start with. But in doing `class Echo extends Beta` will promote Echo to be subclass of Alpha. I did not expect that.
If I do this:
scala> class Delta extends AnyRef with Beta
<console>:6: error: illegal inheritance; superclass Object
is not a subclass of the superclass Alpha
of the mixin trait Beta
class Delta extends AnyRef with Beta
^
Which is what I expected on the general case.
This brings me to the following question. How can I make the Beta trait mixable with only sub-classes of Alpha, instead of promoting the class it get mixed in as a subclass of Alpha?
Should I as a best practice for mixin traits always explicitly declare it as a sub-class of AnyRef (it it's not inheriting from another class)?
Thomas
Thu, 2009-03-05, 03:27
#2
Re: What is the expected behavior for Trait that extend Class?
On Wed, Mar 4, 2009 at 11:02 PM, Alex Cruise <alex@cluonflux.com> wrote:
On 03/04/2009 06:00 PM, Thomas Sant Ana wrote:
How can I make the Beta trait mixable with only sub-classes of Alpha, instead of promoting the class it get mixed in as a subclass of Alpha?
trait Beta {
this: Alpha =>
def ...
}
I has always had a hard time with the: `this: T => `. Now I know one use case :)
But this brings me other questions.. Why is `trait Beta extends Alpha` less strict than the other expression? When I use extends Alpha in a trait 'this' refers to Alpha? Or does it refer to something different?
Thomas
Thu, 2009-03-05, 03:57
#3
Re: What is the expected behavior for Trait that extend Class?
If you use the "extends" form, any resulting types must inherit from Alpha,
but cannot also be made to extend from subclasses of Alpha. The self-type
form allows you to extend arbitrary subtypes of Alpha.
And while we are talking about self-types, can someone tell me what the use
case is for using a self-type declaration to alias "this" with some other
name? That strikes me as a recipe for confusion, but it's such an unlikely
design choice that someone must have had a serious rationale.
Thomas Sant Ana wrote:
>
> On Wed, Mar 4, 2009 at 11:02 PM, Alex Cruise wrote:
>
>> On 03/04/2009 06:00 PM, Thomas Sant Ana wrote:
>>
>>> How can I make the Beta trait mixable with only sub-classes of Alpha,
>>> instead of promoting the class it get mixed in as a subclass of Alpha?
>>>
>>
>> trait Beta {
>> this: Alpha =>
>> def ...
>> }
>>
>
> I has always had a hard time with the: `this: T => `. Now I know one use
> case :)
>
> But this brings me other questions.. Why is `trait Beta extends Alpha`
> less strict than the other expression? When I use extends Alpha in a
> trait
> 'this' refers to Alpha? Or does it refer to something different?
>
> Thomas
>
>
Thu, 2009-03-05, 11:27
#4
Re: What is the expected behavior for Trait that extend Class?
On Thu, Mar 5, 2009 at 2:52 AM, Dave Griffith wrote:
>
>
> If you use the "extends" form, any resulting types must inherit from Alpha,
> but cannot also be made to extend from subclasses of Alpha. The self-type
> form allows you to extend arbitrary subtypes of Alpha.
Um. What?
scala> class Foo;
defined class Foo
scala> trait Bar extends Foo;
defined trait Bar
scala> class Baz extends Foo;
defined class Baz
scala> new Baz with Bar;
res0: Baz with Bar = $anon$1@e51bda
> And while we are talking about self-types, can someone tell me what the use
> case is for using a self-type declaration to alias "this" with some other
> name? That strikes me as a recipe for confusion, but it's such an unlikely
> design choice that someone must have had a serious rationale.
It's useful when you have inner classes of the same type for exampe.
class Foo{
outer =>
def foo = new Foo{
// I can refer to the outer instance as 'outer' here
}
}
On 03/04/2009 06:00 PM, Thomas Sant Ana wrote:
> How can I make the Beta trait mixable with only sub-classes of Alpha,
> instead of promoting the class it get mixed in as a subclass of Alpha?
trait Beta {
this: Alpha =>
def ...
}
-0xe1a