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

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

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

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

Q&A

解決済

3回答

3663閲覧

Java クラスの継承の基本 サブクラスでメソッドを使うには?

masaakitsuyoshi

総合スコア102

Java

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

0グッド

0クリップ

投稿2016/03/10 14:54

下記で、ClassSampleというクラスの内で定義されているいくつかのメソッド(かんたんな算術演算のメソッド)
を、同じパッケージ内の別のクラスClassSample2でも使いたいです。

そこでextendsを使っているのですが、ClassSample2にて継承したはず?のメソッドが実行されません。

おそらく基本的な事項の理解が足りてないのだと思いますが、どこが問題でしょうか。

package sample; public class ClassSample { public static void main (String[] args) { ClassSample ddd = new ClassSample(); System.out.println(ddd.tashizan(190,30)); System.out.println(ddd.hikizan(380, 89)); System.out.println(ddd.warizan(900, 40)); System.out.println(ddd.amari(15, 5)); } public int tashizan (int a, int b) { return a + b; } public int hikizan (int a, int b) { return a - b; } public int warizan (int a, int b) { return a / b; } public int amari (int a, int b) { return a % b ; } } class ClassSample2 extends ClassSample{ public static void main (String[] args) { ClassSample ccc = new ClassSample(); System.out.println(ccc.tashizan(1000,30)); System.out.println(ccc.hikizan(100, 20)); System.out.println(ccc.warizan(10000, 40)); System.out.println(ccc.amari(300, 5)); } }

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

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

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

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

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

guest

回答3

0

ベストアンサー

コメントをいただきましたので回答を追記します。

と書けばOKでしょうか?

まず、javaのコンソールプログラムは起動クラスのmain()メソッドから実行されることになっています。
パッケージが設定されているのでコマンドプロンプトでは下のように実行します。

...\sample\bin>java sample.ClassSample

するとクラスファイルのmainメソッドから実行されるので
下記のソースではClassSample2のインスタンス化がまず実行されます。
続いて元々のSystem.out.println数行が実行されます。
さらにパターン1が実行された後、パターン2、パターン3、パターン4が実行されます。

package sample; public class ClassSample { @SuppressWarnings("static-access") public static void main (String[] args) { ClassSample2 ddd = new ClassSample2(); /* 元の出力処理 */ System.out.println("元の処理"); System.out.println(ddd.tashizan(190,30)); System.out.println(ddd.hikizan(380, 89)); System.out.println(ddd.warizan(900, 40)); System.out.println(ddd.amari(15, 5)); System.out.println(""); /* パターン1 */ System.out.println("パターン1"); ddd.main(new String[]{}); System.out.println(""); /* パターン2 */ System.out.println("パターン2"); System.out.println(ddd.tashizan(1000,30)); System.out.println(ddd.hikizan(100, 20)); System.out.println(ddd.warizan(10000, 40)); System.out.println(ddd.amari(300, 5)); System.out.println(""); /* パターン3 */ System.out.println("パターン3"); (new ClassSample2()).main(new String[]{}); System.out.println(""); /* パターン4 */ System.out.println("パターン4"); ClassSample2.main(new String[]{}); System.out.println(""); } /* 中略 */ }

クラスを継承していても、継承側(ClassSample2)で、ClassSample2をインスタンス化しなければならない。

継承先(=継承側?)、継承元にかかわらず、staticメソッドじゃない場合、インスタンス化が必要です。
(ClassSampleを継承している)ClassSample2を利用する側でインスタンス化する必要があります。
上の例ではパターン1、3がインスタンス化したClassSample2の持つmain()メソッドを実行しています。

で、ClassSample2はClassSampleを継承しているので、その中のメソッドが自由に使える、という理解でいいでしょうか?

基本的にはそういう理解でよいのではないでしょうか?
なぜ「基本的には」かというと、修飾子によって動きが大きく変わるからです。
クラスにstaticをつけることでインスタンス化が「不必要(不可)」が変わったり、
メソッドにprivateをつけることでそのメソッドが外から利用することが出来なくなったりします。

