• ベストアンサー

newの基本的な使い方が理解できていません

以下のソースコードで【Super s = new Sub();】となっているのですが、これはSuperを見ているのでしょうか?またはSubでしょうか? この考え方がいまいち理解できません。 次の【System.out.println(s.d);】では、class Superの10を返しているようですが、その次の行でのs.meth(); ではclass Subの20を返しているようです。 また、クラスsuperのint dおよび、boid meth()をstaticにすると、そちらをみているようなのですが、混乱して理解できません。 すみませんが、どのようになっているか教えて頂けませんでしょうか? class Super{ int d = 10; void meth(){ System.out.println(d); } } class Sub extends Super{ double d =20.0; void math (){ System.out.println(d); } } class Test{ public static void main(String args[]){ Super s = new Sub(); System.out.println(s.d); s.meth(); } }

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

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

  • ベストアンサー
  • guccii
  • ベストアンサー率31% (14/44)
回答No.2

仕様は観察されたとおりです。メンバ変数とstaticメソッドのオーバーライドは多態性によりハイドされません。メンバ変数には仮想関数表がありませんから多態性は利用できませんよね。staticメソッドもインスタンスに関連付けられていないので、参照時に動的に判断することがでないので、参照の「型」によりコンパイル時に参照する先が決定されます。逆にいえば、多態性は(saticメソッドを除く)メソッドに適用されるということです。わかりにくく感じるのは、クラス解決演算子を参照と同じ記述にした副作用でしょう。違うものを同じに扱っているかのように見えてしまうので... いずれにしてもこれは多重継承と同じ問題で、言語文法のトリビアです。資格試験のペーパーテストでしか役にはたたないので、細かなところまで正確に理解する必要はありません。 実際のコーディングの場合には、このような問題があることと、それに巻き込まれないようにすることが重要です。 この問題の場合には、名前付定数以外のメンバ変数はすべてprivateにしてアクセッサ(get/set)を介してアクセスすることとし、直接メンバ変数を参照することを禁止することです。また、名前つき定数については、インスタンスではなく、クラス名でスコープ解決すべきです。たとえ正しく動いている(ように見えても)許容してはいけません。コーディングした人or時は正しく理解できても、修正・変更する人or時に正しく理解できないかもしれませんから。

その他の回答 (1)

noname#24040
noname#24040
回答No.1

スーパークラスのメソッドはmeth ではなくmathですよね。 オーバーライドと多様性の問題で、前のスレッドにも同じようなことが書いてると思います。

