2012-02-19 15 views
16

Mi chiedo quale sia la semantica dell'utilizzo della parola chiave abstract in combinazione con uno trait.Semantica di tratti astratti in Scala

Se il tratto non definisce alcun metodi astratti, la parola chiave abstract non mi impedisce di creare un'istanza:

scala> abstract trait T 
defined trait T 

scala> new T{} 
res0: java.lang.Object with T = [email protected] 

D'altra parte, se il tratto fa definire un metodo astratto, non posso creare un'istanza (senza implementare questo metodo naturalmente), non importa se la parola abstract è presente o no:

scala> abstract trait T { def foo : Unit } 
defined trait T 

scala> new T{} 
<console>:9: error: object creation impossible, since method foo in trait T of type => Unit is not defined 
       new T{} 
       ^

scala> trait T { def foo : Unit } 
defined trait T 

scala> new T{} 
<console>:9: error: object creation impossible, since method foo in trait T of type =>  Unit is not defined 
       new T{} 
       ^

Qual è la parola abstract davanti ad un trait buono?

+2

Non è possibile creare un'istanza di un tratto. Quando dici 'new T {}' crei un oggetto anonimo che mescola il tratto T. – sschaef

risposta

1

Lei non è la creazione di un'istanza del tratto. I tratti non possono essere istanziati.

Stai creando un'istanza di una classe anonima che estende il tratto.

In generale,

new __t__ 

è equivalente a

{ class __anonymous__ extends __t__; new __anonymous__ } 

(dove __anonymous__ è un nome fresco di una classe anonima che è inaccessibile al programma utente).

Questo è dettagliato in section 6.10 Instance Creation Expressions of the Scala Language Specification.

Quindi, il motivo per cui è possibile creare un'istanza nel primo caso, è perché non si sta creando un'istanza del tratto (che è astratto) ma un oggetto (che non lo è).

Nel secondo caso, il motivo per cui non è possibile creare un'istanza è che se si eredita da qualcosa, che si tratti di un tratto o di una classe, in definitiva si deve implementare i suoi metodi astratti da qualche parte lungo la catena di ereditarietà in per istanziarlo. Nel primo caso, non ci sono metodi astratti da implementare.

La parola chiave abstract non fa alcuna differenza: i tratti sono implicitamente astratti, la parola chiave è ridondante.

+4

Penso che tu intenda che sta creando una * classe * anonima, che ha il tratto come mixin. –

+0

Siamo spiacenti, si. Un oggetto che è un'istanza di una classe anonima che è una sottoclasse del tratto. Uff. –