Spec2.8Chap5b2

5.2 修飾子 (Modifiers)

構文:

   Modifier            ::=   LocalModifier
                         |   AccessModifier
                         |   'override'
   LocalModifier       ::=   'abstract'
                         |   'final'
                         |   'sealed'
                         |   'implicit'
                         |   'lazy'
   AccessModifier      ::=   ('private' | 'protected') [AccessQualifier]
   AccessQualifier     ::=   '[' (id | 'this') ']'

Member definitions may be preceded by modifiers which affect the accessibility and usage of the identifiers bound by them. If several modifiers are given, their order does not matter, but the same modifier may not occur more than once. Modifiers preceding a repeated definition apply to all constituent definitions. The rules governing the validity and meaning of a modifier are as follows .

メンバー定義には修飾子が先行することがあり、 それらは結びつく識別子のアクセス性と使用法に影響を与えます。 複数の修飾子が与えられていても、その順番は重要ではありません。 しかし同じ修飾子は一度以上は現れはいけません。 定義の繰り返しに先行する修飾子は、各定義すべてに適用されます。 修飾子の有効性と意味を決定する規則は次の通りです。

・ The private modifier can be used with any definition or declaration in a template . Such members can be accessed only from within the directly enclosing template and its companion module or companion class (§5.4). They are not inherited by subclasses and they may not override definitions in parent classes .

・ private 修飾子はテンプレート中の任意の定義または宣言と共に使えます。 そのようなメンバーは、直接に取り囲むテンプレートとそのコンパニオンモジュール あるいはコンパニオンクラス (§5.4)中からのみアクセスできます。 それらはサブクラスによって継承されません。 また、それらは親クラス中の定義をオーバライドできません。

The modifier can be qualified with an identifier C (e.g. private[C]) that must denote a class or package enclosing the definition. Members labeled with such a modifier are accessible respectively only from code inside the package C or only from code inside the class C and its companion module (§5.4) Such members are also inherited only from templates inside C .

修飾子は識別子 C で 限定修飾(qualified) でき (たとえば private[C])、 この C は定義を囲むパッケージあるいはクラスを表していなければなりません。 そのような修飾子が印されたメンバーは、パッケージ C のコード中から、 あるいはクラス C とそのコンパニオンモジュール (§5.4)のコード中からのみ、 それぞれアクセス可能です。 そのようなメンバーはまた、C 中のテンプレートからのみ継承されます。

An different form of qualification is private[this]. A member M marked with this modifier can be accessed only from within the object in which it is defined. That is, a selection p.M is only legal if the prefix is this or O.this, for some class O enclosing the reference. In addition, the restrictions for unqualified private apply .

private[this] は限定修飾の異なる形です。この修飾子を使ってマークされた メンバー M は、それが定義されたオブジェクト内からのみアクセスできます。 すなわち、選択 p.M は、その参照を囲むあるクラス O があって、 前置子が this あるいは O.this である場合のみ正しいとされます。 加えて、限定修飾なしの private の制約が適用されます。

限定修飾子がない private と印されたメンバーは、 クラス非公開(class-private) と呼ばれるのに対して、 private[this] と印されたメンバーは、 オブジェクト非公開(object-private) と呼ばれます。 メンバーは、もしそれがクラス非公開あるいはオブジェクト非公開で、private[C] (ここで C は識別子) とマークされていないなら、 非公開(private) です。; 後者の場合、そのメンバーは 限定非公開 (qulified private) と呼ばれます。

Class-private or object-private members may not be abstract, and may not have protected or override modifiers .

クラス非公開あるいはオブジェクト非公開のメンバーは、抽象であってはならず、 また、protected あるいは override 修飾子を持ってはいけません。

・ protected 修飾子はクラスメンバ定義に適用されます。 クラスの protected メンバーは、次の中からアクセスできます。

  • the template of the defining class,
  • all templates that have the defining class as a base class,
  • the companion module of any of those classes.
  • 定義しているクラスのテンプレート、
  • 定義しているクラスを基底クラスとしてもつ、すべてのテンプレート
  • それらクラスの任意のコンパニオンモジュール

protected 修飾子は、識別子 C で限定修飾できます(たとえば、protected[C])。 ここで C は、その定義を囲むクラスあるいはパッケージを表さなくてはなりません。 そのような修飾子を印されたメンバーもまた、パッケージ C 中のすべてのコードから、 あるいはクラス C とそのコンパニオンモジュール (§5.4)中のすべてのコードから、 それぞれアクセス可能です。

protected 識別子 x は、 次の 1 つが適用される場合に限り、選択 r.x 中でメンバー名として使えます。

  • そのアクセスがメンバーを定義しているテンプレート中にあるか、あるいは、限定修飾 C が与えられている場合は、そのアクセスがパッケージ C 中あるいはクラス C 中、あるいはそのコンパニオンモジュール中にある。あるいは、
  • r は、予約語 this あるいは super の 1 つ。あるいは
  • r の型が、そのアクセスを含むクラスの型インスタンスに適合する。

protected[this] は、限定修飾の異なる形です。 この修飾子を印された メンバー M は、それが定義されたオブジェクト内からのみアクセスできます。 すなわち、選択 p.M は、その参照を囲むあるクラス O に対して、前置子が this あるいは O.this である場合のみ正しいとされます。 加えて、限定修飾なしの protected の制約が適用されます。

