java interface使用のプログラムの流れが分かりません
解決済
回答 2
投稿
- 評価
- クリップ 0
- VIEW 979
java言語です。
コード、実行結果は下記のようになります。
どうして実行結果の様になるのか分かりません。処理の流れを教えてください。宜しく御願い致します。
コード
import java.util.ArrayList;
import java.util.List;
public class Sample {
public static void main(String[] args){
LayoutBase layout = new LayoutBase();
layout.addChild(new GridLayout());
layout.addChild(new FlowLayout());
layout.flush();
}
}
interface Layout{
void addChild(Layout layout);
void flush();
}
class LayoutBase implements Layout{
String tag = "root";
List<Layout>child;
public LayoutBase(){
child = new ArrayList<Layout>();
}
public void addChild(Layout layout){
child.add(layout);
}
public void flush(){
System.out.println("</" + getTag() + ">");
for(Layout c:child){
c.flush();
}
System.out.println("</" + getTag() + ">");
}
String getTag(){
return tag;
}
}
class GridLayout extends LayoutBase{
String getTag(){
return "GridLayout";
}
}
class FlowLayout extends LayoutBase{
String getTag(){
return "FlowLayout";
}
}
実行結果
</root>
</GridLayout>
</GridLayout>
</FlowLayout>
</FlowLayout>
</root>
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+1
下のコード内で説明して見ました
番号順に説明してあります
import java.util.ArrayList;
import java.util.List;
public class Sample {
public static void main(String[] args){
//①LayoutBaseオブジェクトのインスタンスを変数layoutに入れる
//この時、new LayoutBase() してLayoutBaseオブジェクトのインスタンスを作成した時に
//LayoutBaseクラスのコンストラクタである public LayoutBase(){}が呼ばれ
//予めLayoutBaseクラス内で宣言されていた List<Layout> 型の変数child内に
//new ArrayList<Layout>() が代入される
LayoutBase layout = new LayoutBase();
//②layout変数に入っているLayoutBaseオブジェクトのインスタンス内のaddChild()メソッドを呼び出す
//引数にnew GridLayout(),new FlowLayout()を入れて二回実行する
//この時、addChildメソッドの引数は public void addChild(Layout layout){のように
//Layout型になっているため このメソッドの引数にはポリモーフィズムを用い
//Layoutインターフェースをimplementsしたクラスを入れて呼び出す事ができる
//二回呼び出した結果addChild内の操作により
// List<Layout> 型の変数child内のインスタンスnew ArrayList<Layout>()内に
//new GridLayout()・・・・クラスGridLayoutのインスタンスと
//new FlowLayout()・・・・クラスFlowLayoutのインスタンスが一つずつ入る
layout.addChild(new GridLayout());
layout.addChild(new FlowLayout());
//③layout変数に入っているLayoutBaseオブジェクトのインスタンス内のflush()メソッドを呼び出す
//flushメソッド内での操作は
//・・・・④に続く
layout.flush();
}
}
interface Layout{
void addChild(Layout layout);
void flush();
}
class LayoutBase implements Layout{
String tag = "root";
List<Layout>child;
public LayoutBase(){
child = new ArrayList<Layout>();
}
public void addChild(Layout layout){
child.add(layout);
}
public void flush(){
//④ </ と > の間にメソッドgetTag()の返り値が結合されて表示され改行される
//getTag()の返り値とはString tag = "root";で代入されている値root
//よって</root>が表示される
System.out.println("</" + getTag() + ">");
//⑤拡張for文により変数child内に入っているインスタンスが順にLayout型の変数cに代入されて{}内で実行される
//c.flush();により各インスタンス内のflushメソッドが呼び出されるが、
//flushメソッドは各オブジェクト(GridLayout,FlowLayout)ではオーバーライドされておらず、
//それらが共通でextendsしているクラスLayoutBaseのみでオーバーライドされている
//よって、これらのオブジェクトが入っているLayout型変数cからflushメソッドを呼び出した場合
//ポリモーフィズムの働きによりLayoutBase内でオーバーライドされたflushメソッドが実行され
//その呼び出されたそれぞれのオブジェクト(GridLayout,FlowLayout)内のflushメソッドは
//その内部で</ と > の間にメソッドgetTag()の返り値が結合されて表示し改行する
//この時、メソッドgetTag()はそれぞれのオブジェクト(GridLayout,FlowLayout)内でオーバーライドされており、
//GridLayout内メソッドのgetTag()では"GridLayout",FlowLayoutメソッドのgetTag()では"FlowLayout"
//を返す
//その後それぞれのオブジェクト(GridLayout,FlowLayout)内のflushメソッドは
// for(Layout c:child){
// c.flush();
// }
//部分を実行しようとするが、この時GridLayout,FlowLayoutそれぞれのオブジェクト内では一度もaddChildメソッドが実行されていないので
//これらのオブジェクト内のList<Layout>child;にはGridLayout,FlowLayoutそれぞれのオブジェクトの生成時のコンストラクタの動作
//により生成されたnew ArrayList<Layout>()が入っているだけでこのインスタンス内には値が入っていない よって
//上記拡張for文内では何も表示されず
//その後のSystem.out.println("</" + getTag() + ">");により
//</ と > の間にメソッドgetTag()の返り値 すなわち
//GridLayout内メソッドのgetTag()では"GridLayout",FlowLayoutメソッドのgetTag()では"FlowLayout"が結合されて表示され改行される
//これらがそれぞれのオブジェクト内にて順に実行され
//</GridLayout>
//</GridLayout>
//</FlowLayout>
//</FlowLayout>
//と表示された後
//上の⑤先頭部分の拡張for文を抜けて次の文に進み
//</ と > の間にメソッドgetTag()の返り値が結合されて表示され改行される
//getTag()の返り値とはこの場合String tag = "root";で代入されている値root
//よって</root>が表示される
//ここでmainメソッドで呼び出したflushメソッドが終了しmainメソッドが終わりプログラムは終了する
for(Layout c:child){
c.flush();
}
System.out.println("</" + getTag() + ">");
}
String getTag(){
return tag;
}
}
class GridLayout extends LayoutBase{
String getTag(){
return "GridLayout";
}
}
class FlowLayout extends LayoutBase{
String getTag(){
return "FlowLayout";
}
}
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
interface余り関係ないですが…
まずlayoutのflush()が実行されますので、layoutに対して
System.out.println("</" + getTag() + ">");
が実行されます。layoutのgetTag()は"root"を返すため、</root>が表示されます。
次に、拡張for文でまず最初に追加したGridLayoutのflush()が実行されます。
GridLayoutの拡張for文に入る前の文で</GridLayout>が出力されます。
その後GridLayoutの拡張for文に入りますが、GridLayoutには何も入っていないので何もせず抜けます。
そして抜けた後の文で</GridLayout>が表示されます。
追加されたGridLayoutのflushが終了し、layoutの拡張for文が次に進み、FlowLayoutのflushが実行されます。
先ほどのGridLayoutの流れと全く同じ理由で、2回</FlowLayout>が実行されます。
ここでlayoutの拡張for文が終了し、layoutのfor文が終了します。
そしてそのあとの文が実行され、</root>が出力されます。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.13%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2017/02/11 08:39
ありがとうございました。これで眠れます。