• 締切済み

スーパークラスのコンストラクタの処理を引き継ぐ

基本情報18年秋のJava問題問12の設問1(a)の問でわからないことがあるので教えてください。 スーパークラスを継承したクラスのコンストラクタ内の処理を、スーパークラスのコンストラクタと同じ処理する場合の記述についてです。 問題と解答(http://www.jitec.jp/1_04hanni_sukiru/mondai_kaitou.html#18aki)はここですが、簡単に書くと、次のようになります。 抽象クラスBook abstract class Book { String name; String id; Book(String name, String id) { this.name = name; this.id = id; } ~ } Bookを継承したRegularBook class RegularBook extends Book { RegularBook(String name, String id) { ここが穴埋め ; } ~ } 穴埋めの解答群5つのうちの2つが次のとおりです。 エ super(name, id) オ this.name = name; this.id = id もちろんエが正解です。 普通ここにエの記述をするのはわかるのですが、なぜ「オ」が「絶対に間違い」と言い切れるのかが分からないのです。 スーパークラスのコンストラクタ内の処理が変更になった場合、それを継承するクラスのコンストラクタの処理にも反映されるとか、そういう意味でもエの書き方は便利だとは思いますが、オも絶対に間違いといいきれないのでは?? お尋ねしたいのは、情報処理試験の問題として、絶対に間違いでない選択肢を2つ以上もいれるはずもないので、オは「なにがなんでも間違い」なんだろうけれどもその理由が分からないのです。 オが確実に間違っているという理由が分かりましたら教えてください。よろしくおねがいいたします。

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

みんなの回答

  • neko_noko
  • ベストアンサー率45% (146/319)
回答No.2

オは間違いです。 本来、サブクラスのコンストラクタは、その処理の最初でスーパークラスのコンストラクタを呼び出します。 スーパークラスのコンストラクタが複数ある場合、「どのスーパークラスのコンストラクタを呼ぶか」、 つまりどの引数のコンストラクタを呼ぶのか指定しないといけません。 ただ、一つだけスーパークラスのコンストラクタを省略できる場合があります。 それが、スーパークラスの引数なしのコンストラクタ、つまり「super();」を呼ぶ場合です。 このコンストラクタを呼び出す場合に限り、スーパークラスのコンストラクタの呼び出しを省略できるのです。 (サブクラスのコンストラクタと同じ引数のコンストラクタではない、というのが重要です。 冷静に考えれば当然のことですが。) 言い換えると、引数のないコンストラクタ「以外」を呼ぶ場合は、明示的に記述しないといけません。 というのがJavaの言語仕様です。 これでお分かりでしょう。 RegularBookクラスのスーパークラスBookクラスにはBook()というコンストラクタがありません。 Book(String, String)というコンストラクタしかありません。 なので、RegularBook クラスのコンストラクタは、super(String, String)を必ず定義しないといけないのです。

noname#219128
noname#219128
回答No.1

ま、実際に手を動かすのが早いと言う事で、 提示していただいたサンプルでコンパイルすると「暗黙的スーパー・コンストラクター Book() は未定義です。別のコンストラクターを明示的に呼び出す必要があります。」というエラーがでてきました。 ま、そのまんまということで。

関連するQ&A

  • コンストラクタの super() で処理が止まります。

    いつもお世話になってます。 eclipse & Visual Editor にて開発しております。 JFrame を継承したクラスを作成したのですが コンストラクタにて super() を呼び出したときに 処理が止まる?ようになってしまいます。 NoSuchMethodException(Throwable).<init>(String)行: 195 上記、タブが追加されて、 ----- ソースが見つかりませんでした。 ソース・ルックアップ・パスの編集 ← ボタン ----- が表示されている状態です。 解決策が分かりません。 どの辺りから調べれば良いのでしょうか?

    • ベストアンサー
    • Java
  • スーパークラスのコンストラクタの呼び出し

    こんにちは。 スーパークラスに引数のあるコンストラクタと引数のないコンストラクタをサブクラスで継承する際の質問です。 具体的に書くと下記になります。 class A { A () {} A (int i) {} } class B extends A { } 何がわからないかというと 『スーパークラスのA()は、サブクラスのBでわざわざ明示的にスーパークラスのコンストラクタ呼び出しをしなくても問題ないというのはわかるのですが、なぜスーパークラスのA(int)は、呼び出さなくても良いのかということです。』 もしかしたら基礎中の基礎かもしれませんが、ご教授よろしくお願いいたします。

    • ベストアンサー
    • Java
  • 親クラスのコンストラクタは? 引数付きコンストラクタは?

    VisualBasic.NETです。 あるクラスを継承したクラスからインスタンスを作成したときに、派生クラスのコンストラクタは呼び出されると思うのですが、基本クラスのコンストラクタはどうなるのでしょうか? JAVAのように、super() で呼び出す必要があるのでしょうか? 自動で呼び出されるのでしょうか? それとも、そもそも呼び出せないのでしょうか? また、引数の個数が違うコンストラクタは、同じクラス内に設定できるのでしょうか? JAVAのコードを移植しようと考えているのですが、出来るのかどうかが分からずに悩んでいます。 ご存じの方、よろしくお願いします。

  • Javaコンストラクタthisとsuperについて

    javaのthisとsuperの理解の為に下記のようなクラスで実験してみているのですが、 少し解らない箇所が出てきました。 コメントアウト行(1)に書いたようにsuper()を書くとエラーが発生してしまいます。 確かsuper()はコンパイラが自動的にコンストラクタが実行された時1行目に挿入している。 と覚えていたので明示的にしようとしたのですが、どうやら認識違いのようでして、だとしたら Q1:super()はいつ呼ばれているのでしょうか? また、ConstThisTestは暗黙的にObjectクラスを継承しているはずなので Q2:Objectクラスのコンストラクタが呼ばれているはずですが、 いつ呼ばれているかをログなどで確認する方法はありますでしょうか? 因みに開発環境はeclipseを使用しております。 尚javaのバージョンやeclipseのバージョン等は 今回は関係ないかなと思うので記載しておりません。 以上 何卒宜しくお願い致します。 --------------------------------------------------------- public class ConstThisTest { int constValue = 0 ; public ConstThisTest(int constValue) { this.constValue = constValue; } public ConstThisTest() {        /* (1)super()を書くとthis()は1行目にかかないと          コンストラクタ内の最初のステートメントであることが必要とエラーが出る。 */ this(-1); } public void printValue(){ System.out.println("constValue = " + constValue); } } public class ConstThisTestMain { public static void main(String[] args) { ConstThisTest ct = new ConstThisTest(); ct.printValue(); } }

    • ベストアンサー
    • Java
  • コンストラクタとその類似の形について 初心者です。

    コンストラクタについて勉強したばかりのところ、似たような記述に出会い違いが全くわかりません。 プログラム1 class Book { int price; int num = 0; String title; Book(String t, int p) { ...☆ title = t; price = p; } ・      ・       ・ プログラム2 class Cat { String name; String place; int age; void setData(String n, String p, int a) {...★ name = n; place = p; age = a; }      ・      ・      ・ ☆と★の違いがわかりません。どちらも値(変数)を代入してるという点では同じですよね。なぜ★はvoidがつくのに☆はつかないのでしょうか? 本によると☆のほうはコンストラクタで、★はコンストラクタではなくメソッドらしいのですが・・・。使い分けはどういうときするのでしょうか?  よろしくお願いします。

    • ベストアンサー
    • Java
  • 継承における暗黙のデフォルトコンストラクター

    ”継承の際、スーパークラスで引数なしのコンストラクターが省略せずにきちんと記述されるなら、そのサブクラスでコンストラクターを記述しなくても、スーパークラスの引数なしのコンストラクターが受け継がれるためコンパイルエラーがおきない。”のは分かりますが”スーパークラスで引数なしのコンストラクターが省略され、かつサブクラスでコンストラクターを省略した場合”はなぜコンパイルエラーがおきるのでしょうか? 暗黙の内にスーパークラスにコンストラクターが生成され、それがサブクラスに受け継がれることは出来ないのでしょうか? 宜しく願います。

  • C#でプロパティを使わずXMLにデータを保存したい

    C#を使っているのでC・C++のジャンルでいいのか分からないのですがこちらで質問させて下さい。 現在簡単な本の管理をするアプリを作っています。 プロパティをできるだけ使わずにカプセル化して作っていたのですが、肝心のデータを保存する段階で分からなくなりました。 public class Book { private static int _id_gen; private int _id2; private string _isbn; private string _name; public Book(string isbn, string name) { this._isbn = isbn; this._name = name; } } このようにコンストラクタでデータを渡して get プロパティだけあとで追加するようにしています。 こういうデータを保存する際はまとめて保存するのではなくて List<Book> なんかを foreach で回して1件ずつ保存するといいのでしょうか? 読み込む際は1件ずつ読み込んでクラスに設定していくというのが標準的な考え方ですか? 「C# XML 保存」で検索をかけると XmlSerializer でまとめて保存する事例ばかりでちょっと分からなくなってしまいました。 よろしくお願いします。

  • コンストラクタの動作について

    下記のソースについて質問があります。 public class Test{ private String msg; public Test(){ this("Good morning"); } public Test(String msg){ msg = msg; } public String toString(){ /*(2)*/ return ("msg:" + msg); } public static void main(String args[]){ System.out.println(new Test()); /*(1)*/ } } このコードをコンパイルした出力結果は、 msg:null となるのですが、ここの仕組みがわかりません。 (1)でTestクラスのコンストラクタを呼び出し、msgに"Good morning"を設定し、 処理が終わると思うのですが、(2)の処理も行われてしまいます。 (1)では、Testのコンストラクタを設定しているだけに見えてしまうのですが、 (2)まで処理が行われるのは、何故かのかをご教授の程お願い致します。

    • ベストアンサー
    • Java
  • スーパークラスの取得の仕方

    どなたかお知恵を貸してください。 現在抽象クラスを作って表示をさせる実験をしています。 ですが、下記ソースでは、取得したnameをが参照することができません。 どのようにすれば、たまの名前を出すことが出来るのでしょうか よろしくお願いいたします。 abstract class Mammals { /** 名前を表す */ String name; abstract public void introduceOneself(); public void setName(String name) { name = name; } } class Cat extends Mammals { public Cat() { super(); } public void introduceOneself() { System.out.println(name+"です。うにゃにゃ。"); } } class Main { public static void main (String[] args) { Cat tama = new Cat(); //コンストラクタ呼び出し Mammals neko = tama; //コンストラクタ呼び出し neko.setName("たま"); //自己紹介する tama.introduceOneself(); //自己紹介する } }

    • ベストアンサー
    • Java
  • コンストラクタの記述について ―引数を持ったクラスを継承する場合―

    コンストラクタの記述について ―引数を持ったクラスを継承する場合― ActionScript3.0でプログラミングをしています。 クラスの継承に挑戦したのですが、うまくいきません。 コンストラクタの記述は、何か特別なものが必要なのでしょうか? ■コンストラクタに引数なし → 成功。 ■コンストラクタに引数あり → 失敗。  エラー「No default constructor found in base class <親クラスの名前>」。 ■エラーの出るソース↓ ・Main.as(コンストラクタ内抜粋)     var parent:Parent = new Parent(100);     var child:Child = new Child(200); ・Parent.as package {   import flash.display.Sprite;      public class Parent extends Sprite {     protected var str:String = "親クラスのプロパティ";     public function Parent(inNum:Number):void {       trace("親クラス, ", str, inNum);     }   } } ・Child.as package {   import Parent;   public class Child extends Parent {     public function Child(inNum:Number):void { //■エラー。       trace("子クラス, ", str, inNum);     }   } } ご存知の方、よろしくお願いします。 よろしくお願いします!

    • ベストアンサー
    • Flash

専門家に質問してみよう