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

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

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

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

インターフェース

インターフェイスという用語はハードウェア・ソフトウェアの両方に使うことができます。 一般的に、インターフェイスは内部処理の詳細を見せないように設定されます。オブジェクト指向プログラミングにおいて、インターフェイスはabstractクラスとして定義されます。

継承

継承(インヘリタンス)はオブジェクト指向プログラミングに存在するシステムです。継承はオブジェクトが各自定義する必要をなくし、継承元のオブジェクトで定義されている内容を引き継ぎます。

Q&A

解決済

4回答

1303閲覧

インターフェース、継承について

DORA0702

総合スコア7

Java

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

インターフェース

インターフェイスという用語はハードウェア・ソフトウェアの両方に使うことができます。 一般的に、インターフェイスは内部処理の詳細を見せないように設定されます。オブジェクト指向プログラミングにおいて、インターフェイスはabstractクラスとして定義されます。

継承

継承(インヘリタンス)はオブジェクト指向プログラミングに存在するシステムです。継承はオブジェクトが各自定義する必要をなくし、継承元のオブジェクトで定義されている内容を引き継ぎます。

0グッド

1クリップ

投稿2021/12/15 09:57

現在、Java silverの資格取得に向けて勉強しています。参考書を読んで勉強していますが、
解説を読んでもわからないことがありましたので質問させていただきます。

interface Worker{ void work(); }
class Employee{ public void work(){ System.out.println("work"); } }
class Enginner extends Empolyee implements Worker{}
public class Main{ public static void main(String[] args){ Worker worker = new Enginner(); worker.work(); } }

解答では、このコードは「work]と表示されると書いてあります。しかし、私の解釈では、EnginnerのインスタンスをWokerとして扱おうとしているため、Mainクラスの「worker.work();」はWorkerクラスの「 void work();」が参照されると思いました。
なぜ、workと出力されるのか教えていただきたいです。

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

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

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

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

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

BeatStar

2021/12/15 10:01

Employeeも継承しているから。
dodox86

2021/12/15 10:04

> Workerクラスの「 void work();」が参照されると思いました。 Workerはクラスではなく、実体の無いインターフェースです。
jimbe

2021/12/15 10:10

Worker "インターフェース" の work の宣言を参照して・・・どうなるというのでしょうか。 「Worker 型には work メソッドがある」というだけですし、worker 変数に入れられた (Worker 型である) Enginner オブジェクトには (Employee クラスから継承された )work メソッドがあるのですから実行できるだけです。
guest

回答4

0

ベストアンサー

Java

1class Enginner extends Empolyee implements Worker { 2}

「Empolyee」は誤記で、Employee ですね
Enginner も 「Engineer」の綴りミスでしょうが、これはmainメソッド内も同じなのでプログラム上は問題なし。

以下Employee、Engineer として記載しています。

この設問、私が所有しているものと同じ書籍であれば、回答は以下の4択です。

A.Engineerクラスでコンパイルエラーが発生する
B.Mainクラスでコンパイルエラーが発生する
C.「work」と表示される
D.実行時に例外がスローされる

一見インターフェースに定義された抽象メソッドを、実装クラスでオーバーライドしているようには見えません。
コンパイルエラーになるかも、でもそうはならないよ、というタイプの問題かと思います。

スーパークラスの型でサブクラスのインスタンスを生成した際、
スーパークラスに定義したメソッドは、サブクラスでオーバーライドしていなければ
スーパークラスのメソッドを使う。
同様に、この設問の場合
インスタンスの型はWorkerインターフェース。
Workerインターフェースには、work()メソッドが定義されている。
Engineerクラスにはwork()メソッドの定義がなくオーバーライドしていない。
なのでWorkerで定義したwork()メソッドが実行される」

と、質問者さんは考えたのではないかと想像します。


抑えておくべき点は以下です。

  • 抽象メソッドはそのままでは実行できない(実行するものではない)。
  • 抽象メソッドをもったインターフェースを実装する場合、抽象メソッドをオーバーライドし実装しなければいけない。実装しないとコンパイルエラー。
  • メソッドを実行するには、実装クラスのインスタンスを生成し実行する
  • インターフェース型で実装クラスのインスタンスを生成した場合に使用できるのは
  1. インターフェースの抽象メソッドを実装クラスでオーバーライドしているメソッド
  2. インターフェースのデフォルトメソッド