上記の例ではパターン2がClassSampleを継承したClassSample2がインスタンス化され、
継承したtashizan()など4つのメソッドを持っているので利用できることになります。

ちなみにClassSample2の中でmain()staticになっているので、
パターン4のような実行もできますし、

public static void main(String[] args)

で定義されているので、コマンドプロンプトから

...\sample\bin>java sample.ClassSample2

の実行もできます。


現状、どちらのクラスもコンストラクタが無いようです。
javaのコンソールプログラムの場合、起動クラスのmain()メソッドが最初実行されるメソッドです。

そのmain()の中でClassSampleはインスタンス化されていますが、
ClassSample2はインスタンス化もされていないですし、
もちろんClassSample2.main()メソッドも実行されていません。

因みにですがClassSampleの中でClassSampleをインスタンス化していますが、
ここにコンストラクタを追加するとエラーになると思います。
無限にコンストラクタメソッドを実行し続けるようなループに陥るでしょう。

以上、
ご参考になりますでしょうか?

投稿2016/03/10 15:05

編集2016/03/14 12:38
Aeona

総合スコア396

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

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

masaakitsuyoshi

2016/03/14 09:31

お返事が遅くなりました。 私のクラスの「継承」の基本的理解が足りていないのだと思います。 >> ClassSample2はインスタンス化もされていないですし、 もちろんClassSample2.main()メソッドも実行されていません。 ということは、 class ClassSample2 extends ClassSample{ public static void main (String[] args) { ClassSample2 ccc = new ClassSample2(); System.out.println(ccc.tashizan(1000,30)); System.out.println(ccc.hikizan(100, 20)); System.out.println(ccc.warizan(10000, 40)); System.out.println(ccc.amari(300, 5)); } } と書けばOKでしょうか? クラスを継承していても、継承側(ClassSample2)で、ClassSample2をインスタンス化しなければならない。 で、ClassSample2はClassSampleを継承しているので、その中のメソッドが自由に使える、という理解でいいでしょうか?
Aeona

2016/03/14 12:39

回答に追記しました。 分かりにくければコメントしてください。
masaakitsuyoshi

2016/03/15 04:24

ご回答ありがとうございます。 「static」,一番最初に出てくる修飾子なのに、大抵のサイトで特に説明がなかったのでずっと引っかかっていましたが、なんとなく概要をつかむことができました。 >>基本的にはそういう理解でよいのではないでしょうか? なぜ「基本的には」かというと、修飾子によって動きが大きく変わるからです。 クラスにstaticをつけることでインスタンス化が「不必要(不可)」が変わったり、 メソッドにprivateをつけることでそのメソッドが外から利用することが出来なくなったりします。 private protected public などはなんとなく言葉からイメージができますが、 「カプセル化」あたりがまだあまり分からないので勉強してまいります!
guest

0

こんな感じにすると、両方呼びだされますね。

Java

