• ベストアンサー

データ型で質問です。

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を見に行くと 思うのですが、違うのですか? 本に書いてあったので解説お願いします。

  • Java
  • 回答数7
  • ありがとう数7

質問者が選んだベストアンサー

  • ベストアンサー
  • PED02744
  • ベストアンサー率40% (157/390)
回答No.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."』になるのです。

tomojyuu
質問者

お礼

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

その他の回答 (6)

  • PED02744
  • ベストアンサー率40% (157/390)
回答No.6

ANo.3です。 追追伸:(一度に書けよ>自分、ごめんなさい>みなさま) Animal myAnimal = new Dog();   -----* こっちをそのままにしたいのならば、クラスキャストをしなくてはいけません。 Animal myAnimal = new Dog(); ((Dog)myAnimal).run((long)5);

tomojyuu
質問者

お礼

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

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.5

#1です。 代入先の型がスーパークラスなので、 #3さんのおっしゃる通り、longを引数にすると コンパイルエラーになりますね。 失礼しました。 Animal myAnimal = new Dog(); が Dog myAnimal = new Dog() ならrun((long)5);が通りますね。

tomojyuu
質問者

お礼

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

  • PED02744
  • ベストアンサー率40% (157/390)
回答No.4

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

  • PED02744
  • ベストアンサー率40% (157/390)
回答No.3

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

  • phoenix343
  • ベストアンサー率15% (296/1946)
回答No.2

オーバーロード http://www.nextindex.net/java/overload.html Animalクラスから派生したのがDogクラスですね なのでAnimalで宣言した関数はprotected/publicであれば 子であるDogクラスでも使えます。 だからあなたの考え通りでいいと思います。

tomojyuu
質問者

お礼

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

  • ngsvx
  • ベストアンサー率49% (157/315)
回答No.1

Animalクラスのrunメソッドの引数はint型。 Dog クラスのはlong型。 そのため、オーバーライド(上書き)されず別なメソッドとして解釈されているためです。 呼び出すときに、 myAnimal.run((long)5); とすれば「My dog is running」が表示されるはずです。

tomojyuu
質問者

お礼

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

