プロが教える店舗&オフィスのセキュリティ対策術

実際に使うことは考えられないのですが、試験対策用の勉強の中で異なるインターフェイス同士のキャストは可能であるとの記述があり、その意味が解らず混乱しています。質問は
1.そもそも本当にインターフェイス同士のキャストは可能なのか?
2.可能だとしたらそのキャストを認めたJavaコンパイラーを作った人の意図はなんなのか?
3.インターフェイス同士のキャストを利用する場面はあるのか?
の3点です。
よろしくお願い致します。

A 回答 (5件)

例えば「食べられる物」を表す「Eatableインターフェイス」と「液体」を表す「Liquidインターフェイス」があったとして



・Checken implements Eatable
・Gasoline implements Liquid
・Beer implements Eatable, Liquid

というクラスがあった場合、
「食べ物」としてオブジェクトを扱いたい場合は
CheckenやBeerをEatableオブジェクトとして扱い、
「液体」として処理を行う場合には
GasolineやBeerをLiquidオブジェクトとして扱います。

上記のように2つ以上の抽象的なもの(=インターフェイス)として扱いたいクラスがあれば継承関係にないインターフェイス同士でキャストを利用する場面があるかもしれません。
ただ、
Liquid beerLiquid = (Liquid)beerEatable;
のような明示的なキャストは必要なく、
暗黙的なキャストが行われるだけだと思います。
具体的には最近流行のフレームワークなどでは
SerializableインターフェイスやCloneableインターフェイスとして内部処理を行うものもあるようです。
この2つのインターフェイスはもちろん継承関係にはありません。
    • good
    • 0
この回答へのお礼

ご解答頂き、誠にありがとうございました。
具体的な例を挙げて頂いたのでとても解りやすく、疑問が完全に解決しました。

お礼日時:2005/05/14 23:44

以下のソースを実行したら、実行できました。


(貼り付けのために全角スペースに置換してあります)

クラスFooはインタフェースAaaとBbbをインプリメンツしていますが、AaaとBbbには継承関係はありません。

それでも、変数a を (Bbb) でキャストできるところが面白いですね。

public class Foo implements Aaa, Bbb{

 public static void main(String[] args) {
  Aaa a = new Foo();
  a.aaa();
  Bbb b = (Bbb)a;
  b.bbb();
 }

 public void aaa() {
  System.out.println("aaa");
 }

 public void bbb() {
  System.out.println("bbb");
 }
}

interface Aaa{
 void aaa();
}

interface Bbb{
 void bbb();
}
    • good
    • 0
この回答へのお礼

ご解答いただきまして、誠にありがとうございました。

お礼日時:2005/05/14 23:45

他の回答者さんの補足として、


1の回答の単純なソースを書きます。
みにくいと思いますが参考にしてください。
public class ClassA implements A {
public void aaa() {
System.out.println("aaa");
}
public void bbb() {
System.out.println("bbb");
}
public static void main(String[] args) {
A a = new ClassA();
a.aaa();
B b = (B)a; // A から B へキャスト
b.bbb();
}
}
interface A extends B {
public void aaa();
}
interface B {
public void bbb();
}
インタフェースもクラスと同様にextendsして親子関係を作れるので、キャストというか例えばBを引数とするメソッドにAのインスタンスを渡すことが可能です。
明示的にキャストする場面はちょっと思い浮かびませんけども。
    • good
    • 0
この回答へのお礼

ご解答、誠にありがとうございます。
hiraku-jp様のお礼文でも少し触れましたが、親子関係の無い場合でも
インターフェイスのキャストがコンパイル可能なのでしょうか?

public class ClassA implements A {
public void aaa() {
System.out.println("aaa");
}
public static void main(String[] args) {
A a = new ClassA();
a.aaa();
B b = (B)a; // A から B へキャスト
b.bbb();
}
}
interface A {
public void aaa();
}
interface B {
//Aとの継承関係をはずしました
public void bbb();
}

おそらく私が読んでいる参考書の記述が意図しているところは
上記のような状況だと思うのですが
この場合、コンパイルは可能だが実行時エラーになる、のでしょうか?

お礼日時:2005/05/14 10:38

Javaにおける、基本型の変数のキャストと参照型の変数のキャストの違いは理解されていますか?



基本型のキャストが文字通り型を変換するのに対して、参照型のキャストはあくまでインスタンスを指し示す参照変数の型を変換するものであり、指し示すインスタンスがキャストされるわけではありません。

そして、インターフェース型の参照変数が指し示すインスタンスは、必ずそのインターフェースを実装したクラスのインスタンスになります。インスタンスが、自身か継承関係にあるスーパークラスの型の参照変数からしか参照できないのと同じように、自身が実装したインターフェースか、そのインターフェースと継承関係にあるスパーインターフェースの型の参照変数からしか参照できません。
インターフェースの場合はクラスの継承と違い、複数実装できますけどね。これらの関係にあるインターフェース型の参照変数なら、どれでも対象のインスタンスを参照できるので、インターフェース型の参照変数のキャストが成り立つわけですね。
1への回答はこんな感じです。

2への回答は、当然ポリモーフィックな処理を意図してだと思いますよ。
個人的にはJavaのインターフェースは多重継承の問題に対する非常にスマートな解決策だと思ってます。
・・・これで3への回答も兼ねてしまいましたね。。
    • good
    • 0
この回答へのお礼

ご解答誠にありがとうございました。
参考書に
インターフェイス→無関係なインターフェイス
への参照変数のキャストが可能とあったので混乱していました。

インターフェイス自体の参照変数というのはありえませんよね。
その文章の意図は
インターフェイスを実装したクラスの参照変数を無関係なインターフェイスにキャストする、
ということだったの、かな、と思いました。

お礼日時:2005/05/14 10:37

質問の趣旨と、ずれているかもしれませんが、


お答えします。
JAVAは、OSに依存しない言語で、オブジェクト指向
かつ、HTML作成には、欠かせない言語です。JAVA
ベースで作られるツール・言語もあります。
JAVAベースのツール・言語の一例:
 Super-Vidual-Formade for JAVA(PDF作成ツール)
 Cold Fusion MX(DBアクセスも可能なHTML言語)
そして、これらのツールで扱うデータは、文字列
数字(実数・整数)等様々です。
したがって、これらのツールから、JAVAへアクセス
する際、型を変換(キャスト)する必要があるの
です。
    • good
    • 0
この回答へのお礼

ご解答誠にありがとうございました。
他の言語からの型変換も可能なのですね。

お礼日時:2005/05/14 10:39

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!