質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

4回答

7700閲覧

コンストラクタチェーンについて

退会済みユーザー

退会済みユーザー

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2016/12/22 07:34

public class Super{ protected int num; public Super(){ this.num = 1; } public Super(int num){ this.num = num; } } public class Sub extends Super{ private int a; private int b; public Sub(int a){ this.a = a; } public Sub(int a,int b){ this(a); this.b = b; } public static void main(String[] args){ Sub sub = new Sub(2,3); System.out.print(sub.num + ":" + sub.a + ":" + sub.b) } }

この時、aが2、bが3になるのはわかります。
Superクラスのpublic Super()が呼ばれてthis.numに1が代入されていることはわかるのですが、どこでSuper()が呼ばれたのかが分かりません。
答えを見るとSubクラスのSub(int a)の1行目で呼ばれていますが、なぜここで呼ばれるのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

子クラスのコンストラクタが呼び出される時、そのコンストラクタの1行目では(暗黙的に)引数なしの親クラスのコンストラクタが呼び出されます。そういう決まりになっているのです。

Java

1 public Sub(int a){ 2 this.a = a; 3 }

は内部的に

Java

1 public Sub(int a){ 2 super(); 3 this.a = a; 4 }

になっているのです。

参考
http://www.javadrive.jp/start/extends/index4.html

もし明示的に親クラスの引数有りのコンストラクタを呼び出したい場合は、1行目に

public Sub(int a){ super(a); this.a = a; }

と書くといいでしょう。

投稿2016/12/22 07:56

編集2016/12/22 08:01
hitsujimeeee

総合スコア486

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/12/22 14:44

ありがとうございます。そういう決まりなのですね。 Sub(int a,int b)の方にない理由はthis(a)があるからですか?
hitsujimeeee

2016/12/26 06:03

コンストラクター呼び出しthis(a)とsuper(a)は1つのコンストラクタ内で両方呼ぶことはできないため(そもそもキチンと設計していれば両方呼ぶ必要は無い)、Sub(int a, int b)の方にはありません。
guest

0

Java言語仕様で、以下のように定められているからです。
https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.7

If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object, then the constructor body implicitly begins with a superclass constructor invocation "super();", an invocation of the constructor of its direct superclass that takes no arguments.

もし、コンストラクタ本体が明示的なコンストラクタ呼び出しで始まらず、 かつ宣言されているコンストラクタが Objectクラスの一部でない場合、 コンストラクタ本体は暗黙のうちにスーパークラスコンストラクタの呼び出し"super();"で始まります。

投稿2016/12/22 08:17

KiyoshiMotoki

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Superにコンストラクターが定義してある以上、いずれかのコンストラクターを呼び出さずにSuperのインスタンスを生成することはできません。もしそれができたらコンストラクターの意味はないですね?

Sub(int a)では基底クラスのコンストラクターは呼び出していませんが、前述したとおり必ずどれかのコンストラクターは呼ばなければならないのです。なぜ呼び出していなくてもいいかというと、基底クラスに引数なしのコンストラクターが定義されているからです。

試しにSuperの引数なしコンストラクターをコメントアウトしてみてください。そうするとSub(int a)では「基底クラスのコンストラクターを呼ばないと初期化できませんよ」というエラーになるはずです。

投稿2016/12/22 08:01

KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2016/12/22 08:06

引数なしのコンストラクターがあれば暗黙的に呼び出されます云々を追記しようとしたら、hitsujimeeeeさんが既に回答されてました・・・
guest

0

コンパイラがコンパイル時に引数無しのコンストラクタを追加するのでソースコード上にはなくても実行ファイル上では呼び出しが書いてあると思いますよ。

投稿2016/12/22 07:46

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問