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

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

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

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

Q&A

解決済

2回答

1160閲覧

サブクラスにおけるインスタンス生成の際の宣言名について(「java言語で学ぶデザインパターン入門」の第3章のサンプルプログラムに関する質問)

jiro3752

総合スコア19

Java

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

0グッド

1クリップ

投稿2021/09/02 15:01

編集2021/09/02 15:45

java言語における以下のプログラムに関する質問です。書籍「java言語で学ぶデザインパターン入門」の第三章Template Methodに関するサンプルプログラムを簡略化したものです。
[質問]
Mainクラス中のStringDisplayクラスのインスタンス生成の際に
StringDisplay d2 = new StringDisplay("Hello, world.");
ではなく
AbstractDisplay d2 = new StringDisplay("Hello, world.");
とサンプルプログラムに記載されています。前者ではなく、後者のように記述するべき理由があるのでしょうか。

[追記]
質問したかった点は、一般にスーパークラス型の変数にサブクラスのインスタンスを代入するメリットは存在するのかということです。(該当書籍にはこのような記述は良いと述べられています。)

よろしくお願いいたします。

java

1abstract class AbstractDisplay { 2 public abstract void open(); 3 public abstract void print(); 4 public abstract void close(); 5 public final void display() { 6 open(); 7 for (int i = 0; i < 5; i++) { 8 print(); 9 } 10 close(); 11 } 12} 13 14class StringDisplay extends AbstractDisplay { 15 private String string; 16 private int width; 17 public StringDisplay(String string) { 18 this.string = string; 19 this.width = string.getBytes().length; 20 } 21 public void open() { 22 printLine(); 23 } 24 public void print() { 25 System.out.println("|" + string + "|"); 26 } 27 public void close() { 28 printLine(); 29 } 30 private void printLine() { 31 System.out.print("+"); 32 for (int i = 0; i < width; i++) { 33 System.out.print("-"); 34 } 35 System.out.println("+"); 36 } 37} 38 39public class Main { 40 public static void main(String[] args) { 41 StringDisplay d2 = new StringDisplay("Hello, world."); 42 AbstractDisplay d3 = new StringDisplay("こんにちは。"); 43 d2.display(); 44 d3.display(); 45 } 46} 47 48 49

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

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

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

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

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

jimbe

2021/09/02 15:07

その書籍には Template Method とは何だと書かれているのでしょうか。
jiro3752

2021/09/02 15:10

この書籍には、template methodとはスーパークラスで処理の枠組みを定め、サブクラスでその具体的な内容を定めるようなデザインパターンであると述べられています。
jimbe

2021/09/02 15:20

d2 はそのように動作していると思います。 では、d3 はどのような結果だったでしょうか。
jiro3752

2021/09/02 15:26

d3でも、AbstractDisplayをStringDisplayに置換しても同じように動作します。このように動作することはリスコフの置換原則によって保障されていますが、上記のようにAbstractDisplay型の変数に代入する理由はどのようなものがあるのでしょうか。
jimbe

2021/09/02 17:04 編集

つまり、このコードだけを見れば、(既にどう動作するか理解されている jiro3752 さんに対しては) AbstractDisplay のほうは余分だということでしょう。
guest

回答2

0

ベストアンサー

前者ではなく、後者のように記述するべき理由があるのでしょうか。

そのように記載した時の動作を読者に示すためでしょう。


d1,d2,d3とも、すべて同じAbstractDisplayのサブクラスのインスタンスだから、
継承したdisplayメソッドを呼び出すことができる。
実際の動作は個々のクラスCharDisplayやStringDisplayで定まる。

と書いてありませんか?


AbstractDisplayが提供しているメソッド群で処理を組みたてる時には

java

1AbstractDisplay d = new StringDisplay("Hello, world.");

と宣言すればAbstractDisplayが提供するメソッドだけを使っていることが保証されます
そうすれば、サブクラスをnewする部分だけを置き換えることで、AbstractDisplayを継承する別の実装に**(以降の処理には手を加えずに)切り替えられることが保証できます**。


java

1StringDisplay d = new StringDisplay("Hello, world.");

と宣言した時、コードを書いていく最中にStringDisplayの内部実装にあたるメソッドを呼んでしまったら、AbstractDisplayを継承する別の実装に(以降の処理には手を加えずに)切り替えられることが保証できません
これでは抽象クラスを上位クラスとして定義するメリットを享受していません。

抽象クラスを使う時には抽象クラスをわざわざ宣言するメリットを享受したいです。

投稿2021/09/02 15:39

編集2021/09/02 16:17
quickquip

総合スコア11235

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

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

jiro3752

2021/09/02 16:15

この解答は StringDisplay d2 = new StringDisplay("Hello, world."); と記述しない理由にはなっていないのではないでしょうか。
quickquip

2021/09/02 16:18

最初の質問だと「書籍でサンプルプログラムをそのように書く理由」でしたから……
quickquip

2021/09/02 16:21 編集

print("ABC") と書くとABCと表示されますと書いてある書籍に 「なんでABCと表示するんですか? そのメリットは?」と聞いているような質問でしたよね…… それは、どういう機能を持っているか、どういう動作をするかを説明するためのコードです、という答えになりますよね
quickquip

2021/09/02 16:24

クラススタイルのオブジェクト指向に慣れてないと AbstractDisplay d2 = new StringDisplay("Hello, world."); d2.display(); と書いた時に実際にどのdisplayが動くのかわからないわけです。 その説明のためのコードですよね? という回答をするべき質問だと(元の質問だと)判断したわけです。
quickquip

2021/09/02 16:27 編集

StringDisplay d2 = new StringDisplay("Hello, world."); と書いたら、クラススタイルのオブジェクト指向言語における多態性の説明にならないんですよ。
jiro3752

2021/09/03 00:35

不明瞭な質問で申し訳ありません。 知りたかった答えを頂くことができました。ありがとうございます。
guest

0

スーパークラス型の変数にサブクラスのインスタンスを代入するメリット

当初と趣旨が全然変わってしまいますが。

よく、 java のメソッドにオブジェクトを渡す際には、大抵はその宣言された型そのものでは無く(ユーザが選んだり定義したりした)サブクラスのオブジェクトを渡しますね。
それが出来るのがメリット(の1つ)ではないでしょうか。

投稿2021/09/02 17:22

jimbe

総合スコア13209

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

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

jiro3752

2021/09/03 00:39

回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問