アクセス修飾子
2003年5月13日
オブジェクト指向言語は、プログラムをクラスと呼ばれるモジュールに分割します。各クラスには、データ(フィールド)とメソッドで構成される機能が含まれています。(すべての言語がこれらの用語を使用するわけではありませんが、ここではこれで十分です。)言語には、クラスの機能に他のクラスがアクセスできるかどうかに関するさまざまなルールがあります。これらは、多くの場合、クラスに適用されるアクセス修飾子に基づいています。
C++の選択
おそらく最も影響力のあるアクセス修飾子のセットは、3つを持つC++で始まりました。
- public: どのクラスでも機能にアクセスできます
- protected: どのサブクラスでも機能にアクセスできます
- private: 他のクラスは機能にアクセスできません
クラスは、friend
キーワードを使用して別のクラスまたはメソッドにアクセスを許可することもできます。したがって、C++では、フレンドはお互いのプライベートな部分に触れることができるというコメントがあります。
Java
JavaはC++に基づいていました。Javaは言語にパッケージの概念を追加し、これが動作に影響を与えました。
- public: どのクラスでもアクセス可能
- (package): (デフォルトで、コードでキーワードを使用しません)同じパッケージ内のどのクラスでもアクセス可能
- protected: 同じパッケージ内のどのサブクラスまたはクラスでもアクセス可能
- private: 他のクラスはアクセスできません
JavaのprotectedとC++のprotectedの微妙な違いに注意してください(混乱を招くためだけです。)
C#
C#もC++モデルに基づいています
- public: どのクラスでもアクセス可能
- internal: 同じアセンブリ内のどのクラスでもアクセス可能(メソッドとクラスのデフォルトですが、指定することもできます)
- protected: どのサブクラスでもアクセス可能
- protected internal: 同じアセンブリ内のどのサブクラスまたはクラスでもアクセス可能
- private: 他のクラスはアクセスできません(フィールドのデフォルト)
C#では、アセンブリは物理的な構成単位です。dll、jar、またはバイナリに相当します。 C#には、Javaパッケージに似た論理単位(名前空間)もありますが、アクセス修飾子では使用されません。
Smalltalk
Smalltalkは、最も純粋なOO言語であると見なされることが多く、C++、Java、C#よりも前に存在します。アクセスを制御するためにキーワードを使用せず、基本的なポリシーを使用しました。Smalltalkerは、フィールドはプライベートであり、メソッドはパブリックであると言うでしょう。
ただし、プライベートフィールドは、C++ベースの言語での意味と同じ意味ではありません。 C++などでは、アクセスはテキストスコープとして考えられています。クラスPersonのサブクラスであるクラスProgrammerの例を考えてみましょう。インスタンスはMartinとKentの2つです。 C++では、両方のインスタンスが同じクラスであるため、MartinはKentのプライベート機能にアクセスできます。 Smalltalkの世界観では、アクセスはオブジェクトに基づいているため、MartinとKentは異なるオブジェクトであるため、MartinはKentのフィールドにアクセスする権利はありません。しかし、すべてがオブジェクトベースであるため、MartinはPersonクラスで宣言された場合でも、すべてのフィールドにアクセスできます。したがって、Smalltalkのデータは、プライベートよりも保護に近いものですが、オブジェクトスコープによっていずれにしても異なります。
アクセス制御はアクセスを制御しません
プライベートなフィールドがある場合、他のクラスはそれにアクセスできないことを意味します。間違っています! 実際には、ほとんどすべての言語でアクセス制御メカニズムを覆すことができます。通常、その方法を介してリフレクションを行うことができます。その根拠は、デバッガーやその他のシステムツールがプライベートデータを確認する必要があることが多いため、通常、リフレクションインターフェイスではこれを実行できることです。
C++にはこの種のリフレクションはありませんが、C++は基本的にオープンメモリであるため、直接メモリ操作を使用できます。
アクセス制御のポイントはアクセスを防止することではなく、クラスが一部のものを自分自身に保持したいというシグナルを送ることです。プログラミングの多くのことと同様に、アクセス修飾子を使用することは、主にコミュニケーションに関するものです。
公開されたメソッド
別のアクセスタイプであるPublishedInterfaceの余地が実際にあると私は主張してきました。プロジェクトチーム内の他のクラスに公開する機能と、APIなど他のチームに公開する機能には根本的な違いがあると思います。これらの公開された機能は、パブリック機能のサブセットであり、異なる扱いをしなければならないため、公開とパブリックの区別は、パブリックとプライベートの区別よりも重要であると私は考えています。