情報隠蔽
CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 12/87。
情報隠蔽とは、オブジェクトの内部データへの直接的なアクセスを制限するという原則です。private フィールドをゲッターやセッターと組み合わせることで、オブジェクトの状態の周囲に保護バリアを作成します。
情報隠蔽(information hiding)を行わない場合に何が起こるか考えてみましょう:
public class Temperature {
public double celsius; // 直接公開されている
}
// 誰でも無効な値を設定できてしまう
Temperature t = new Temperature();
t.celsius = -500; // 絶対零度を下回っている - 不可能です!情報隠蔽により、データのアクセスや変更の方法を制御できます:
public class Temperature {
private double celsius;
public void setCelsius(double celsius) {
if (celsius >= -273.15) {
this.celsius = celsius;
}
}
public double getCelsius() {
return celsius;
}
}これで、無効な温度は自動的に拒否されるようになります。内部表現は隠蔽されているため、クラスを使用するコードに影響を与えることなく、後で温度の内部的な保存方法(おそらくケルビンなど)を変更することができます。
このアプローチには、3つの主な利点があります。バリデーション(検証)はデータの整合性を保証し、柔軟性は外部のコードを壊すことなく内部の変更を可能にし、制御はデータに対してどのような操作を許可するかを正確に決定できるようにします。
チャレンジ
簡単機密データを保護し、制御されたアクセスを通じてセキュリティルールを適用することで、情報の隠蔽(information hiding)を実証する Password 管理クラスを作成しましょう。
コードを整理するために、2つのファイルを作成します:
Password.java: 内部データを隠蔽し、パスワードの設定とアクセス方法を制御する Password クラスを作成します:- 実際のパスワードを格納する private な
passwordフィールド (String) - 許容される最小パスワード長を定義する private な
minLengthフィールド (int) - 最小長の要件を受け取るコンストラクタ
- 最小長の要件を満たすパスワードのみを受け入れるセッター
setPassword(String password)。有効な場合は保存してtrueを返し、短すぎる場合はパスワードを変更せずにfalseを返します - すべての文字をアスタリスク (
*) に置き換えたパスワードを返すゲッターgetMaskedPassword()- 実際のパスワードは決して公開しないでください! - 試行された文字列が保存されているパスワードと一致する場合は
trueを、そうでない場合はfalseを返すメソッドcheckPassword(String attempt) - 現在のパスワードの長さを返す(パスワードが設定されていない場合は 0 を返す)ゲッター
getLength()
- 実際のパスワードを格納する private な
Main.java: 最小長 6 で Password オブジェクトを作成し、2つの入力(設定するパスワードとチェックする試行パスワード)を読み取ります。次の3行を出力してください:Set: trueまたはSet: false(パスワード設定の結果)Masked: ******(マスクされたバージョンのパスワード)Match: trueまたはMatch: false(試行チェックの結果)
入力として、設定するパスワードと、チェックするパスワードの試行の2つを受け取ります。
実際のパスワードがクラスの外部から直接アクセスできないことに注目してください。これが情報の隠蔽の実践です。クラスは、どの情報が公開され、パスワードがどのように変更されるかを正確に制御します。
チートシート
情報隠蔽は、private フィールドをゲッターおよびセッターと組み合わせて使用することで、オブジェクトの内部データへの直接アクセスを制限します。
情報隠蔽を行わない場合、フィールドが公開され、無効な値が設定される可能性があります。
public class Temperature {
public double celsius; // 直接公開されている
}
Temperature t = new Temperature();
t.celsius = -500; // 無効な値が許可されてしまう情報隠蔽を行うと、アクセスを制御し、データを検証できます。
public class Temperature {
private double celsius;
public void setCelsius(double celsius) {
if (celsius >= -273.15) {
this.celsius = celsius;
}
}
public double getCelsius() {
return celsius;
}
}情報隠蔽の主な利点:
- 検証: 無効な値を拒否することで、データの整合性を確保します
- 柔軟性: 外部のコードに影響を与えることなく、内部の変更を可能にします
- 制御: データに対してどのような操作を許可するかを決定できます
自分で試してみよう
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 設定するパスワードを読み込む
String passwordToSet = scanner.nextLine();
// チェックするパスワードの試行を読み込む
String passwordAttempt = scanner.nextLine();
// TODO: 最小長 6 の Password オブジェクトを作成する
// TODO: パスワードを設定し、結果("Set: true" または "Set: false")を出力する
// TODO: マスクされたパスワード("Masked: ******")を出力する
// TODO: パスワードの試行をチェックし、結果("Match: true" または "Match: false")を出力する
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造