親クラスと子クラスのフィールドとメソッドについて

このQ&Aのポイント
  • 親クラスと子クラスのフィールドとメソッドについての解説です。
  • 親クラスと子クラスのフィールドとメソッドが異なる動作をする原理について説明します。
  • 実行結果の違いを通じて、フィールドとメソッドの動作原理を明確にします。
回答を見る
  • ベストアンサー

親クラスと子クラスのフィールドとメソッドについて

親クラスと子クラスのフィールドとメソッドについて 以下のサンプルソースを実行した時の動作の原理について 教えてください。 oya型変数にkoクラスのインスタンスを作成した場合、 メソッドはkoクラスのものなのに、 フィールドはoyaクラスのものになるということが イマイチすっきり理解できません。 どういうことなんでしょうか。 ------------------------------------------------------- [ソース] public class exec { public static void main( String args[]){ oya obj = new ko(); System.out.println(obj.str_field); obj.disp_field(); } } public class oya{ String str_field="親実行"; public void disp_field(){ System.out.println(str_field); } } public class ko extends oya { String str_field = "子実行"; public void disp_field(){ System.out.println(str_field); } } ------------------------------------------------------- [実行結果] > 親実行 > 子実行 -------------------------------------------------------

  • Java
  • 回答数2
  • ありがとう数1

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

  • ベストアンサー
  • tekebon
  • ベストアンサー率62% (36/58)
回答No.2

Javaの仕様ではフィールドにアクセスする場合には変数の型に依存します。 質問文ではoyaクラスの変数objからobj.str_fieldとなっていますので、 oyaクラスのフィールドの値である"親実行"が表示されます。 koクラスの変数objでobj.str_fieldとすれば koクラスのフィールドの値である"子実行"が表示されます。 言語仕様のサイトのフィールドとメソッドの名前解決に関するリンクを紹介しておきます。 http://www.y-adagio.com/public/standards/tr_javalang/6.doc.htm#22133 http://www.y-adagio.com/public/standards/tr_javalang/15.doc.htm#20448

その他の回答 (1)

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

一言で答えるなら、「メソッドはオーバーライドできるが、フィールドはオーバーライドできないから」です。 もう少し説明してみます。区別のために、oyaクラスのstr_fieldをF1、koクラスのstr_fieldをF2と呼ぶことにします。 oyaクラスのオブジェクトは当然F1しか持っていませんが、実はkoクラスのオブジェクトはF1とF2の両方を持っています。 さらに、フィールドのアクセスは内部的にはフィールドの名前ではなくて「このオブジェクトのn番目のフィールド」という形で行われます。 execクラスとoyaクラスでのstr_fieldへのアクセスは1番目のフィールド(F1)へのアクセス、koクラス内でのstr_fieldへのアクセスは2番目のフィールド(F2)へのアクセスとして理解されます。 したがって、execクラス内でobjが指しているのがkoクラスのオブジェクトであっても、koのF1へアクセスするので「親実行」の文字列が得られます。

b_hunter
質問者

補足

解答ありがとうございます。 > メソッドはオーバーライドできるが、 > フィールドはオーバーライドできないから ソースを書き換え、ko型変数にkoクラスのインスタンスを 作成するように変更した場合は、str_fieldへのアクセスが koクラスのものになることに説明がつかないように感じます。 恐縮ですが、こちらについてもご回答いただけないでしょうか。

