こんにちは!今日の講義では、「アクセス修飾子」の概念を理解し、それらを使用した例を見ていきます。 「知り合いになろう」という言葉は完全に正しいわけではありませんが、それらのほとんどはこれまでの講義ですでによく知っています。念のため、本題について思い出してみましょう。 アクセス修飾子は、ほとんどの場合、コードのさまざまな部分へのアクセス レベルを制御するキーワードです。なぜ「ほとんどの場合」なのでしょうか?それらの 1 つはデフォルトで設定されており、キーワードによって示されないためです :) Java には合計 4 つのアクセス修飾子があります。最も厳格なものから最も「ソフト」なものまでの順序でリストします。
- プライベート;
- 保護されています。
- デフォルト(パッケージが表示されます);
- 公共
修飾子プライベート
Private
— 最も制限的なアクセス修飾子。これにより、単一クラス内のデータとメソッドの可視性が制限されます。この修飾子については、ゲッターとセッターに関する講義でご存知でしょう。この例を覚えていますか?
public class Cat {
public String name;
public int age;
public int weight;
public Cat(String name, int age, int weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
public Cat() {
}
public void sayMeow() {
System.out.println("Meow!");
}
}
public class Main {
public static void main(String[] args) {
Cat cat = new Cat();
cat.name = "";
cat.age = -1000;
cat.weight = 0;
}
}
これについては以前の記事で取り上げました。ここで私たちは重大な間違いを犯しました。データを開いた結果、他のプログラマーがクラス フィールドに直接アクセスしてその値を変更してしまうことになりました。さらに、これらの値はチェックなしで割り当てられたため、プログラムでは、年齢が-1000歳、名前が「」、体重が0の猫を作成することができます。この問題を解決するには、次のようにします。getter と setter を使用し、修飾子を使用してデータへのアクセスを制限しましたprivate
。
public class Cat {
private String name;
private int age;
private int weight;
public Cat(String name, int age, int weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
public Cat() {
}
public void sayMeow() {
System.out.println("Meow!");
}
public String getName() {
return name;
}
public void setName(String name) {
// checking the input parameter
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
// checking the input parameter
this.age = age;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
// checking the input parameter
this.weight = weight;
}
}
実際、フィールドへのアクセスを制限し、ゲッターセッターを実装することは、実際の作業での最も一般的な使用例ですprivate
。 つまり、プログラムにカプセル化を実装することが、この修飾子の主な目的です。 ちなみに、これはフィールドに限らず当てはまります。プログラムに非常に複雑な機能を実装するメソッドがあると想像してください。これを例として考え出すと...メソッドがreadDataFromCollider()
データを含むアドレスを入力として受け取り、バイト形式でラージハドロン衝突型加速器からデータを読み取り、このデータをテキストに変換し、ファイルに書き込んで印刷するとします。コードは言うまでもなく、メソッドの説明さえ不気味に見えます:) コードの可読性を高めるには、複雑なメソッド ロジックを 1 か所に書かず、逆に、機能を別々のメソッドに分割するとよいでしょう。 。たとえば、このメソッドは、データの読み取り、コライダーから読み取られたデータのテキストへの変換、結果のテキストのファイルへの保存、およびデータ ファイルの印刷readByteData()
を担当します。この方法は最終的にははるかに簡単になります。 convertBytesToSymbols()
saveToFile()
printColliderData()
readDataFromCollider()
public class ColliderUtil {
public void readDataFromCollider(Path pathToData) {
byte[] colliderData = readByteData(pathToData);
String[] textData = convertBytesToSymbols(colliderData);
File fileWithData = saveToFile(textData);
printColliderData(fileWithData);
}
public byte[] readByteData(Path pathToData) {
// reads data in bytes
}
public String[] convertBytesToSymbols(byte[] colliderDataInBytes) {
// convert bytes to characters
}
public File saveToFile(String[] colliderData) {
// save the read data to a file
}
public void printColliderData(File fileWithColliderData) {
// print data from file
}
}
ただし、インターフェイスに関する講義で覚えているように、ユーザーは最終インターフェイスにしかアクセスできません。そして、私たちの 4 つのメソッドはその一部ではありません。これらは補助的なものです。コードの可読性を向上させ、4 つの異なるタスクを 1 つのメソッドに詰め込むのを避けるために作成されました。ユーザーにこれらのメソッドへのアクセス権を与える必要はありません。ユーザーが collider を操作するときにこのメソッドにアクセスできる場合convertBytesToSymbols()
、このメソッドが何であるか、またなぜそれが必要なのかを理解できない可能性が高くなります。どのバイトが変換されるのでしょうか? 彼らはどこから来ましたか?なぜテキストに変換するのでしょうか? このメソッドで実行されるロジックは、ユーザー インターフェイスの一部ではありません。メソッドのみがreadDataFromCollider()
インターフェイスの一部です。これら 4 つの「内部」メソッドをどうするか? 右!修飾子を使用してアクセスを制限しますprivate
。こうすることで、クラス内で簡単に作業を行うことができ、ユーザーを混乱させることなく、それぞれのロジックを個別に確認する必要がなくなりました。
public class ColliderUtil {
public void readDataFromCollider(Path pathToData) {
byte[] colliderData = readByteData(pathToData);
String[] textData = convertBytesToSymbols(colliderData);
File fileWithData = saveToFile(textData);
printColliderData(fileWithData);
}
private byte[] readByteData(Path pathToData) {
// reads data in bytes
}
private String[] convertBytesToSymbols(byte[] colliderDataInBytes) {
// convert bytes to characters
}
private File saveToFile(String[] colliderData) {
// save the read data to a file
}
private void printColliderData(File fileWithColliderData) {
// print data from file
}
}
修飾子が保護されています
次に制限的なアクセス修飾子は ですprotected
。 アクセス修飾子で指定されたフィールドとメソッドprotected
が表示されます。
- 私たちと同じパッケージ内のすべてのクラス内。
- 私たちのクラスのすべての後継クラス内で。
protected
適用されるケースは よりもはるかに少なくprivate
、それらは特殊です。諜報機関の秘密エージェントを表す抽象クラスAbstractSecretAgent
と、top_secret
このクラスとその子孫を含むパッケージがあると想像してください。具体的なクラス ( FBISecretAgent
、MI6SecretAgent
などMossadSecretAgent
)はそこから継承されます。抽象クラス内にエージェント カウンターを実装します。プログラムのどこかに新しいエージェントオブジェクトが作成されると、それが増えていきます。
package top_secret;
public abstract class AbstractSecretAgent {
public static int agentCount = 0;
}
しかし、私たちのエージェントは秘密です!これは、自分の番号については自分だけが知り、他の人は知らないことを意味します。protected
フィールドに修飾子を簡単に追加するagentCount
と、他のシークレット エージェント クラスのオブジェクト、または「シークレット」パッケージにあるクラスのいずれかがその値を取得できますtop_secret
。
public abstract class AbstractSecretAgent {
protected static int agentCount = 0;
}
このような特定のタスクには修飾子が必要ですprotected
:)
パッケージ可視修飾子
リストの次は修飾子default
、または とも呼ばれますpackage visible
。Java ではすべてのフィールドとメソッドに対してデフォルトで設定されているため、これはキーワードによって示されません。コードに書き込むと -
int x = 10;
...変数にx
もこれと同じアクセス権がありますpackage visible
。メソッド (または変数) が修飾子でマークされていない場合、「デフォルト修飾子」でマークされているとみなされます。このような修飾子を持つ変数またはメソッド (つまり、修飾子がまったくない) は、それらが宣言されているパッケージのすべてのクラスに表示されます。そして彼らだけに。修飾子と同様に、その用途は制限されていますprotected
。ほとんどの場合、default
-access は、このパッケージ内の他のすべてのクラスの機能を実装していないユーティリティ クラスがいくつかあるパッケージで使用されます。例を挙げてみましょう。「サービス」パッケージがあると想像してください。内部には、データベースを操作するさまざまなクラスがあります。たとえば、UserService
データベースからユーザー データを読み取るクラス、CarService
同じデータベースから車に関するデータを読み取るクラス、およびその他のクラスがあり、それぞれが独自のタイプのオブジェクトを処理し、それらに関するデータをデータベースから読み取ります。
package services;
public class UserService {
}
package services;
public class CarService {
}
ただし、データベース内のデータがある形式であるにもかかわらず、別の形式が必要になるという状況が簡単に発生します。データベース内のユーザーの生年月日が TIMESTAMP WITH TIME ZONE... の形式で保存されていると想像してください。
2014-04-04 20:32:59.390583+02
...代わりに、最も単純なオブジェクトが必要です - java.util.Date
。services
この目的のために、パッケージ内に特別なクラスを作成できますMapper
。彼は、データベースのデータを、私たちがよく知っている Java オブジェクトに変換する責任を負います。単純なヘルパークラス。通常、すべてのクラスを として作成しますpublic class ClassName
が、これは必須ではありません。ヘルパー クラスは次のように簡単に宣言できますclass Mapper
。この場合でも、その機能は引き続き実行されますが、パッケージの外部には表示されませんservices
。
package services;
class Mapper {
}
package services;
public class CarService {
Mapper mapper;
}
そして、これは実際、正しいロジックです。なぜパッケージの外部にいる人には、同じパッケージのクラスでのみ機能する補助クラスが見えるのでしょうか?
パブリック修飾子
そしてリストの最後ですが、重要なのは修飾子ですpublic
。あなたは JavaRush で勉強し、 を立ち上げた初日に彼に会いましたpublic static void main(String[] args)
。 インターフェイスに関する講義を勉強したので、その目的は明らかです :) 結局のところ、インターフェイスはpublic
ユーザーに何かを提供するために作成されました。たとえば、プログラムのインターフェイスです。たとえば、ロシア語のテキストを英語に翻訳できる翻訳プログラムを作成したとします。translate(String textInRussian)
必要なロジックが実装されたメソッドが作成されました。このメソッドに という単語を付けたのでpublic
、これがインターフェースの一部になります。
public class Translator {
public String translate(String textInRussian) {
// translates text from Russian to English
}
}
このメソッドの呼び出しをプログラム画面の「翻訳」ボタンに関連付けることができます。それだけです。誰でも使用できます。修飾子でマークされたコードの部分は、public
エンド ユーザーを対象としています。生活の例を挙げると、private
これらはテレビの動作中にテレビ内で発生するすべてのプロセスであり、public
ユーザーがテレビを制御できるテレビのリモコンのボタンです。同時に、テレビの仕組みや仕組みを知る必要もありません。public
リモート コントロールは、メソッドのセットです: on()
、off()
、nextChannel()
、previousChannel()
、increaseVolume()
などdecreaseVolume()
。
GO TO FULL VERSION