1public class ClassSample { 2 public static void main(String[] args) { 3 4 ClassSample ddd = new ClassSample(); 5 System.out.println(ddd); 6 System.out.println(ddd.tashizan(190, 30)); 7 System.out.println(ddd.hikizan(380, 89)); 8 System.out.println(ddd.warizan(900, 40)); 9 System.out.println(ddd.amari(15, 5)); 10 11 12 ClassSample ccc = new ClassSample2(); //Look! here! 13 System.out.println(ccc); 14 System.out.println(ccc.tashizan(190, 30)); 15 System.out.println(ccc.hikizan(380, 89)); 16 System.out.println(ccc.warizan(900, 40)); 17 System.out.println(ccc.amari(15, 5)); 18 19 } 20 @Override 21 public String toString() { 22 return "ClassSample Dad!"; 23 } 24 25 public int tashizan(int a, int b) { 26 return a + b; 27 } 28 29 public int hikizan(int a, int b) { 30 return a - b; 31 } 32 33 public int warizan(int a, int b) { 34 return a / b; 35 } 36 37 public int amari(int a, int b) { 38 return a % b; 39 } 40} 41 42class ClassSample2 extends ClassSample { 43 @Override 44 public String toString() { 45 return "ClassSample Jr!"; 46 } 47}

「継承の動きを確認したい」のがプログラムの意図だと思うのですが、
「確認するより前に、2つめのクラスが動いてない」という問題でひっかかっています。

つまり、動いたところで思ったように継承の動きを確認できるとは限らない、ということはご留意ください。

投稿2016/03/10 23:57

thesecret11

総合スコア234

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

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

masaakitsuyoshi

2016/03/14 09:39

お返事が遅くなりました。 extendしたもの(ClassSample2)を、extendsされた側(ClassSample)のmainメソッドに書けばいいんですね。 下記のようにしても同じ意味ですか? ※元ソースの一部のみ変更 class ClassSample2 extends ClassSample{ public static void main (String[] args) { ClassSample2 ccc = new ClassSample2(); //ClassSample2をインスタンス化 System.out.println(ccc.tashizan(1000,30)); System.out.println(ccc.hikizan(100, 20)); System.out.println(ccc.warizan(10000, 40)); System.out.println(ccc.amari(300, 5)); } }
thesecret11

2016/03/15 04:45

んー。 mainメソッドは、public classのものしか動かないので、sample2にmainを書いてもあまり意味がありません。両方をClassSampleのmain、またはmainから呼び出されるオブジェクト/メソッドに入れてあげる必要があります。 あと、繰り返しですが、どのmainメソッドが動くという話と、継承は別問題です。
masaakitsuyoshi

2016/03/15 08:58

最初のmainの方に全部ぶち込んだら動きました。 ーーーー 継承って、スーパークラスと全く同じメソッドをサブクラスに呼び出したいときにはあまり意味ないのでしょうか? あくまで、スーパークラスのメソッドを再定義したり、 ポリモフィズム的にメソッドの処理を増やしたり、といったことに使ことが多い? ClassSample のメソッドと全く同じメソッドを持つ複数のクラスを作りたい場合は、 ご回答いただいたようにClassSample内で複数インスタンス化すればいいだけ、ということでしょうか。
thesecret11

2016/03/15 09:35

継承の使い方はいろいろありますが、もちろんスーパークラスと同じメソッドを使いたいケースも多いです。例えば、AndroidやSwingで使われる、TableModelだとか、ListModelだとかを必要な全メソッドを定義するのは面倒ですから、継承したクラスを使います。 ログや例外の実装がどうであれ、個々のServletなどに細かい処理を書くのは面倒ですから、子クラスでは「this.log()」とだけ書けばいいようにするとかいう形で継承を使います。深すぎると何をしてるのやらわからなくなるので、親クラスはabstractクラスで定義して、子クラスは1階層だけ・・にするのは私の書き方です。 ポリモフィズムは丁寧にやるならinterfaceで受け側を定義して、Abstractで一番の親を作って、Defaultクラスで汎用的な動きを作り、その他の子クラスで特殊な動きを作りますが、そこまでクラスを作らないならinterfaceだけで終わりにしますので、継承は使わなかったりします。
guest

0

ClassSampleとClassSample2で別々にmainメソッドを書いているだけで、使っているインスタンスはどちらもClassSampleのものです。
ClassSample2の機能を使いたければClassSample2のインスタンスを生成して使う必要があります。

投稿2016/03/10 14:57

swordone

総合スコア20651

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

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

masaakitsuyoshi

2016/03/14 09:32

ということは、 class ClassSample2 extends ClassSample{ public static void main (String[] args) { ClassSample2 ccc = new ClassSample2(); System.out.println(ccc.tashizan(1000,30)); System.out.println(ccc.hikizan(100, 20)); System.out.println(ccc.warizan(10000, 40)); System.out.println(ccc.amari(300, 5)); } } と書けばOKでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問