Java
 Computer >> コンピューター >  >> プログラミング >> Java

Javaのインターフェース型参照からサブクラスのメンバーにアクセスする方法

Javaでは、インターフェース型やスーパークラス型の参照変数にサブクラスのオブジェクトを代入した場合、その参照を通じてアクセスできるのは、宣言元の型(インターフェースやスーパークラス)が持つメンバーのみです。この参照を使ってサブクラス(派生クラス)独自のメンバーやメソッドにアクセスしようとすると、コンパイルエラーが発生します。

例:コンパイルエラーが発生するケース

interface Sample {
   void demoMethod1();
}
public class InterfaceExample implements Sample {
   public void display() {
      System.out.println("This is a method of the sub class");
   }
   public void demoMethod1() {
      System.out.println("This is demo method-1");
   }
   public static void main(String args[]) {
      Sample obj = new InterfaceExample();
      obj.demoMethod1();
      obj.display();
   }
}

出力結果

InterfaceExample.java:14: error: cannot find symbol
      obj.display();
          ^
   symbol: method display()
   location: variable obj of type Sample
1 error

この例では、Sample型の変数objInterfaceExampleのインスタンスを代入しています。obj.demoMethod1()はインターフェースに宣言されたメソッドなので問題なく呼び出せますが、display()Sampleインターフェースには存在しないため、「cannot find symbol」というコンパイルエラーとなります。これは、コンパイラが参照変数の宣言型に基づいてメンバーの存在をチェックするためです。

解決策:キャスト演算子によるダウンキャスト

スーパークラス型(またはインターフェース型)の参照から派生クラスのメンバーにアクセスしたい場合は、キャスト演算子を使って参照を明示的に派生クラス型へダウンキャストする必要があります。

interface Sample {
   void demoMethod1();
}
public class InterfaceExample implements Sample {
   public void display() {
      System.out.println("This is a method of the sub class");
   }
   public void demoMethod1() {
      System.out.println("This is demo method-1");
   }
   public static void main(String args[]) {
      Sample obj = new InterfaceExample();
      obj.demoMethod1();
      ((InterfaceExample) obj).display();
   }
}

出力結果

This is demo method-1
This is a method of the sub class

((InterfaceExample) obj).display()のように、objInterfaceExample型にキャストすることで、サブクラス独自のメソッドdisplay()を正常に呼び出せるようになりました。

補足:instanceofによる安全なダウンキャスト

実際の開発では、実際のオブジェクトがキャスト先の型と一致しない場合にClassCastExceptionが発生する可能性があります。そのため、instanceof演算子で型を確認してからキャストするのが安全な書き方です。

if (obj instanceof InterfaceExample) {
   ((InterfaceExample) obj).display();
}

このように、ポリモーフィズムを活用しつつ派生クラス固有の機能が必要な場面では、適切なダウンキャストを行うことで柔軟に対応できます。

  1. Javaで文字列をInputStreamオブジェクトに変換する方法

    ByteArrayInputStreamクラスとは ByteArrayInputStreamは、InputStreamクラスのサブクラスであり、ストリームから読み取り可能なバイトデータを内部バッファに保持するクラスです。このクラスを利用することで、メモリ上のデータをあたかも入力ストリームであるかのように扱うことができます。 Javaで文字列(String)をInputStreamオブジェクトに変換したい場合、このByteArrayInputStreamクラスを使うのが最もシンプルな方法です。コンストラクタにはバイト配列を渡す必要があるため、StringクラスのgetBytes()メソッドを呼

  2. Javaで別のパッケージのクラスにアクセスする3つの方法

    Javaでは、クラスをパッケージにまとめることでコードを整理できますが、別のパッケージにあるクラスを利用したい場合には特別な記述方法が必要です。ここでは、payrollパッケージ内に定義されたBossクラスを例に、その方法を解説します。例:payrollパッケージ内のBossクラスpackage payroll; public class Boss { public void payEmployee(Employee e) { e.mailCheck(); } }上記のコードでは、BossクラスとEmployeeクラスが同じpayrollパッケージ内にあるため、