アクセシビリティとはメソッド、プロパティ、クラスや構造体などへのアクセス許可の範囲のことを指します。 アクセシビリティの他にも、可視性やスコープと呼ばれることもあります。
クラスのメソッドの呼び出しをクラス内からのみに限定するか、もしくはクラス外からも呼び出せるように公開するか、といったようにアクセス許可の範囲には様々な程度があります。 アクセス修飾子を指定することにより、メンバのアクセシビリティ、すなわちメンバに対するアクセス許可の範囲をどの程度に限定するか・どの範囲まで公開するかを指定することができます。
アクセス修飾子とアクセシビリティ
アクセシビリティを指定するためのものがアクセス修飾子で、Public
やPrivate
などのキーワードがアクセス修飾子にあたります。
例えば次のようなクラスにおいて、Method1
はアクセス修飾子Public
が指定されているためクラス外からも呼び出すことができますが、Method2
はPrivate
であるためクラス外からは呼び出せず、同一クラス内からのみ呼び出せます。
Public
やPrivate
以外にも、アクセス範囲を限定するための様々なアクセス修飾子があります。 アクセス修飾子の種類とその概要は次のとおりです。
アクセス修飾子 | 適用されるアクセシビリティ | 詳細 |
---|---|---|
Public
|
すべての箇所からのアクセスを許可 | 同じプロジェクト内・他のプロジェクトのすべての箇所からのアクセスが可能とするように公開する |
Friend
|
プロジェクト内からのアクセスのみ許可 | 同じプロジェクト内からのアクセスは可能とするが、他のプロジェクトからのアクセスは不可能とするように公開する (同じプロジェクト内からのアクセスに対しては Public 相当、他のプロジェクトからのアクセスに対してはPrivate 相当となる) |
Protected
|
クラス内、または派生クラスからのアクセスのみ許可 | 同じクラス内、および派生クラスからのアクセスは可能とするが、クラス外および継承関係にないクラスからのアクセスは不可能とするように公開する |
Private Protected
(VB 15.5以降) |
クラス内、またはプロジェクト内の派生クラスからのアクセスのみ許可 | 同じクラス内、および同じプロジェクト内の派生クラスからのアクセスは可能とするが、クラス外および継承関係にないクラスや、他のプロジェクトで派生しているクラスからのアクセスは不可能とする (同じプロジェクト内からのアクセスに対しては Protected 相当、他のプロジェクトからのアクセスに対してはPrivate 相当となる) |
Protected Friend
|
プロジェクト内、クラス内、または派生クラスからのアクセスのみ許可 | 同じクラス内、および派生クラス、同じプロジェクト内からのアクセスは可能とするが、他のプロジェクトおよび他のプロジェクトで宣言される派生クラスからのアクセスは不可能とするように公開する (同じプロジェクト内からのアクセスに対しては Public 相当、他のプロジェクトからのアクセスに対してはProtected 相当となる) |
Private
|
クラス内からのアクセスのみ許可 | 同じクラス内からのアクセスは可能とするが、派生クラスやクラス外からのアクセスは不可能とする (クラス外には一切公開しない) |
Protected
, Protected Friend
, Private Protected
は、継承に関わるアクセス修飾子であるため、クラスのメンバに対してのみ適用可能です。 それ以外のアクセス修飾子は、クラス以外のメンバに対しても適用可能です。 詳しくは§.アクセス修飾子を適用できる対象でも解説します。
アクセス修飾子とアクセス箇所ごとのアクセス可否をマトリクスにすると次のようになります。
アクセス箇所 | アクセス修飾子 | ||||||
---|---|---|---|---|---|---|---|
Public
|
Protected Friend
|
Friend
|
Protected
|
Private Protected
|
Private
|
||
同じクラス内から | ○ | ○ | ○ | ○ | ○ | ○ | |
同じプロジェクト内の | 派生クラスから | ○ | ○ | ○ | ○ | ○ | × |
クラス外から | ○ | ○ | ○ | × | × | × | |
他プロジェクトの | 派生クラスから | ○ | ○ | × | ○ | × | × |
クラス外から | ○ | × | × | × | × | × |
アクセス修飾子にFriend
が設定されているメンバは、同じプロジェクト内(厳密には同じアセンブリ)からのアクセスに対してはPublic
と同様にすべての箇所からアクセスすることができますが、他のプロジェクトからはPrivate
と同様に一切アクセスすることはできません。
Friend
は同じプロジェクト内のみ可、Protected
は派生クラスのみ可となることを踏まえた上で、Protected Friend
は「Friend
またはProtected
の意」つまり「同じプロジェクト内または派生クラスからであれば可」、Private Protected
は「Friend
かつProtected
の意」つまり「同じプロジェクト内かつ派生クラスからのみ可」と捉えると、アクセス可否の範囲がわかりやすくなります。
アクセス修飾子の選択例としてクラスライブラリを作成する場合を考えると、クラスライブラリ内からのアクセスは許可したいが、クラスライブラリの利用者にはアクセスを許可しないメソッドを作りたい、といった場面ではアクセス修飾子Friend
(およびProtected Friend
)を使うことができます。 Private Protected
も同様で、クラスライブラリ内での派生クラスからはアクセスを許可したいが、クラスライブラリの利用者には許可しない、といった場面に用いることができます。
具体例については後述するFriendとProtected Friendの例、型をPrivate・Protectedにする例もあわせてご覧ください。
アクセス修飾子を適用できる対象
アクセス修飾子は、クラスやメソッドだけでなくメンバ変数やプロパティ、構造体などにも指定することができます。 ただし、すべてのアクセス修飾子をすべての要素に指定できるわけではなく、対象によっては指定できないアクセス修飾子もあります。
次の表は、各アクセス修飾子とそのアクセス範囲、アクセス修飾子を適用できる要素をまとめたものです。
アクセス修飾子 | 適用できる対象 | ||||||
---|---|---|---|---|---|---|---|
クラス | 構造体 | モジュール | クラスメンバ | 構造体メンバ | モジュールメンバ | ローカル変数 | |
Public
|
○ | ○ | ○ | ○ | ◎ | ○ | |
Friend
|
◎ | ◎ | ◎ | ○ | ○ | ○ | |
Protected
|
○ | ||||||
Private Protected
(VB 15.5以降) |
○ | ||||||
Protected Friend
|
○ | ||||||
Private
|
○ | ○ | ○ | ◎ | ○ | ◎ | |
Dim
|
○ | ○ | ○ | ○ |
表中の◎はアクセス修飾子を指定しなかった場合のデフォルトのアクセシビリティです。 例えば構造体ではメソッドにアクセス修飾子を指定しなかった場合はPublic
として扱われますが、クラスではメソッドにアクセス修飾子を指定しなかった場合はPrivate
として扱われます。
Dimはローカル変数の宣言だけでなくクラス・構造体のメンバ変数を宣言する際にも指定することができます。 Dim自体はアクセス修飾子ではありませんが、Dimを使って宣言されたメンバ変数のアクセシビリティはデフォルトと同じ、つまり構造体ではPublic、クラス・モジュールではPrivateで宣言されているのと同じものとして扱われます。
ローカル変数はメソッド内でのみ有効である(ローカル変数はメソッド外に公開できない)ため、アクセス修飾子を指定することはできません。 (ブロックと変数のスコープ)
アクセス修飾子の適用例
次のサンプルはアクセス修飾子の適用とメンバの公開範囲を例示したものです。 詳細はコメントにあるとおりです。
型のアクセシビリティとメンバの公開範囲
メンバの公開範囲は型の公開範囲より広くすることはできません。 例えば、Friendアクセス修飾子が指定されているモジュールの場合、このモジュールはプロジェクト内からしかアクセスできません。 このモジュール内でPublic修飾子を指定したメソッドを宣言したとしても、そのメソッドはモジュール自体と同じくプロジェクト内からしかアクセスできません。
公開範囲についてはネストされた型の場合もあわせてご覧ください。
FriendとProtedted Friend
アクセス修飾子FriendとProtected Friendが指定されたメンバは、同じプロジェクト(アセンブリ)内ではどちらもPublicと同様のアクセシビリティを持ちます。
一方で、別のプロジェクト(アセンブリ)からはアクセス修飾子Friendが指定されたメンバはPrivate、Protected Friendが指定されたメンバはProtectedと同様のアクセシビリティとなります。 上記のプロジェクトProject1で定義されているクラスCを使用する別のプロジェクトProject2では、各メソッドのアクセシビリティは次のようになります。
プロパティとアクセシビリティ
プロパティでは、SetプロシージャとGetプロシージャで異なるアクセシビリティを設定することができます。 これにより、クラス外からの値の取得は許可するが、値の設定はクラス内のみに限定する、といったプロパティを用意することができます。
プロパティ宣言自体にアクセス修飾子を指定した場合は、SetプロシージャとGetプロシージャにそのアクセシビリティが適用されます。 プロパティ宣言自体にアクセス修飾子が指定されていても、SetプロシージャまたはGetプロシージャにアクセス修飾子を指定すれば、そのアクセシビリティが適用されます。
プロパティ宣言の構文についてはプロパティを参照してください。
ネストされた型とPrivate・Protected
クラス・構造体・モジュール自体にもPrivateアクセス修飾子を指定することはできますが、名前空間直下に属するものにはPrivateを指定することはできません。 Privateが指定できるのはいずれかの型の中で宣言された型、つまりネストされたクラス・構造体・モジュールのみです。 クラスであれば、これらは入れ子クラス・内部クラス・インナークラスなどと呼ばれます。
ネストされた型のメンバを参照できるようにするには、そのメンバにアクセス修飾子PublicもしくはFriendを指定する必要があります。 アクセス修飾子Privateを指定した場合は、ネストされた型の内部のみでしか参照できなくなります。
クラスの場合、ネストされた型にアクセス修飾子Protectedを指定することができます。 Protectedが指定された型は、型が宣言されているクラスとその派生クラスにのみ公開されます。
ネストされた型と親クラスのメンバのアクセシビリティ
ネストされた型からは親クラスのすべてのメンバを参照することができます。 例えば、次のようにインナークラスから親クラスのPrivateなメソッドを呼び出すこともできます。
インターフェイスの実装とアクセシビリティ
インターフェイスの実装となるメンバは、そのアクセシビリティと無関係に参照可能となる点に注意が必要です。 次の例のように、インターフェイスのメソッドをPrivateなメソッドとして実装していたとしても、インターフェイス型にキャストすればそのメソッドを呼び出すことが可能となります。