【Java学習|豆知識】Javaの「カプセル化」を極める:アクセス修飾子と継承・インターフェースの正しい使い分け

導入:なぜアクセス修飾子を意識すべきなのか

Java開発において、クラスやメソッドの「アクセス修飾子」を適切に設定することは、コードの堅牢性を高めるために不可欠です。適切なアクセス制御を行わないと、意図しない外部からのデータ書き換えや、密結合による保守性の低下を招きます。本記事では、アクセス修飾子の基本から、継承やインターフェースと組み合わせた際の注意点まで、現場で役立つポイントを解説します。

基礎知識:アクセス修飾子の4つの分類

Javaには以下の4つのレベルが存在します。

1. public: どこからでもアクセス可能。
2. protected: 同一パッケージ内、または異なるパッケージのサブクラスからアクセス可能。
3. package-private(修飾子なし): 同一パッケージ内のみアクセス可能。
4. private: そのクラス内のみアクセス可能。

特に「継承」が絡む場合、protectedの挙動を正しく理解しておくことが重要です。

実装と解決策:継承とインターフェースでの活用

インターフェースの進化により、Java 8以降はdefaultメソッド、Java 9以降はprivateメソッドが使用可能になりました。インターフェース内で共通処理を隠蔽し、実装クラスに見せたくないロジックをprivateに切り出すことで、インターフェースの設計が非常に洗練されます。

サンプルプログラム:アクセス修飾子の実践例

// インターフェースの定義
interface MyInterface {
// デフォルトメソッドは実装クラスから利用可能
default void publicAction() {
System.out.println("公開されたメソッドです。");
privateHelper(); // 内部でprivateメソッドを呼び出し
}

// Java 9以降で使用可能なprivateメソッド(内部ロジックの隠蔽)
private void privateHelper() {
System.out.println("外部からは見えない内部処理を実行中...");
}
}

// 継承クラス
class BaseClass {
// サブクラスにのみ公開したい機能
protected void protectedMethod() {
System.out.println("継承先でのみ使用可能なメソッドです。");
}
}

public class Main extends BaseClass implements MyInterface {
public static void main(String[] args) {
Main app = new Main();
app.publicAction(); // インターフェースのメソッド呼び出し
app.protectedMethod(); // 継承したメソッド呼び出し
}
}

応用・注意点:現場で陥りやすい罠

現場で最も注意すべきは、「必要以上にpublicを広げない」ことです。特に、クラス内部の状態を保持するフィールドは、原則としてprivateにし、getter/setterを介してアクセスさせる「カプセル化」を徹底してください。

また、サブクラスでメソッドをオーバーライドする際、アクセス修飾子を狭くすることはできません。例えば、親クラスのprotectedメソッドをサブクラスでprivateに変更しようとするとコンパイルエラーになります。これは「多態性(ポリモーフィズム)」を維持するためのルールです。「親クラスの公開インターフェースは、サブクラスでも最低限維持されるべき」という原則を忘れないようにしましょう。

コメント

タイトルとURLをコピーしました