関連するQ&A

  • Javaについて教えてください!

    OyaクラスのメインメソッドからKoクラス内のメソッドを呼び出して文字列の出力を行いたいのですが、今のままではエラーが出てコンパイル出来ません。どこが間違っているか教えてください!ちなみにエクリプスでの実行には問題はありません。 public class Ko{ public static void ko(){ String str = "KO"; System.out.println(str); }} public class Oya{ public static void main(String[] args){ Ko.ko(); }}

    • ベストアンサー
    • 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
  • 初歩的な質問ですみません。

    はじめまして。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
  • 親クラスから子クラスへアクセス。

    親クラスから子クラスへアクセス。 お世話になります。 以下のプログラムについて考えています。 public class Main{  public static void main(String[] args) {   SubA subA = new SubA();   SubB subB = new SubB();   Super[] subs = {subA,subB};   subs[1].method();   subs[2].method();  } } class Super{  String str = "親";  public void method(){   System.out.println(str);  } } class SubA extends Super{  String str = "子A"; } class SubB extends Super{  String str = "子B"; } この場合、出力結果は当然 親 親 になります。 これを子クラスの str を表示するようにしたいのです。つまり 子A 子B です。 ただし、子クラスで method() をオーバーライドしたり、super.str = "子A" のように親クラスを書きかえずにです。 子クラスが何百種類もある場合、全く同じmethod()を書く無駄や、変更があったときにそれを全てを修正しなければならないことを避けたいのです。 何か良案がありましたら、ぜひご教授ください。よろしくお願いします。

  • mainクラス内に書いたメソッドの宣言の仕方(staticの必要性)

    java を勉強中の超初心者です、宜しくお願いします。 main と同じクラスに disp というメソッドを作成してやり、” void disp(int a , int b )”と書いてやりましたが、mainからアクセス出来ません。 そこで、” static void disp(int a , int b )” という風に” static ” を先頭につけてやりましたら、うまく動きました。 これは、mainメソッドから他のメソッドにアクセスする場合には、必ず” static ” をつけてやる必要があるということでしょうか。 ======================================================= class クラス練習 { public static void main(String[] args) { disp(5,10); } /*static*/ void disp(int a , int b ) { System.out.println("a+b = " + (a+b)); } }

    • ベストアンサー
    • Java
  • クラス変数/メソッドとインスタンス変数/メソッドの見え方について

    Javaの言語仕様(?)についてお教え下さい。 参照変数の型がインスタンスのスーパークラスの型の時、クラス変数/メソッドとインスタンス変数/メソッドの見え方が納得いかずに困っています。 以下のような条件の時です。   ・クラスが2つあり、1つはもう1つのクラスを継承しています。     それぞれを「スーパー」「サブ」と以下で呼びます。   ・インスタンスは"サブ"の型です。   ・上記インスタンスへの参照変数は"スーパー"のクラスの型です。   ・"スーパー"、"サブ"ともに【同名】の「クラス」変数/メソッド、「インスタンス」変数/メソッドがあります。 この場合に、"サブ"のインスタンスを参照している"スーパー"の型の変数を介し、それらにアクセスしたらどれが見えるか?という疑問です。 実験結果では以下のようになりました。           [フィールド]  [メソッド]   [1.static ]  スーパーの   スーパーの   [2.非static]  スーパーの   サブの 納得いかないのは「2.非static」で「フィールド」が、「スーパーの」になるところです。 これも「サブの」になると思っていました。 なぜサブクラスのが見えないのでしょうか? 同名の変数なのでスーパークラスのはサブクラスので隠れされ、サブクラスのが見えると思っていたのですが。 参考書には以下のように書いてありました。   フィールドの場合、参照変数の型のものが見える。   メソッドの場合、インスタンスの型のものが見える。 私には不自然に感じられるのですが、「こういう仕様だから。」と納得するしか無いのでしょうか? 「なぜこうなるか」について説明がある文献、サイトなどありましたらお教えください。 参考までに以下が実験したサンプルコードと結果です。長くて申し訳ありません。 「サンプルコード」 public class Super { static int staticField = 10; int instanceField = 100; static void staticMethod() { System.out.println( "staticField = " + staticField ); } void instanceMethod() { System.out.println( "instanceField = " + instanceField ); } } public class Sub extends Super { static int staticField = 90; int instanceField = 900; static void staticMethod() { System.out.println( "staticField = " + staticField ); } void instanceMethod() { System.out.println( "instanceField = " + instanceField ); } } public class TestStatic { public static void main(String[] args) { // インスタンスはSub、参照変数もSub、という状態。 Sub sub = new Sub(); System.out.println( "実験1" ); System.out.println( "1.クラス変数      " + sub.staticField ); System.out.print( "2.クラスメソッド    " ); sub.staticMethod(); System.out.println( "3.インスタンス変数   " + sub.instanceField ); System.out.print( "4.インスタンスメソッド " ); sub.instanceMethod(); // インスタンスはSub、参照変数はSuper、という状態。 Super sup = new Sub(); System.out.println( "実験2" ); System.out.println( "5.クラス変数      " + sup.staticField ); System.out.print( "6.クラスメソッド    " ); sup.staticMethod(); System.out.println( "7.インスタンス変数   " + sup.instanceField ); System.out.print( "8.インスタンスメソッド " ); sup.instanceMethod(); } } 「結果」 実験1 1.クラス変数      90 2.クラスメソッド    staticField = 90 3.インスタンス変数   900 4.インスタンスメソッド instanceField = 900 実験2 5.クラス変数      10 6.クラスメソッド    staticField = 10 7.インスタンス変数   100 8.インスタンスメソッド instanceField = 900 納得が行かないのは7のところです。 以上よろしくお願いいたします。

    • ベストアンサー
    • Java
  • メインメソッドの記述について

    メインメソッドを記述する際に、   public static void main(String[] args){     ~~~~~~~~~~~~~   } と書くと思いますが、なぜpublicを付けなければならないのでしょうか? 簡単に考えるために、1つのクラスのみで実行してみたのですがやはりpublicをつけないとエラーになってしまします。 1つのクラスしかないので、どこからも参照されないからpublicでなくても良いと思ったのですが・・・ ちなみに以下の様なとても簡単なもので考えました。 class E_1{ static void main(String[] args){ System.out.println("実験です"); } }

  • クラスの拡張について

    Teacher クラスを変更し、newTeacher()の時は、名前「TARO」、年齢「25」、科目「国語」で初期化し、newTeacher(名前、年齢、科目)のときはそれぞれのパラメータでオブジェクトを作るようにしたい。 Person クラスのコンストラクタが使ってもかまわない という問題で //ClassRoom3.java class Person{ String name; int age; Person(String name,int age){ this.name = name; this.age = age; } void print(){ System.out.println("[Name]"+name); System.out.println("[age]"+age); } } class Teacher extends Person{ String subject; void print(){ System.out.println("私は"+name+" といいます。"); System.out.println("年齢は"+age+" 才です。"); System.out.println(subject+" を教えています。"); } } class ClassRoom3{ public static void main(String args[]){ Teacher obj1 = new Teacher(); Teacher obj2 = new Teacher("JIRO",27,"算数"); obj1.print(); System.out.println(); obj2.print(); } } /* 実行例 >java ClassRoom3 私は TARO といいます。 年齢は 25 才です。 国語 を教えています。 私は JIRO といいます。 年齢は 27 才です。 算数 を教えています。 */ という出力結果をだしたいのですが、なんどもやっても失敗してしまい。なかなかできません。 どう直したらよいのですか?

  • mainクラスのpublicの意味を教えて下さい

     お早う御座います、JAVA初心者です、宜しくお願いします。  main クラスの public をコメントアウトしてもエラーもなく走ります。  これは、「public static void main(String[] args)」を持っているクラスを自動的に「main クラス」と判断しているということでしょうか。 ============================================================ class Sub { void disp() { System.out.println(" a "); } } /*public*/ class Main { public static void main(String[] args) { Sub s = new Sub(); s.disp(); } }

    • ベストアンサー
    • Java
  • クラスのフィールドの比較方法

    2つのクラスのフィールドを比較して、その結果を以下のように表示させたいのですが、どのようにプログラミングをすればいいのでしょうか? 例 class Car { String carname; int height; int width; int length; } class Garage { String garagename; int height; int width; int depth; } public class example { public static void main (String[] args) throws IOException { Car car[]; car = new Car[5]; System.out.println("車の情報を入力してください。"); BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in); for(int i=0; i<5; i++){ car[i] = new Car(); System.out.println(i+1 + "台目の車の名前を入力してください。"); String str1 = br1.readLine(); System.out.println("車の高さを入力してください。"); String str2 = br1.readLine(); System.out.println("車の幅を入力してください。"); String str3 = br1.readLine(); System.out.println("車の長さを入力してください。"); String str4 = br1.readLine(); int h1 = Integer.parseInt(str2); int w1 = Integer.parseInt(str3); int l1 = Integer.parseInt(str4); car[i].carname = str1; car[i].height = h1; car[i].weith =w1; car[i].length =l1; } for(int i=0; i<5; i++){ garage[i] = new Garage(); System.out.println(i+1 + "つ目の車庫の名前を入力してください。"); String str5 = br2.readLine(); System.out.println("車庫の高さを入力してください。"); String str6 = br2.readLine(); System.out.println("車庫の幅を入力してください。"); String str7 = br2.readLine(); System.out.println("車庫の長さを入力してください。"); String str8 = br2.readLine(); int h2 = Integer.parseInt(str6); int w2 = Integer.parseInt(str7); int d2 = Integer.parseInt(str8); garage[i].garagename = str2; garage[i].height = h2; garage[i].weith =w2; garage[i].depth =d2; } } 出力例 garage1 car3 garage2 car5 garage3 car4 garage4 car2 garage5 car1 よろしくお願いします。

    • ベストアンサー
    • Java

専門家に質問してみよう