All three forms are valid, and have the effect that B
is assumed as the type of this
in class A
.
The first two variants
trait A { self: B => ... }
trait A { foo: B => ... }
introduce self
(respectively, foo
) as an alias for this
in trait A
. This is useful for accessing the this
reference from an inner class. I.e. you could then use self
instead of A.this
when accessing the this
reference of the trait A
from a class nested within it. Example:
class MyFrame extends JFrame { frame =>
getContentPane().add( new JButton( "Hide" ) {
addActionListener( new ActionListener {
def actionPerformed( e: ActionEvent ) {
// this.setVisible( false ) --> shadowed by JButton!
frame.setVisible( false )
}
})
})
}
The third variant,
trait A { this: B => ... }
does not introduce an alias for this
; it just sets the self type.
There is a difference in that this
always refers to the object defined by the innermost template.
The expression
this
can appear in the statement part of a template or compound type. It stands for the object being defined by the innermost template or compound type enclosing the reference. If this is a compound type, the type ofthis
is that compound type. If it is a template of a class or object definition with simple name C, the type of this is the same as the type of C.this
. (Scala Ref. §6.5)
So, if you call your self-type foo
, you could still refer to it as this
(unless, of course, you are in an inner template in which case this
will refer to the object defined by it – and unless you don’t give the inner template’s self-type the same name) but obviously not the other way round.
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