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

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

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

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

Q&A

解決済

3回答

3382閲覧

ポリモーフィズムについて:内容が真逆でわけがわからない

k_mail

総合スコア90

Java

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

0グッド

1クリップ

投稿2016/03/12 02:54

編集2016/03/12 03:55

Java SE7 Silver の資格を目指し勉強中です。
分からない点はポリモーフィズムです。
1.「インスタンスがどのようなメソッドやフィールドを持っていたとしても、
扱っている型で定義されているもの以外は使えない」という文と
2.「何型で扱っていてもインスタンスが持つメソッドが実行される」という文があります。

どちらも黒本(P272とp519)に書かれているのですが真逆のように思えます。

1に関しては
public class A{
public void hello(){
//any code
}
}

public class B extends A{
public void sample(){
//any code
}
}

public class Main{
public static void main(String[] args){
A a = new B();
a.sample(); //←Aには存在しないメソッドでコンパイルエラーとなる


--------------------------------------------
一方、2に関しては
public class A{
public void sample(){
System.out.println("A");
}
}

public class B extends A{
public void sample(){
System.out.println("B");
}
}

public class Main{
public static void main(String[] args){
A a = new B();
a.sample();
}
}
では、「B」と表示される、というのが答えです。

何がどう違うのかが全く分かりません。
これから席を外すので、返信は夜になると思いますが、
どうか、よろしくお願いします。

追記:修正依頼を受け、修正済みです。

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

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

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

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

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

swordone

2016/03/12 02:59 編集

2.のコードで、Aのメソッド名がsample()になっているとか、そういうコードの見間違いはありませんか?もしこの通り書かれているとしたらその本は真っ赤な嘘を書いてることになります。あるいは本の発行社のサイトなどで正誤表が出ていないか確認するべきかと思います。
guest

回答3

0

結論からいえば、矛盾してないように見えます。

ただ、ちょっと2つめの答えのコードは
「何型で扱っていてもインスタンスが持つメソッドが実行される」を説明するには
「何型で扱っていても」と言っているのに、Aでしか扱ってないので、例として弱い気がします。

・変数宣言をしたメソッドしか呼べない。
・違うインターフェースでメソッドを呼んだ場合に、それぞれの実装クラスで定義された同一のメソッドが実行される。

ひとつめは、変数で「働く人」を宣言したなら、彼らに言えることは「稼げ!」というだけで、それぞれに魚を釣れだとか、木を切れと言うことはできません。

ふたつめは、私の例だと誰に稼げと言われても、それぞれが、やることは同じで、木こりは木を切るし、漁師は魚を釣るだけです。

Java

1public class Boss { 2 public static void main(String[] args) throws Exception { 3 WorkingPerson one; 4 5 //Only what you can say is just earn. 6 one = new Lumberjack(); 7 //Each people earn with their own way. 8 System.out.println(one.earn()); 9 10 one = new Fisherman(); 11 System.out.println(one.earn()); 12 //You cannot say row a boat to fisherman when you declare one as a working person. 13 //one.rowABoat(); //oops! 14 15 //When children say earn to their father.. 16 Dad dad; 17 dad = new Lumberjack(); 18 //Fathers do just same thing. 19 System.out.println(dad.earn()); 20 dad = new Fisherman(); 21 System.out.println(dad.earn()); 22 } 23} 24interface WorkingPerson { 25 public String earn(); 26} 27interface Dad { 28 public String earn(); 29} 30 31class Lumberjack implements WorkingPerson,Dad { 32 public String earn() { 33 return "I'll hew down a tree."; 34 } 35 public void climbATree() { 36 37 } 38} 39 40class Fisherman implements WorkingPerson,Dad { 41 public String earn() { 42 return "I'll catch a fish."; 43 } 44 public void rowABoat() { 45 46 } 47}

投稿2016/03/12 05:00

thesecret11

総合スコア234

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

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

k_mail

2016/03/12 12:23

丁寧な例も挙げていただいて勉強が深まりました。 有難うございました。
guest

0

ベストアンサー

a.sample();
と書かれていたら

1.の場合
aの(宣言上の)型を見ます。→Aでした。
Aにsample()が存在するか見ます。→ありませんでした。
ないものを使おうとしたのでコンパイルエラーです。

2.の場合
aの(宣言上の)型を見ます。→Aでした。
Aにsample()が存在するか見ます。→ありました。
aに、「aが持っている」sample()を実行させます。

aの中身はa=new B()、Bクラスでsample()の内容がオーバーライドされているので、
aの持っているsample()の内容はBクラスに書かれているほうのsample()です。

投稿2016/03/12 04:46

ozwk

総合スコア13521

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

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

k_mail

2016/03/12 12:18 編集

順序立てて説明していただき、非常に分かりやすかったです。 オーバーライドをしていれば、そちらを優先するということですね。 有難うございました。
guest

0

本の記述は正しいです。

まず、1のこの部分ですが、

java

1A a = new B();

変数aは型がAになっているので、
class Bにはあるがclass Aには無いsample()メソッドは呼び出せません。

2について

java

1public class A{ 2 public void sample(){ 3 System.out.println("A"); 4 } 5}

と定義されているので、1とはまったく別の話になっています。
これはオーバーライド(override)と呼ばれる仕組みで、
class Aを継承した class B でsampleメソッドを上書きしています。
この時、

java

1A a = new B(); 2a.sample();

にあるようにBのインスタンスが、A型の変数に入っていても、
Bで上書きしたsampleメソッドが呼び出されるため出力はBという結果になります。

投稿2016/03/12 04:36

rysh

総合スコア874

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

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

k_mail

2016/03/12 12:19

オーバーライドをしていれば、そちらが優先すされるということですね。 有難うございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問