関連するQ&A

  • 継承について

    以下のような問題(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
  • java

    次のコード中の括弧内で下に示す11通りの各コードを実行した場合の実行画面を正確に答えよ。 class A{ public void func1(){System.out.println("A1");} public void func2(){System.out.println("A2");} } class B extends A{ public void func1(){System.out.println("B");} } class C{ public int x=0, y=1; } class D extends C{ public int x=2; public void func1(int x){System.out.println(x);} public void func2(int x){System.out.println(this.x);} public void func3(int x){System.out.println(super.x);} public void func4(int x){System.out.println(this.y);} public void func5(int x){System.out.println(super.y);} } class E{ public void func1(int n){ try{ System.out.println("E1"); int[] ary=new int[n]; System.out.println("E2"); }catch(NegativeArraySizeException e){ System.out.println("E3"); }finally{ System.out.println("E4"); } } } (1) A a=new A(); a.func1(); (2) A a=new B(); a.func1(); (3) B b=new B(); b.func1(); (4) B b=new B(); b.func2(); (5) D d=new D(); d.func1(3); (6) D d=new D(); d.func2(3); (7) D d=new D(); d.func3(3); (8) D d=new D(); d.func4(3); (9) D d=new D(); d.func5(3); (10) E e=new E(); e.func1(5); (11) E e=new E(); e.func1(-2); (1) A1 (2)B (3)B (4) A2 (5) 3 (6) 2 (7) 0 (8) 1 (9) 1 (10) E1E2E4(11) E1E3E4 と答えになるんですがなぜこうなるのかわかりません。教えてください

    • ベストアンサー
    • Java
  • 継承とオーバーライド

    サブクラスのインスタンスを、スーパークラスの変数に代入するときの考え方が分かりません。下記のプログラムを実行すると x: 10 Sub という結果にります。 spで、message()を呼び出してるのだから、Superクラスのmessage()が処理されるのではないでしょうか? また、コメントアウトすると、コンパイルエラーになる理由もわかりません。 上記の答えのように、Subクラスのmessage()を参照できるのでしたら、printY()も参照できるんじゃないのかって思います。 基本的な質問かもしれませんが、よろしくお願いします。 class Super{ int x = 10; void printX(){ System.out.println("x:" + x); } void message(){ System.out.println("Super"); } } class Sub extends Super{ int y; void printY(){ System.out.println("Y:" +y ); } void message(){ System.out.println("Sub"); } } class ExtensSample01{ public static void main(String[] args){ Super sp = new Sub(); sp.printX(); // sp.printY(); sp. message(); } }

    • ベストアンサー
    • Java
  • 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
  • abstract と static を一緒に付けることはある?

    抽象クラスの抽象メソッドにstaticを付ける(abstract と static をメソッドに一緒に付ける)ことはありますか? 例えば、 abstract class Super {  static abstract void meth(); } class Sub extends Super {  static void meth() {   System.out.print("hello");  } } として、mainの中に  Sub.meth(); を書いてみたのですが、普通にコンパイルは通りhelloが出力されます。 staticの意味を考えると、こういうことをするのは意味がないと思うのですが、独学なので身近に聞ける人もいません。 御教授よろしくお願いします。

  • JAVAコンストラクタについて

    JAVA のコンストラクタ定義の際に、下記のようにコンストラクタにvoidを付けた時と付けない時の処理結果が変わるのはなぜでしょうか。 (1) class O { protected int d; O(){ System.out.println("O = " + d); } } class Study_6_3main_void { public static void main(String args[]) { int i = 1; O OO = new O(); System.out.println("O = "); } } (2) class O { protected int d; void O(){ System.out.println("O = " + d); } } class Study_6_3main_void { public static void main(String args[]) { int i = 1; O OO = new O(); System.out.println("O = "); } } 実行結果 (1) O = 0 O = (2) O = 以上です。回答の程よろしくおねがいします。

    • ベストアンサー
    • Java
  • Java初心者です、エラーの意味が理解できません

    今晩は。Java初心者です、宜しくお願いします。 下のようなコードを書きましたが、 「コンストラクタ'sub(int)'は未定義です」、 「/型subのメソッド'disp(int)'は引数()に適用出来ません」というエラーが出ます。 エラーの意味が理解できません。 1.メソッドのみを持ったクラスSubに値をこのような渡し方は不可なのでしょうか。 2.Subには自動的にコンストラクタが生成されないのでしょうか。   されないとすれば、どの部分の書き方が悪いのでしょうか。 3.「型subのメソッド'disp(int)'への引数の渡し方」は、文法的にまずいということでしょうか。 それとも全てコンストラクタの生成が原因なのでしょうか。 ========================================================================= class Sub { void disp(int a) { System.out.println("a = " + a ); } } public class クラス { public static void main(String[] args) { Sub s = new Sub(10); //コンストラクタ'sub(int)'は未定義です s.disp();     //型subのメソッド'disp(int)'は引数()に適用出来ません  } }

    • ベストアンサー
    • 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
  • 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
  • java iを1づつ増やすプログラムと2づつ増やすプログラム

    次のようにすればiを1づつ増やして表示されます。 class Calc{   int i=1;   int add(){     return i++;   } } class Count{   public static void main(String[] args){     Calc calc = new Calc();     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());   } } 実行結果 i = 1 i = 2 i = 3 しかし次のように2づつ増やそうとすると、 class Calc{   int i=1;   int add(){     return i+2;   } } class Count{   public static void main(String[] args){     Calc calc = new Calc();     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());     System.out.println("i = " + calc.add());   } } 実行結果 i = 3 i = 3 i = 3 このようになってしまいます。どこがおかしいのでしょうか?

    • ベストアンサー
    • Java

専門家に質問してみよう