構文:
TmplDef ::= ['case'] 'class' ClassDef | ['case'] 'object' ObjectDef | 'trait' TraitDef
Classes (§5.3) and objects (§5.4) are both defined in terms of templates .
クラス(§5.3)とオブジェクト (§5.4) は共にテンプレートの言葉で定義されています。
構文:
ClassTemplate ::= [EarlyDefs] ClassParents [TemplateBody] TraitTemplate ::= [EarlyDefs] TraitParents [TemplateBody] ClassParents ::= Constr {'with' AnnotType} TraitParents ::= AnnotType {'with' AnnotType} TemplateBody ::= [nl] '{' [SelfType] TemplateStat {semi TemplateStat} '}' SelfType ::= id [':' Type] '=>' | this ':' Type '=>'
A template defines the type signature, behavior and initial state of a trait or class of objects or of a single object. Templates form part of instance creation expressions, class definitions, and object definitions. A template sc with mt1 with ... with mtn {stats} consists of a constructor invocation sc which defines the template's superclass, trait references mt1,...,mtn (n >= 0), which define the template's traits, and a statement sequence stats which contains initialization code and additional member definitions for the template.
テンプレートは、クラス/トレイトあるいはオブジェクト群あるいは 単一のオブジェクトの、 型シグニチャ、振る舞い、初期状態を定義します。 テンプレートは、 インスタンス生成式、クラス定義とオブジェクト定義等の一部を形成します。 テンプレート sc with mt1 with ... with mtn {stats} は、テンプレートの スーパークラス を定義するコンストラクタ呼び出し sc、 テンプレートの トレイト を定義するトレイト参照 mt1,...,mtn (n >= 0)、テンプレートの初期化コードと 追加のメンバー定義を含む文並び stats からなります。
Each trait reference mti must denote a trait (§5.3.3). By contrast, the superclass constructor sc normally refers to a class which is not a trait. It is possible to write a list of parents that starts with a trait reference, e.g. mt1 with ... with mtn . In that case the list of parents is implicitly extended to include the supertype of mt1 as first parent type. The new supertype must have at least one constructor that does not take parameters. In the following, we will always assume that this implicit extension has been performed, so that the first parent class of a template is a regular superclass constructor, not a trait reference .
各トレイト参照 mti は、トレイト (§5.3.3)を表わします。 これと対照して、スーパークラスコンストラクタ sc は通常、 トレイトではないクラスを参照します。 トレイト参照で始まる親のリストを書くことが可能です。例えば、 mt1 with ... with mtn。 この場合、親のリストは、最初の親型として mt1 の スーパー型を含むように暗黙のうちに展開されます。 新しいスーパー型は、 パラメータをとらない少なくとも 1 つのコンストラクタを持っていなくてはなりません。 以降では、常にこの暗黙の展開が実行されると想定します。 ですから、テンプレートの最初の親クラスは、 通常のスーパークラスコンストラクタであり、トレイト参照ではありません。
The list of parents of every class is also always implicitly extended by a reference to the scala.ScalaObject trait as last mixin. E.g.
あらゆるクラスの親のリストは同様に、最後のミックスインである scala.ScalaObject トレイトへの参照により、常に暗黙のうちに拡張されます。 つまり、
sc with mt1 with ... with mtn {stats }
は、次になります。
mt1 with ... with mtn {stats } with ScalaObject {stats}
The list of parents of a template must be well-formed. This means that the class denoted by the superclass constructor sc must be a subclass of the superclasses of all the traits mt1,...,mtn . In other words, the non-trait classes inherited by a template form a chain in the inheritance hierarchy which starts with the template's superclass .
テンプレートの親のリストは、正しい形でなければなりません。 これはスーパークラスコンストラクタ sc によって表されるクラスが、 すべてのトレイト mt1,...,mtn のスーパークラスのサブクラスでなければ ならないことを意味します。 言い換えれば、テンプレートによって継承される非トレイトクラスは、テンプレートの スーパークラスで始まる継承階層の中で、1 つのチェインを形成します。
The least proper supertype of a template is the class type or compound type (§3.2.7) consisting of all its parent class types .
テンプレートの 最小固有のスーパー型(least proper supertype) とは、 そのすべての親クラス型から構成される複合型 (§3.2.7)あるいはクラス型です。
The statement sequence stats contains member definitions that define new members or overwrite members in the parent classes. If the template forms part of an abstract class or trait definition, the statement part stats may also contain declarations of abstract members. If the template forms part of a concrete class definition, stats may still contain declarations of abstract type members, but not of abstract term members. Furthermore, stats may in any case also contain expressions; these are executed in the order they are given as part of the initialization of a template .
文並び stats は、新しいメンバーを定義するメンバー定義あるいは、 親クラス中のメンバーを上書きするメンバー定義を含みます。 もしテンプレートが抽象クラスあるいはトレイト定義の一部を形づくるなら、 文部分 stats も抽象メンバの宣言を含んでいて構いません。 もしテンプレートが具象クラス定義の一部を形づくるなら、stats はそれでも、 抽象型メンバの宣言を含んでいて構いません。 ただし、抽象項メンバの宣言は含みません。 さらに、stats は、 いずれの場合も式を含み得ます。; それらはテンプレートの初期化の一部として、与えられた順に実行されます。
The sequence of template statements may be prefixed with a formal parameter definition and an arrow, e.g. x =>, or x :T =>. If a formal parameter is given, it can be used as an alias for the reference this throughout the body of the template.
テンプレートの文並びには、形式上のパラメータ定義と矢印、たとえば x => あるいは x :T => が前置されることがあります。 もし形式上のパラメータが与えられていれば、それをテンプレート本体全体にわたって this 参照のエイリアスとして使えます。
If the formal parameter comes with a type T , this definition affects the self type S of the underlying class or object as follows: Let C be the type of the class or trait or object defining the template. If a type T is given for the formal self parameter, S is the greatest lower bound of T and C . If no type T is given, S is just C . Inside the template, the type of this is assumed to be S .
もし形式上のパラメータが型 T が一緒に書いてあるなら、その定義は、 下地となっているクラス/オブジェクトの 自己型 S に 次のような影響を与えます。: まず、C をテンプレートを定義するクラス/トレイト/オブジェクトの型であると 仮定します。 もし型 T が形式上の自己パラメータに対して与えられているなら、 S は T と C の最大の下限境界です。 もし型 T が与えられていないなら、 S はたんに C です。 テンプレート内では、this の型は S であると想定されます。
The self type of a class or object must conform to the self types of all classes which are inherited by the template t .
A second form of self type annotation reads just this: S =>. It prescribes the type S for this without introducing an alias name for it .
クラスあるいはオブジェクトの自己型は、テンプレート t によって継承されるすべてのクラスの自己型に適合しなくてはなりません。
自己型アノテーションの 2 つめの形は、たんに this: S => と書きます。 これにより、エイリアス名を導入せずに this の型 S を記述できます。
Example 5.1.1
: 次のクラス定義について考えます:
class Base extends Object {} trait Mixin extends Base {} object O extends Mixin {}
この場合、O の定義は次のように展開されます。
object O extends Base with Mixin {}
Java 型からの継承 :
テンプレートは、そのスーパークラスとして Java クラスを、
そのミックスインとして Java インターフェースを持っていても構いません。
テンプレートの評価 :
Consider a template sc with mt1 with mtn {stats } . If this is the template of a trait (§5.3.3) then its mixin-evaluation consists of an evaluation of the statement sequence stats .
テンプレート sc with mt1 with mtn {stats } について考えます。
もしこれがトレイト (§5.3.3)のテンプレートなら、 その ミックスイン評価 は、文並び stats の 評価 から構成されます。
If this is not a template of a trait, then its evaluation consists of the following steps .
もしこれがトレイトのテンプレートでないなら、その評価は、 次のステップによって構成されます。
構文:
Constr ::= AnnotType {'(' [Exprs] ')'}
Constructor invocations define the type, members, and initial state of objects created by an instance creation expression, or of parts of an object's definition which are inherited by a class or object definition. A constructor invocation is a function application x.c[targs](args1)...(argsn) , where x is a stable identifier (§3.1), c is a type name which either designates a class or defines an alias type for one, targs is a type argument list, args1,...,argsn are argument lists, and there is a constructor of that class which is applicable (§6.6) to the given arguments. If the constructor invocation uses named or default arguments, it is transformed into a block expression using the same transformation as described in (§6.6.1) .
コンストラクタ呼び出しは、型、メンバー、 そしてインスタンス生成式によって生成されるオブジェクトの初期状態、 あるいはクラス/オブジェクト定義によって継承された オブジェクト定義部分の初期状態等を定義します。 コンストラクタ呼び出しは、関数適用 x.c[targs](args1)...(argsn)です。 ここで、x は安定識別子 (§3.1)であり、c は型名で、 クラスを指定するかあるいはクラスのエイリアス型を定義するかのいずれかであり、 targs は型引数リスト、 args1,...,argsn は引数リスト、そして与えられた引数に適用可能 (§6.6)な そのクラスのコンストラクタがあります。 もしコンストラクタ呼び出しが、名前付きあるいはデフォルト引数を用いるときは、 (§6.6.1) 中で記述したのと同じ変形を使ったブロック式に変換されます。
The prefix 'x.' can be omitted. A type argument list can be given only if the class c takes type parameters. Even then it can be omitted, in which case a type argument list is synthesized using local type inference (§6.26.4). If no explicit arguments are given, an empty list () is implicitly supplied .
前置子 'x.' は省略できます。 クラス c には、それが型パラメータをとる場合に限り、 型引数リストを与えることができます。 このときにも、それを省略できます。その場合、型引数リストはローカルな型推論 (§6.26.4)を使って合成されます。 もし明示的な引数が与えられていないなら、空リスト()が暗黙のうちに補充されます。
An evaluation of a constructor invocation x.c[targs](args1)...(argsn) consists of the following steps:
コンストラクタ呼び出し x.c[targs](args1)...(argsn)の評価は、 次のステップからなります。
The classes reachable through transitive closure of the direct inheritance relation from a class C are called the base classes of C . Because of mixins, the inheritance relationship on base classes forms in general a directed acyclic graph. A linearization of this graph is defined as follows .
クラス C からの直接の継承関係の推移的なクロージャを通して到達可能なクラスは、 C の 基底クラス(base classes) と呼ばれます。 ミックスインにより、基底クラス上の継承関係は一般に有向非巡回グラフになります。 このグラフの線形化は、次のように定義されています。
定義 5.1.2
:
Let C be a class with template C1 with ... with Cn { stats }. The linearization of C , LL(C) is defined as follows:
C をテンプレート C1 with ... with Cn { stats } をもつクラスとします。 C の線形化 LL(C)は、次のように定義されます。:
LL(C) = C , LL(Cn) ⊕ ... ⊕ LL(C1)
Here ⊕ denotes concatenation where elements of the right operand replace identical elements of the left operand:
ここで ⊕ は連結を表し、右オペランドを左オペランドの同一の要素で置き換えます。:
{a, A} ⊕ B = a,(A ⊕ B) if a ∉ B = A ⊕ B if a ∈ B
Example 5.1.3
: 次のクラス定義について考えます。
abstract class AbsIterator extends AnyRef { ... } trait RichIterator extends AbsIterator { ... } class StringIterator extends AbsIterator { ... } class Iter extends StringIterator with RichIterator { ... }
クラス Iter の線形化は、次のようになります。
{Iter,RichIterator,StringIterator,AbsIterator,ScalaObject,AnyRef,Any}
このリストの中ではトレイト ScalaObject が現れます。なぜなら、 それはすべての Scala クラスに最後のミックスインとして加えられるからです (§5.1)。
クラス線形化は、継承関係を精緻化することに注意してください。: もし C が D のサブクラスなら、C と D 両方が現れるどのような線形化中でも、 C は D より先に現れます。 定義 5.1.2 は、 クラス線形化が常にその直上のスーパークラスの線形化を接尾部として含む、 という特性も満たします。
例えば、StringIterator の線形化は、
{ StringIterator, AbsIterator, ScalaObject, AnyRef, Any }
です。これは、そのサブクラス Iter の線形化の接尾部となっています。 同じことはミックスインの線形化では、正しくありません。 例えば、RichIterator の線形化は次です。
{ RichIterator, AbsIterator, ScalaObject, AnyRef, Any }
これは Iter の線形化の接尾部ではありません。
テンプレート C1 with ... with Cn { stats } によって定義されたクラス C は、 その文並び stats の中でメンバーを定義でき、 また、すべての親クラスからメンバーを継承できます。 Scala はメソッドの静的なオーバーロードに関して Java と C# の規則を採用しています。 ですからクラスは同じ名前の複数のメソッドを定義あるいは継承できます。
To decide whether a defined member of a class C overrides a member of a parent class, or whether the two co-exist as overloaded variants in C , Scala uses the following definition of matching on members:
クラス C の定義されたメンバーがどの親クラスのメンバーをオーバライドするか、 あるいは、C 中のオーバーロードされた変位指定として 2 つが共存するかどうかを 決めるために、Scala は次のメンバー マッチング の定義を用います。
定義 5.1.4
:
もし M と M´ が同じ名前を束縛し、次の 1 つが満たされるなら、
メンバー定義 M はメンバー定義 M´と
マッチします
。
Member definitions fall into two categories: concrete and abstract. Members of class C are either directly defined (i.e. they appear in C's statement sequence stats) or they are inherited. There are two rules that determine the set of members of a class, one for each category:
メンバー定義は 2 つのカテゴリ、具象または抽象、に分けられます。 クラス C のメンバーは、 直接定義される (すなわち、 それらは C の文並び stats 中に現れる)かあるいは、 継承された かのいずれかです。 クラスのメンバーの集合を決定する 2 つの規則があり、 それぞれ 1 つのカテゴリーに対応します。
Definition 5.1.5 A concrete member of a class C is any concrete definition M in some class Ci ∈ LL(C), except if there is a preceding class Cj ∈ LL(C) , where j < i which directly defines a concrete member M´ matching M .
An abstract member of a class C is any abstract definition M in some class Ci ∈ LL(C), except if C contains already a concrete member M´ matching M , or if there is a preceding class Cj ∈ LL(C) , where j < i , which directly defines an abstract member M´ matching M .
定義 5.1.5
:
クラス C の
具象メンバー
とは、あるクラス Ci∈LL(C) 中の
すべての具象定義 M である。
ただしここで、M にマッチする具象メンバーM´を直接定義するような、
先行するクラス Cj∈LL(C) (j < i)がある場合を除く。
クラス C の 抽象メンバー とは、 あるクラス Ci∈LL(C) 中のすべての抽象定義 M である。 ただしここで、C がすでに M にマッチする具象メンバーM´ を含むか、あるいは、 M にマッチする抽象メンバーM´を直接定義するような、先行するクラス Cj∈LL(C) (j < i)がある場合を除く。
This definition also determines the overriding relationships between matching members of a class C and its parents (§5.1.4). First, a concrete definition always overrides an abstract definition. Second, for definitions M and M' which are both concrete or both abstract, M overrides M´ if M appears in a class that precedes (inthe linearization of C) the class in which M´ is defined.
この定義は、 クラス C のマッチするメンバーとその親との間のオーバーライド関係も決定します (§5.1.4)。 第一に、具象定義は常に抽象定義をオーバライドします。 第二に、共に具象であるかあるいは共に抽象的な定義 M と M'について、 もし M が、M´ が定義されているクラスよりも(C の線形化で) 先行するクラス中に現れるなら、M は M´をオーバライドします。
It is an error if a template directly defines two matching members. It is also an error if a template contains two members (directly defined or inherited) with the same name and the same erased type (§3.7). Finally, a template is not allowed to contain two methods (directly defined or inherited) with the same name which both define default arguments.
もしテンプレートが 2 つのマッチするメンバーを直接定義しているなら、エラーです。 もしテンプレートが同じ名前と同じ消去型(erased type) (§3.7)をもつ 2 つの (直接定義されたか、あるいは継承された) メンバーを含むなら、 同様にエラーです。 最後に、テンプレートは、 同じ名前で共にデフォルト引数を定義する (直接定義されたか、あるいは継承された) 2 つのメソッドを含むことは許されていません。
Example 5.1.6
: 次のトレイト定義について考えます。
trait A { def f: Int } trait B extends A { def f: Int = 1 ; def g: Int = 2 ; def h: Int = 3 } trait C extends A { override def f: Int = 4 ; def g: Int } trait D extends B with C { def h: Int }
このときトレイト D は直接定義された抽象メンバ h を持っています。 それは、トレイト B からメンバー g を、トレイト C からメンバー f を継承します。
A member M of class C that matches (§5.1.3) a non-private member M´ of a base class of C is said to override that member. In this case the binding of the overriding member M must subsume (§3.5.2) the binding of the overridden member M´ .
C の基底クラスの非 private なメンバー M´ にマッチ (§5.1.3)する、 クラス C のメンバー M は、 そのメンバーを オーバライド すると言われます。 この場合、オーバーライドするメンバー M の束縛は、 オーバライドされるメンバー M´ の束縛を包含しなくてはなりません (§3.5.2)。 さらに、修飾子に関する次の制限が M および M´へ適用されます。
パラメータなしのメソッドに関係する特別の規則があります。 もし def f : T = ... あるいは def f = ... として定義されたパラメータなしのメソッドが、 空きのパラメータリストをもつ型 ()T´ のメソッドをオーバライドするなら、 f も同じく空きのパラメータリストを持つと想定されます。
もう 1 つの制限が抽象型メンバーに適用されます。: その上限境界として volatile 型 (§3.6)をもつ抽象型メンバーは、 volatile 型の上限境界をもたない抽象型メンバーをオーバーライドできません。
An overriding method inherits all default arguments from the definition in the superclass . By specifying default arguments in the overriding method it is possible to add new defaults (if the corresponding parameter in the superclass does not have a default) or to override the defaults of the superclass (otherwise) .
オーバーライドするメソッドは、 スーパークラス中の定義からすべてのデフォルト引数を継承します。 オーバーライドするメソッド中でデフォルト引数を指定して、 (もしスーパークラス中の対応するパラメータがデフォルトを持たないなら) 新しいデフォルトを追加したり、 あるいは(そうでなければ)、スーパークラスのデフォルトをオーバライドできます。
Example 5.1.7
: 次の定義を考えます。
trait Root { type T <: Root } trait A extends Root { type T <: A } trait B extends Root { type T <: B } trait C extends A with B
このとき、クラス定義 C は正しくありません。なぜなら、C 中の T の束縛は type T <: B であり、型 A 中の T の束縛 type T <: A の包含に失敗するからです。 この問題は、クラス C 中に型 T のオーバーライド定義を加えることで解決できます:
class C extends A with B { type T <: C }
Let C be a class type. The inheritance closure of C is the smallest set SS of types such that
It is a static error if the inheritance closure of a class type consists of an infinite number of types. (This restriction is necessary to make subtyping decidable [KP07]).
C はクラス型であるとします。 C の 継承クロージャ(inheritance closure) とは、 次のような型の最小の集合 SS です。
もしクラス型の継承クロージャが無数の型からなるなら、静的エラーです (この制限は、サブ型付けを決定可能とするために必要です[KP07] )。
構文:
EarlyDefs ::= '{' [EarlyDef {semi EarlyDef}] '}' 'with' EarlyDef ::= {Annotation} {Modifier} PatVarDef
A template may start with an early field definition clause, which serves to define certain field values before the supertype constructor is called.
テンプレートを 事前フィールド定義(early field definition) 節で始めることができ、それによりスーパー型のコンストラクタがコールされる前に、 ある特定のフィールド値を定義できます。
次のテンプレート中で
{ val p1 : T1 = e1 ... val pn : Tn = en } with sc with mt1 with mtn {stats}
The initial pattern definitions of p1,...,pn are called early definitions. They define fields which form part of the template. Every early definition must define at least one variable.
p1,...,pn 定義の最初のパターンは 事前定義(early difinition) と呼ばれます。 それらはテンプレートの一部をなすフィールドを定義します。 すべての事前定義は、少なくとも 1 つの変数を定義していなくてはなりません。
An early definition is type-checked and evaluated in the scope which is in effect just before the template being defined, augmented by any type parameters of the enclosing class and by any early definitions preceding the one being defined. In particular, any reference to this in the right-hand side of an early definition refers to the identity of this just outside the template. Consequently, it is impossible that an eaarly definition refers to the object being constructed by the template, or refers to one of its fields and methods, except for any other preceding early definition in the same section. Furthermore, references to preceding early definitions always refer to the value that's defined there, and do not take into account overriding definitions . In other words, a block of early definitions is evaluated exactly as if it was a local bock containing a number of value definitions .
事前定義は型チェックされ、そのテンプレートが定義される直前に有効なスコープ中で 評価されます。 また、取り囲むクラスのすべての型パラメータと、 定義しているものに先行するすべての事前定義によって拡張されます。 特に、事前定義の右辺における this への参照はすべて、テンプレートのすぐ外の this 識別子への参照です。 したがって、事前定義が、テンプレートによって構築中のオブジェクトを参照したり 、あるいは、同じセクション中の先行する他の事前定義以外のフィールドや メソッドの 1 つを参照することはできません。 さらに、先行する事前定義への参照は、そこで定義されている値を常に参照し、 オーバーライド定義は考慮されません。 言い換えると、事前定義ブロックはまさに、複数の値定義を含むローカルなブロック であるかのように評価されます。
Early definitions are evaluated in the order they are being defined before the superclass constructor of the template is called .
事前定義は、テンプレートのスーパークラスコンストラクタが呼ばれる前に、 それらが定義された順番で評価されます。
Example 5.1.8
:
事前定義は、通常のコンストラクタパラメータをもたないトレイトに対して
特に役立ちます。
例:
trait Greeting { val name: String val msg = "How are you, "+name } class C extends { val name = "Bob" } with Greeting { println(msg) }
上記のコードで、フィールド name は Greeting のコンストラクタが呼び出される前に初期化されます。 ですから、クラス Greeting 中のフィールド msg は "How are you, Bob" に適切に初期化されます。
If name had been initialized instead in C's normal class body, it would be initialized after the constructor of Greeting. In that case, msg would be initialized to "How are you, <null>" .
代わりに、もし name が C の通常のクラス本体中で初期化されると、 それは Greeing のコンストラクタの後に初期化されます。 その場合、msg は "How are you, <null>" と初期化されます。