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 とそのコンパニオンモジュール(§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)です。
- abstract 修飾子はクラス定義の中で使います。これはトレイトには
不必要であり、不完全なメンバーを持つ他のすべてのクラスでは必須です。
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 .
抽象クラスは、クラスのすべての不完全なメンバーをオーバライドする
ミックスインや細別 (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 クラスのサブクラスは、どこでも継承できます。
遅延評価 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 :
クライアントがクラスの新しいインスタンスを構築するのを阻止するのに役立つ
イディオムは、そのクラスを 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 参照)。
5.3 クラス定義 (Class Definitions)
構文:
TmplDef ::= 'class' ClassDef
ClassDef ::= id [TypeParamClause] {Annotation}
[AccessModifier] ClassParamClauses ClassTemplateOpt
ClassParamClauses ::= {ClassParamClause}
[[nl] '(' implicit ClassParams ')']
ClassParamClause ::= [nl] '(' [ClassParams] ')'
ClassParams ::= ClassParam {',' ClassParam}
ClassParam ::= {Annotation} [{Modifier} ('val' | 'var')]
id [':' ParamType] ['=' Expr]
ClassTemplateOpt ::= 'extends' ClassTemplate | [['extends'] TemplateBody]
クラス定義の最も一般的な形は次です。
class c[tps] as m(ps1)...(psn) extends t (n >= 0)
ここで、
c は定義されるクラスの名前です。
も同じく省略されるかもしれません。その場合は、空の本体 {}
が想定されます。
This class definition defines a type c[tps] and a constructor which when applied to parameters conforming to types ps initializes instances of type c[tps] by evaluating the template t .
このクラス定義は、型 c[tps] とコンストラクタを定義し、そのコンストラクタは、
型 ps に適合するパラメータへ適用されるときにテンプレート t を評価することで、
型 c[tps] のインスタンスを初期化します。
Example 5.3.1 : 次の例は、クラス C の val と var パラメータを示します:
class C(x: Int, val y: String, var z: List[String])
val c = new C(1, "abc", List())
c.z = c.y :: c.z
Example 5.3.2 :
次のクラスは、そのコンパニオンモジュールからのみ生成できます。
object Sensitive {
def makeSensitive(credentials: Certificate): Sensitive =
if (credentials == Admin) new Sensitive()
else throw new SecurityViolationException
}
class Sensitive private () {
...
}
最終更新:2011年02月03日 14:53