ちくのう症(蓄膿症)は「菌」が原因!?

JAVA勉強中のものです。
データ型で質問があります。
class Animal{
public void run(int speed){
System.ou.println("My animal is running");
}
}
class Dog extends Animal{
public void run(long speed){
System.out.println("My dog is running");
}
}
class Test{
Public Static void main(String args[]){
Animal myAnimal = new Dog();   -----*
myAnimal.run(5);
}
}
出力結果は My animal is running になりますが、わかりません。
*行は実際のオブジェクトはDog型で,次のmyAnimal.run(5)は
インスタンスメソッドなので、オブジェクトのDogを見に行くと
思うのですが、違うのですか?
本に書いてあったので解説お願いします。

このQ&Aに関連する最新のQ&A

A 回答 (7件)

日本語が下手で申し訳ないです。


まず、ご質問者さんの本当の意味での質問
「myAnimal.run(5)はインスタンスメソッドなので、
 オブジェクトのDogを見に行くと思うのですが、違うのですか?」
は、正しいです。
インスタンスとしてのDogオブジェクトを見に行っています。

ところで、今回の場合、Animalクラスに代入されています。
そのため、DogオブジェクトインスタンスをAnimalオブジェクトとしてメソッドを実行します。

>変数の型で見に行くのですか?
>(見当違いな質問ならすいません)
これは、「オーバーライド」と「オーバーロード」の話になります。

まず、「インスタンスとしてはDogしかない」というのはOKですよね?
ここで、DogオブジェクトはAnimalオブジェクトを継承していますので、
DogオブジェクトはAnimalオブジェクトとしての機能は全て持っています。
Dogオブジェクト内では、runメソッドが再定義されていて、
引数がlongとintと違うため、「オーバーロード」が発生していますので、
2つのrun()メソッドを持っていることになります。

今回の場合、DogオブジェクトをAnimalオブジェクトとして見ているので、Dogオブジェクト内のAnimalオブジェクト部分しか見えません。
Animalオブジェクトに引数long型のメソッドが無い以上、呼び出すことはできません。

もし、ここで Animalオブジェクトも引数の型がlongだったとすると
今度は「オーバーライド」が成立します。
この場合、『Dogオブジェクトのインスタンスで同じメソッドが上書きされている』
状態になるので、AnimalオブジェクトとしてDogオブジェクトを見ても
「myAnimal.run(5);」の結果は『"My Dog is running."』になるのです。
    • good
    • 0
この回答へのお礼

補足回答ありがとうございます。
わかりやい説明で初心者な私でも理解できました。

お礼日時:2007/07/06 18:09

ANo.3です。


追追伸:(一度に書けよ>自分、ごめんなさい>みなさま)

Animal myAnimal = new Dog();   -----*
こっちをそのままにしたいのならば、クラスキャストをしなくてはいけません。
Animal myAnimal = new Dog();
((Dog)myAnimal).run((long)5);
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
>子オブジェクトを親オブジェクトへ代入した瞬間に親オブジェクトとして>の振る舞いをするようになります。
インスタンスメソッドの場合、変数の型ではなくオブジェクトの型
でクラスを見にいくと思っていたのですが、変数の型で見に行くのですか?
(見当違いな質問ならすいません)

お礼日時:2007/07/06 17:16

#1です。



代入先の型がスーパークラスなので、
#3さんのおっしゃる通り、longを引数にすると
コンパイルエラーになりますね。
失礼しました。

Animal myAnimal = new Dog();

Dog myAnimal = new Dog()
ならrun((long)5);が通りますね。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
>longを引数にするとコンパイルエラーになりますね。
Animalクラスにないメソッドだからコンパイルエラーになるのでしょうか?
そもそも
Animal myAnimal = new Dog();
が良くわかっていないようです。
インスタンスメソッド、インスタンス変数で見にいくクラスが違うのですよね(それがわかっていないようです(泣))

お礼日時:2007/07/06 17:20

ANo.3です。


追伸:
Animal myAnimal = new Dog();   -----*
この行が
Dog myAnimal = new Dog();   -----*
ならANo.1さんが正解です。
(long)でキャストすると "My dog is running."になりますし、
(long)でキャストしないと"My animal is running."になります。
    • good
    • 0

>出力結果は My animal is running になりますが、わかりません。


>*行は実際のオブジェクトはDog型で,次のmyAnimal.run(5)は
>インスタンスメソッドなので、オブジェクトのDogを見に行くと
>思うのですが、違うのですか?
いいえ。違います。
子オブジェクトを親オブジェクトへ代入した瞬間に親オブジェクトとしての振る舞いをするようになります。
myAnimal自体はAnimalのインスタンスとして振舞いますので、
[my animal is running.]
となります。
ANo.1さんはオーバーライドの話をされていますが、(long)でキャストすると、今回の場合は
「メソッド run は引数 long に適用できない」(正しいメッセージ忘れた。まぁ、試せばいいんだけなんだけども(笑))
というコンパイルエラーになるはずです。
    • good
    • 0

オーバーロード


http://www.nextindex.net/java/overload.html

Animalクラスから派生したのがDogクラスですね
なのでAnimalで宣言した関数はprotected/publicであれば
子であるDogクラスでも使えます。

だからあなたの考え通りでいいと思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございます
URL見に行きます

お礼日時:2007/07/06 17:17

Animalクラスのrunメソッドの引数はint型。


Dog クラスのはlong型。

そのため、オーバーライド(上書き)されず別なメソッドとして解釈されているためです。

呼び出すときに、

myAnimal.run((long)5);

とすれば「My dog is running」が表示されるはずです。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
また質問です。
>オーバーライド(上書き)されず別なメソッドとして解釈されているため
Dog クラスに妥当なメソッドが無くて継承関係にあるからAnimalクラス
を探しにいったのですか?

お礼日時:2007/07/06 15:27

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


人気Q&Aランキング