そもそも、これらの点がわかっていないとすれば、恐らくお持ちであろう問題集の黒本ではなく、しっかりとした入門書(若しくは、試験特化で記載が十分とは思えませんが紫本)をまず読んだほうがいいです。

これを踏まえた上で、設問では
・Workerインターフェース型で実装クラスであるEngineerクラスのインスタンスを生成している。
・そのインスタンスのwork()メソッドを実行しようとしている。
・Workerインターフェースにwork()メソッドが抽象メソッドとして定義されている
・実行できるのは実装されたwork()メソッドだが、明示的なwork()メソッドの実装はEngineerクラスにはない
・一方、Employeeクラスには同じシグネチャのwork()メソッドがある
・Engineerクラスは Employeeクラスを継承しているので、このwork()メソッド定義を内包している
・結果、間接的にWorkerインターフェースの抽象メソッドwork()をEngineerクラスで実装していることになりコンパイルエラーは起こらない。且つ、実行することができる

Workerインターフェースのwork()メソッドそのものでなく、あくまでEngineerクラスでオーバーライドしたwork()メソッドを実行している。
そして、その実装内容はEmployeeクラスから継承されたwork()メソッド、ということです。

投稿2021/12/16 01:32

Crimson_Tide

総合スコア509

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

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

DORA0702

2021/12/16 09:35

私が考えていたような間違った解釈を踏まえて解説してくださり、ありがとうございます。 入門書を読んでいても例が少ないので自分の中で飲み込めていない部分が多かったのだと思います。 とてもわかりやすい解説をありがとうございます。資格取得に向けて頑張ります。
guest

0

しかし、私の解釈では、EnginnerのインスタンスをWokerとして扱おうとしているため、Mainクラスの「worker.work();」はWorkerクラスの「 void work();」が参照されると思いました。

なぜ、workと出力されるのか教えていただきたいです。

このコードは「そのようなことにはなりませんよ。実際はこういう結果になりますよ」という事実を説明するためのコードです。
つまり「"Workerインタフェース型"の変数であるworkerを通じてwork()メソッドを呼んでいるけれども、実際は何が動くのかというと代入されているところの"Enginner型のインスタンス"から見えているすでに実装したあったメソッドの方なんですよ」という挙動──interfaceと実装クラスの間にある多相性(多態性)という機能──を示すためのコードです。

機能を示す目的のものに「なぜそう動くのか?」をたずねるのは愚問です。

「interfaceとはこういうもので、このように使い、このようなメリットがあります」という説明があって、「では使ってみましょう、こうなります」という構成になっているはずです。
その様な構成の説明で、コードだけを読んでも意味が無いです。
説明を読んで理解してコードの挙動に納得する、あるいは逆に、コードの挙動を観察して把握した上で説明を読んで機能の意図を掴む、というような読み方をするべきものです。

ここで「なぜそう動くのか?」を説明しようとするなら、「interfaceとはこういうもので、このように使い……」という教科書的な話を重ねて始めなければなりません。

投稿2021/12/15 23:37

編集2021/12/16 01:48
quickquip

総合スコア11038

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

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

quickquip

2021/12/16 01:53

問題集のことを参考書って書いて質問されたら、すれ違いますね……。すごく無駄な時間を使ってしまった。
DORA0702

2021/12/16 09:25

説明が不十分で大変申し訳ございませんでした。 問題集でわざわざ問題まで調べて解説して下さってありがとうございました。
guest

0

Enginnerクラスが継承しているEmpolyeeクラスが持っているメソッドを呼んでいます。
インターフェースが持つメソッドを呼ぶことにはなりません(インターフェースが持つのはあくまで定義だけで実装はクラス側で書くから)

投稿2021/12/15 10:10

編集2021/12/15 10:12
m.ts10806

総合スコア80850

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

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

0

しかし、私の解釈では、EnginnerのインスタンスをWokerとして扱おうとしているため

Javaの場合、継承可能なすべてのメソッドは、そのオブジェクトの実際の型に従って呼び出されるメソッドが決まります。

インターフェース型で呼んだからといって、インターフェースのメソッド宣言だけ使われる、ということにはなりません。

投稿2021/12/16 01:58

maisumakun

総合スコア145184

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問