関連するQ&A

  • Java初心者です

    次のようなプログラムを作りました interface Vehicle{ void drive(); } abstract class Animal{ abstract void show(); } class Lion extends Animal{ public void show(){ System.out.println("ライオンです"); } } class Horse extends Animal implements Vehicle{ public void show(){ System.out.println("馬です"); } public void drive(){ System.out.println("乗り物として使えます"); } } class Elephant extends Animal implements Vehicle{ public void show(){ System.out.println("象です"); } public void drive(){ System.out.println("乗り物として使えます"); } } class Bear extends Animal{ public void show(){ System.out.println("熊です"); } } class twentyeight{ public static void main(String args[]){ Animal an[]; an = new Animal[4]; an[0] = new Lion(); an[1] = new Horse(); an[2] = new Elephant(); an[3] = new Bear(); for(int i = 0;i < an.length;i++){ if(an[i] instanceof Vehicle){ an[i].drive();//ここにエラーが出る } else{ an[i].show(); } } } } インターフェイスを実装しているオブジェクトを判別し、そのdriveメソッドの呼び出しをしたいのですができません、どなたか教えてください。

    • ベストアンサー
    • Java
  • Javaの多態性について質問です

    Java初心者です。どなたかお力をお貸しください。 ------------------- class Animal { public void eat() { // 汎用的なコード } } class Dog extends Animal { public void eat() { // 特化したコード } public void bite() { // Dog特有のコード } } ------------------- 上記のクラスについて質問があります。 Animal obj = new Dog(); obj.bite(); このコードがコンパイルエラーになるのは何故でしょうか? コンパイラが参照型のみをチェックし、Animalクラスにbiteメソッドが 無いため、エラーを出すと参考書に書いてありました。 つまり、スーパークラス型の参照変数にサブクラスのインスタンスを格納し、 サブクラス特有のメソッドをコールできないとはどういう意図なんでしょうか? コンパイラのチェックで引っかかるのは分かったのですが、 オブジェクト指向としては、この使い方は推奨されないということでしょうか? (Animalの参照で、Dog特有のメソッドは使わない?) 実際にJavaでプログラムを組むときには、こんな使い方をしないのですか? 有知識者の方、教えて下さい。 私は、オブジェクト指向の多態性の理解が甘いため、こんな質問をしているのだと 思います。申し訳ございません。

    • ベストアンサー
    • Java
  • 継承について質問させていただきます

    Java初心者です。 privateなフィールドは継承されない と書籍にありましたが、理解に苦しんでおります。 具体例で申しますと、下記コードの cat.setCount(3); です。 CatクラスにはAnimalクラスの変数countは継承されないと考え、 エラーとなることを想像していたのですが。。。 なぜエラーとならないのでしょうか? 宜しければ、解りやすくご説明していただければ幸いです。 どうかよろしくお願いいたします。 ---------------------------------------------- class Animal{ private int count; int getCount(){ return count; } void setCount(int c){ this.count = c; } } class Cat extends Animal{ } public class test{ public static void main(String[] args){ Cat cat = new Cat(); cat.setCount(3); // ここが理解できません System.out.println(cat.getCount()); // ここも同様 } } ----------------------------------------------

    • ベストアンサー
    • Java
  • 初歩的な質問ですみません。

    はじめまして。Javaの初心者です。 初歩的なことで、どうしてもわからないことがあります。 以下のような場合、 *************************************** class Oya { void func() { System.out.println("Oya"); } } class Ko extends Oya { Ko() { this.func(); } } class Main { public static void main(String[] args) { new Ko(); } } *************************************** Koクラスが初期化を完了していないのにもかかわらず func()メソッドを呼びさせてしまう理由がわかりません。なぜなのでしょうか?どうか教えてください。

    • ベストアンサー
    • Java
  • 継承について

    以下のような問題(SJC-P試験)があり、 解説では考え方として ●メンバがフィールドなら「変数の型」 ●インスタンスメソッドなら「実際のオブジェクトの型」 ●クラスメソッドなら「変数の型」 とありました。 できればなぜこのような考え方(法則)になるか理解したいと思っています。 #当方、Javaプログラミング経験ゼロで、実際に下記のようなコーディングをするかどうかもわかりませんが、 #丸暗記だと実際のコーディングで使えそうにないので、できれば理解したいと思ってます。 下記問題は解説の考え方さえ丸暗記すれば解けるのかもしれませんが (なぜ解説のような考え方になるのか含め)教えていただけませんでしょうか。 ----- 【問題1】 class Super{  int d = 10;  void meth()System.out.println(d); } class Sub extends Super{  double d = 20.0;  void meth()System.out.println(d); } class Sample1{  public static void main(String[] args){  Super s = new Sub();  System.out.println(s.d);  s.meth(); } 【答え】 10 20.0 ----- 【問題2】 class Super{  static int d = 10;  static void meth()System.out.println(d); } class Sub extends Super{  static double d = 20.0;  static void meth()System.out.println(d); } class Sample2{  public static void main(String[] args){  Super s = new Sub();  System.out.println(s.d);  s.meth(); } 【答え】 10 10 ----- よろしくお願い致します。

    • ベストアンサー
    • Java
  • エラーが出ます

    public class Test1 { public static void main(String args[]) { My number is 21001100. if(It is able to be divided by 3.){ System.out.println("割り切れます"); } else{ System.out.println("割り切れません"); } } } エラーが一個で、5行目に;がないようなので.のあとに;をつけるとエラーが増えてしまいます。エラーのなくし方を教えてください。(なんか全部文頭につまってるかもしれませんがテキストドキュメントでは文頭をあけてます)

    • ベストアンサー
    • Java
  • 親クラスの型で子のオブジェクトを扱う

    ●下記のコードについての質問となります class Y { int num2 = 20; } class Z extends Y { int num3 = 30; } class Sample{ public static void main(String args[]){ --------------------------------------------- Y y1 = new Z(); --------------------------------------------- System.out.println(y1.num2); System.out.println(y1.num3); } } 「-----」で囲まれている部分になりますが、 親クラスの型で子のオブジェクトを扱おうと思うのですが、 「System.out.println(y1.num3);」 この部分において、コンパイルエラーとなります。 Zクラスから生成されたオブジェクトへの参照を Y型変数y1に代入していると思うのですが、 何故、「y1.num3」の値が表示されないのかを ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ お伺いしたいと思っております。 以上、宜しくお願い致します。

    • ベストアンサー
    • Java
  • Cで多様性を表現するには

    こんにちは、あっちこっちとウェブを検索しましたが これと言った答えが見つからないので書かせていただ きます。 C言語で多様性を表現するにはどのようにすればいいで しょうか?関数ポインタを使用すると出来そうだと言 うとこまでは理解したのですが・・・ 以下にJavaで書いたものをCでどうやって表現したら 良いかご教授ください。また、参考になるポインタな どもあれば宜しくお願いします。 public interface MoverIF{  public void run(); } public class Car implements MoverIF{  public Car(){}  public void run(){   System.out.println("Car run");  } } public class Dog implements MoverIF{  public Dog(){}  public void run(){   System.out.println("Dog run");  }  public static void main(String arg){   MoverIF mi[] = new MoverIF[2];   mi[0] = new Dog();   mi[1] = new Car(); for(int i=0;i<2;i++){ mi[i].run();  } }

  • javaの質問です。

    明日JavaのBronze試験を受けに行くのですが、全然わからずに困っています。 紫色のJavaプログラマBronzr[SE7]という本を使用しています。 本の模試の問題です。 37 Class Super{ static void method(){ System.out.println("Super"); } } Class Sub extends Super{ static void method(){ System.out.println("Sub"); } } Class Test { public static void main(String[] args){ Super obj = new Sub(); obj.method(); } } この問題はSuperが表示されるらしいのですが、理由がわかりません。 サブクラスをインスタンス化しているので、Subが表示されるというのなら理解できます。staticが関係あるのはなんとなくわかるのですが、、、、、、なぜSuperなのかがわかりません。 解答ではスーパークラスの型にサブクラスを入れているからと簡単に書いてあります。 詳しく説明していただけると助かります。

    • ベストアンサー
    • Java
  • メソッドのオーバーライド(java)

    class A3{ void hello(){ System.out.println("A3"); } void hello(int i){ System.out.println("A3"+i); } } class B3 extends A3{ void hello(){ System.out.println("B3"); } } class C3 extends B3{ void hello(String s){ System.out.println("C3"+s); } } class MethodOverriding3{ public static void main(String args[]){ A3 obj = new C3(); obj.hello(); } } 上のプログラムを実行すると"B3"と表示されまが、どうしてクラスBのメソッドが実行されるのでしょうか? クラスAのメソッドが無視される仕組みがわかりません。 また、クラスMethodOverriding3でobj.hello("abc")としてコンパイルすると mo.java:25: シンボルを見つけられません。 シンボル: メソッド hello(java.lang.String) 場所 : A3 の クラス obj.hello("abc");   ^ エラー 1 個 とエラーが出ます。 どうしてでしょうか? 誰か教えてください、お願いします。

    • ベストアンサー
    • Java