Java初心者です。
継承は親クラスのもつ属性や振る舞いを受け継ぐとのことですが、
この意味を理解しているつもりでいました。
しかし、勉強を前の章に戻ってみたところ、同じパッケージ内のクラスであれば、セッター、ゲッターを使って、メソッドや変数を取りに行くことができます。
継承もsuperをつかって、親クラスのメソッドを使うので、意味が一緒な気がしてしまい、むしろ継承は親クラスはひとつしかもてないのであれば、同じクラスのセッター、ゲッターでとりにいけばよいのではないかと考えてしまいました。
インスタンスも他のクラスで作っていたので、継承しなくても他のクラスで準備ができているため、ますますわからなくなってしまいました。
意味をしっかりと理解できておらず、このような質問となっています。
正しい理解をしたいので、ご教示いただけたら嬉しいです。
よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
基底クラスの変数に派生クラスのインスタンスを代入できる(メソッドの引数含む)ことが継承を使う一番の動機です。
そういう利用方法をしないなら継承を使う意味はないと思ってください。
振る舞いを受け継ぐのは、「継承して何もしなければそうなる」だけであって目的ではないです。
で、代入できたり引数に入れたりできると何がうれしいかというと、使う側のコードが簡略化されます。
大枠での目的が似ているクラス(例えば、ファイルに書き出すけど形式が違うとか)C
,D
があって、
それぞれf()
というメソッドがあったとしましょう。
別のクラスでC.f()
,D.f()
の結果を使って何かする、
ただし違いはCをつかうかDをつかうかだけのメソッドがあったとすると、こんな感じで書くと思います。
java
1void someMethod_C(C c){ /* c.f()を使ってなにかする */} 2void someMethod_D(D d){ /* d.f()を使ってなにかする */}
C
,D
に続いてさらにクラスを追加すると、追加した分だけsomeMethod_X
が増えることになります。
ここで、C
,D
がクラスB
を継承していたとすると、
java
1void someMethod(B b){ /* b.f()を使ってなにかする */}
の1つにまとめることができて、似たようなクラスが追加されたとしてもここに変更はありません。
投稿2019/09/01 05:52
総合スコア13512
0
継承の使い方について一番わかりやすいのはGUIの部品だと思います。
「ボタン」と「チェックボックス」はそれぞれ別のクラスですが、共通点も数多くあります。(クリックができる、ラベル(表示用のテキスト)、背景色を持っている、等)
その共通点を例えば「UIコントロール」などに全て実装しておいて、「ボタン」や「チェックボックス」は「UIコントロール」を継承すれば、後はそれぞれ独自の処理だけを実装できます。(差分プログラミング)
ここで、「全てのUIコントロールの背景色を黄色にしたい」という処理を行いたい場合、「ボタン」や「チェックボックス」といった特定の型でなく、「画面上にある全てのUIコントロール」に対して「背景色を黄色にする」処理を書くことで、全部まとめて操作することができます。
継承を使っておらず、「ボタン」や「チェックボックス」が全て独自の型で合った場合は、「画面上にボタンがあれば、黄色にする」「チェックボックスがあれば、黄色にする」などの処理を個別に書く引く必要があります。
投稿2019/08/31 17:47
総合スコア8949
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
クラスの継承に関しては、非常に重要な考え方が存在します。その考え方にはリスコフの置換原則という大層な名前がついていますが、実際そんなに難しいものでもないです。簡単に説明すると、「車は走るものだ」と決めた(決まっている)なら、車の派生であるスポーツカーも、バスも走らなくてはならないということです。
今、Animalというクラスがあったとしましょう。Animalは鳴かなくてはいけません。そして歩く必要もありそうです。この仕様を実装してみます。
java
1class Animal { 2 public String bark() { 3 return "動物が鳴きます"; 4 } 5 6 public String walk() { 7 return "動物が歩きます。"; 8 } 9}
このクラスは「動物とはこういうものである」という仕様を決めてあるだけにすぎません。ベースクラスとは、得てしてこういうものです。仕様と最低限の実装のみ。このクラスは、犬の動作を含んではいますが、犬そのものは表せません。そこで、これを継承したDogクラスを作ります。
java
1class Dog extends Animal { 2 @Override 3 public String bark() { 4 return "犬がワンワンと鳴きます"; 5 } 6 7 @Override 8 public String walk() { 9 return "犬がトコトコ歩きます。"; 10 } 11}
さて、DogクラスはAnimalクラスより正確に犬という存在を表しています。いいかえると、DogクラスはAnimalクラスより犬に特化したクラスとなっています。しかし、あるクラスを継承しているのならば、そのクラスを実際に使う側は何も考えずにそのあるクラスと全く同じ使い方ができます。この例で言うならば、「動物全体からその派生である犬に限定したとしても、動物が鳴くし歩くなら、犬も鳴くし歩く」のです。これが継承の一番重要なポイントです。これは要するに、スーパークラスの場所を任意のサブクラスで置き換えたとしても正常に動くはずであるということになります。
追記
javaには隠蔽という仕様があるため、必ずしもそうとは言えない場面も存在します。たとえば、次のAとB二つのクラスに対して、Test1は正しく実行できます。
java
1class A { 2 public int value = 5; 3} 4class B extends A { 5 public String value = "Hoge Hoge"; 6}
java
1class Test1 { 2 void method() { 3 B b = new B(); 4 System.out.println(b.value.endsWith("ge")); 5 } 6}
一方、Test2はコンパイルできません。
java
1class Test2 { 2 void method() { 3 A a = new B(); 4 System.out.println(a.value.endsWith("ge")); 5 } 6}
というのも、隠蔽の場合は実際の型(変数に格納されたオブジェクトの型)ではなく、見た目の型(変数の型)がアクセスする先に影響するからです。ここがオーバーライドとは大きく違う点です。
以上余談でした。
投稿2019/08/31 22:16
編集2019/08/31 23:27総合スコア322
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/08/31 22:27
2019/08/31 22:34 編集
2019/08/31 22:29
2019/08/31 22:33
2019/08/31 22:35
2019/08/31 22:43
2019/08/31 22:48
2019/08/31 22:52 編集
2019/08/31 23:00
2019/08/31 23:25
2019/09/01 05:07
2019/09/01 08:24
2019/09/01 13:36
2019/09/01 13:38
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/02 12:16