Spec2.8Chap5a

第 5 章 クラスとオブジェクト

構文:

   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) は共にテンプレートの言葉で定義されています。



5.1 テンプレート (Templates)

構文:

   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 .

  • First, the superclass constructor sc is evaluated (§5.1.1) .
  • Then, all base classes in the template's linearization (§5.1.2) up to the template's superclass denoted by sc are mixin-evaluated. Mixin-evaluation happens in reverse order of occurrence in the linearization .
  • Finally the statement sequence stats is evaluated .

もしこれがトレイトのテンプレートでないなら、その評価は、 次のステップによって構成されます。

  • 最初に、スーパークラスコンストラクタ sc が評価されます(§5.1.1)。
  • 次に、sc によって表わされるテンプレートのスーパークラスに至る、テンプレート線形化(§5.1.2)中のすべての基底クラスは、ミックスイン評価されます。ミックスイン評価が、線形化中での出現の逆順でされます。
  • 最後に、文並び stats が評価されます。



5.1.1 コンストラクタ呼び出し (Constructor Invocations)

構文:

   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:

  • First, the prefix x is evaluated .
  • Then, the arguments args1,...,argsn are evaluated from left to right .
  • Finally, the class being constructed is initialized by evaluating the template of the class referred to by c .

コンストラクタ呼び出し x.c[targs](args1)...(argsn)の評価は、 次のステップからなります。

  • 最初に、前置子 x が評価されます。
  • 次に、引数 args1,...,argsn が左から右へ評価されます。
  • 最後に、構成されつつあるクラスが、c によって参照されるクラスのテンプレートを評価することで初期化されます。



5.1.2 クラス線形化 (Class Linearization)

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 の線形化の接尾部ではありません。



5.1.3 クラスメンバ (Class Members)

テンプレート 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´と マッチします

  1. M と M´のいずれもメソッド定義ではない。
  2. M と M´は両方とも、等価な引数型をもつ単相的なメソッドを定義する。
  3. M はパラメータなしのメソッドを定義し、M´ は空きのパラメータリスト()のメソッドを定義するかあるいは、 その逆 である。
  4. M と M´は両方とも、同数の引数型 T、T´ と、同数の型パラメータ t、t´をもつ (たとえば T´ = [t´/t]T) 多相的メソッドを定義する(訳注:英語原文では、Tや t には上線がついていました)。

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 を継承します。



5.1.4 オーバーライド (Overriding)

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´へ適用されます。

  • M´ は final と印されていないこと。
  • M は private ではないこと(§5.2)。
  • If M is labeled private[C] for some enclosing class or package C , then M´ must be labeled private[C´] for some class or package C´ where C´ equals C or C´ is contained in C .
  • If M is labeled protected, then M´ must also be labeled protected.
  • もし M が、ある取り囲むクラス/パッケージ C について private[C] と印されているなら、M´はある取り囲むクラス/パッケージ C について private[C´] と印されていること。ただしここで、C´は C に等しいか、あるいは C´は C に含まれるものとします。
  • もし M が protected と印されているなら、M´もまた protected と印されていること。
  • If M´ is not an abstract member, then M must be labeled override. Furthermore , one of two possibilities must hold:
    • either M is defined in a subclass of the class where is M´ is defined,
    • or both M and M´ override a third member M´´ which is defined in a base class of both the classes containing M and M´
  • もし M´ が抽象メンバでないなら、M は override と印されていること。さらに、次の 2 つの可能性の 1 つが満たされなくてはなりません。
    • M は、M´ が定義されているクラスのサブクラス内で定義されているか、
    • あるいは M と M´ の両方とも、M や M´ を含む両クラスの (1 つの)基底クラス内で定義されている第 3 のメンバー M´´をオーバライドする。
  • If M´ is incomplete (§5.2) in C then M must be labeled abstract override .
  • If M and M´ are both concrete value definitions, then either none of them is marked lazy or both must be marked lazy .
  • もし M´が C 中で不完全(incomplete §5.2)なら、M は abstract override と印されていること。
  • もし M と M´が両方とも具象値定義なら、そのどちらも lazy と印されないか、あるいは両方とも lazy と印されるかのどちらかであること。

パラメータなしのメソッドに関係する特別の規則があります。 もし 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 }



5.1.5 継承クロージャ (Inheritance Closure)

Let C be a class type. The inheritance closure of C is the smallest set SS of types such that

  • If T is in SS , then every type T´ which forms syntactically a part of T is also in SS .
  • If T is a class type in SS , then all parents (§5.1) of T are also in SS .

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 です。

  • もし T が SS 中にあれば、T の一部を構文的に形成するすべての型 T´もまた SS 中にある。
  • もし T が SS 中のクラス型なら、T のすべての親(§5.1)は同じく SS 中にある。

もしクラス型の継承クロージャが無数の型からなるなら、静的エラーです (この制限は、サブ型付けを決定可能とするために必要です[KP07] )。



5.1.6 事前定義 (Early Definitions)

構文:

   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>" と初期化されます。

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2011年02月23日 18:32
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。