・ override 修飾子は、クラスメンバ定義または宣言に適用されます。 これは親クラス中の他のある具象メンバー定義をオーバライドする、 メンバー定義/宣言について必須です。もし override 修飾子が 与えられていれば、少なくとも 1 つのオーバライドされる(具象あるいは抽象の) メンバー定義/宣言がなければなりません。

・ override 修飾子は abstract 修飾子と組み合わされるとき、意味が追加されます。 この修飾子の組合せは、トレイトの値メンバーに対してのみ許されます。

We call a member M of a template incomplete if it is either abstract (i.e. defined by a declaration), or it is labeled abstract and override and every member overridden by M is again incomplete .

テンプレートのメンバー M は、もしそれが抽象(すなわち、 宣言によって定義されている)であるか、あるいは、abstract かつ override と印されているなら、 不完全(incomplete) と呼ばれます。 そして、M によってオーバライドされたすべてのメンバーは、再び不完全です。

abstract override 修飾子の組合せは、 メンバーが具象か抽象かということに影響を与えないことに注意してください。 メンバーは、もしそれに関して宣言だけが与えられていれば 抽象(abstract) であり、 もし完全な定義が与えられていれば 具象(concrete) です。

・ The abstract modifier is used in class definitions. It is redundant for traits, and mandatory for all other classes which have incomplete members. Abstract classes cannot be instantiated (§6.10) with a constructor invocation unless followed by mixins and/or a refinement which override all incomplete members of the class. Only abstract classes and traits can have abstract term members .

・ abstract 修飾子はクラス定義の中で使います。これはトレイトには不必要であり、 不完全なメンバーを持つ他のすべてのクラスでは必須です。 抽象クラスは、 クラスのすべての不完全なメンバーをオーバライドするミックスインや細別 (refinement) が後に続かないなら、 コンストラクタ呼び出しでインスタンス化 (§6.10) することはできません。 抽象クラスとトレイトだけが抽象項(term)メンバーを持てます。 abstract 修飾子は、クラスメンバ定義についても override と一緒に使えます。 その場合、前の議論が適用されます。

・ final 修飾子は、クラスメンバ定義とクラス定義に適用されます。 サブクラス中で final クラスメンバー定義をオーバライドしてはいけません。 テンプレートは final クラスを継承できません。 final はオブジェクト定義には不必要です。final クラス/オブジェクトのメンバーは、 暗黙のうちに同様に final です。ですから、 それらについても final 修飾子は不必要です。 final は不完全なメンバーに適用できず、 また、1 つの修飾子リスト中で sealed とは一緒には使えません。

・ The sealed modifier applies to class definitions. A sealed class may not be directly inherited, except if the inheriting template is defined in the same source file as the inherited class. However, subclasses of a sealed class can be inherited anywhere .

・ sealed 修飾子は、クラス定義に適用されます。 sealed クラスは、継承するテンプレートを継承されるクラスと同じソースファイル中で定義する場合を除き、直接には継承できません。 しかし、sealed クラスのサブクラスはどこででも継承できます。

・ lazy 修飾子は値定義に適用されます。 遅延評価 Val は、それが最初にアクセスされる (決して起きないかもしれない)ときに初期化されます。 遅延評価 Val をその初期化中にアクセスしようとすると、 動作がループするかもしれません。初期化中に例外が送出された場合は、 その値は初期化されていないとみなされ、 後のアクセスでその右辺の評価が再び試みられるでしょう。


Example 5.2.1 : 次のコードは限定修飾された private の使用を示します。:

   package outerpkg.innerpkg
   class Outer {
     class Inner {
       private[Outer] def f()
       private[innerpkg] def g()
       private[outerpkg] def h()
     }
   }

ここで、メソッド f へのアクセスは、OuterClass 内ならどこにでも現れることができますが、その外では現われることはできません。 メソッド g へのアクセスは、Java の package-private の場合と同じように、 パッケージ outerpkg.innerpkg 内のどこにでも現われることができます。 最後に、メソッド h へのアクセスは、パッケージ outerpkg 内の、 そのパッケージが含むパッケージを含めて、どこにでも現われることができます。


Example 5.2.2 : クライアントにクラスの新しいインスタンスを構築させないための 1 つの方法は、 そのクラスを abstart かつ sealed と宣言することです。:

   object m {
     abstract sealed class C (x: Int) {
       def nextC = new C(x + 1) {}
     }
     val empty = new C(0) {}
   }

たとえば、上記のコード中でクライアントは、既存の m.C オブジェクトの nextC メソッドを呼び出すことによってのみ、クラス m.C のインスタンスを生成できます。; クライアントはクラス m.C のオブジェクトを直接生成できません。 実際、次の 2 つの行はどちらもエラーです。

   new m.C(0)    // **** error: C は abstract なのでインスタンス化できない
   new m.C(0) {} // **** error: sealed クラスからの不正継承

基本コンストラクタを private とすることで、同じようなアクセス制限を課すことが できます(Example 5.3.2 参照)。

タグ:

+ タグ編集
  • タグ:

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

最終更新:2011年03月01日 05:55
ツールボックス

下から選んでください:

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