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

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

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

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

Q&A

解決済

3回答

11341閲覧

メンバ変数に、自分と同じクラスのインスタンスを持つクラスについて

TrueOgre2

総合スコア26

Java

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

0グッド

1クリップ

投稿2016/05/19 14:41

###前提・実現したいこと
メンバ変数に、自分と同じクラスのインスタンスを持つクラスについて
見慣れていないこともあり、ものすごく違和感があります。
ネットでこのようなクラスの解説が読みたくて検索したのですが、キーワードが分からず、望む記事が見つかりませんでした。

1.このような、「メンバ変数に、自分と同じクラスのインスタンスを持つクラス」に特別な名前やキーワードなどあるのでしょうか?

2.20行目の_nameは、privateなのに、14行目で「.」でアクセスしています。違和感があるのですが、どう考えれば良いのでしょうか?

どうぞよろしくおねがいします。

###該当のソースコード

Java

1package ReplaceErrorCodeWithException.before_; 2 3import java.util.HashMap; 4import java.util.Map; 5 6public class Command { 7 public static final Command FORWARD = new Command("forward"); 8 public static final Command BACKWARD = new Command("backward"); 9 public static final Command TURN_RIGHT = new Command("right"); 10 public static final Command TURN_LEFT = new Command("left"); 11 private static final Map<String, Command> _commandMap = new HashMap<String, Command>(); 12 13 static { 14 _commandMap.put(FORWARD._name, FORWARD); 15 _commandMap.put(BACKWARD._name, BACKWARD); 16 _commandMap.put(TURN_RIGHT._name, TURN_RIGHT); 17 _commandMap.put(TURN_LEFT._name, TURN_LEFT); 18 } 19 20 private final String _name; 21 22 private Command(String name) { 23 _name = name; 24 } 25 26 public String getName() { 27 return _name; 28 } 29 30 public static Command parseCommand(String name) { 31 if (!_commandMap.containsKey(name)) { 32 return null; 33 } 34 return _commandMap.get(name); 35 } 36}

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

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

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

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

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

guest

回答3

0

ベストアンサー

これはシングルトンと呼ばれるパターンでよく見られるクラスです。まず、このインスタンスはstaticであることに注意、非staticだと無限に入れ子インスタンスを作ることになってしまう。

そして、重要なのはコンストラクタがprivateメソッドであることです。つまり、外部からnewすることを禁止しています。staticで定義された有限のインスタンスのみ存在を許し、これ以上のものは存在を認めません。また、staticの性質上、これらのインスタンスはグローバル変数に近い意味を持ちます。

投稿2016/05/19 14:56

HogeAnimalLover

総合スコア4830

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

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

TrueOgre2

2016/05/19 15:57

回答ありがとうございます。 確かに、自分と同じクラスのインスタンスを持つ形をシングルトンで見たことありました。 4つも自分と同じインスタンスを持ってると、全く気づかず目からウロコでした。 非staticだと、無限に入れ子インスタンスを作ってしまうという話も納得出来ました。 すっごく面白いですね。怖いプログラムが作れちゃいそうですね(笑) 自分自身でしか、自分の保持してるメンバ変数のインスタンスを作れないというのが分かりました。 _commandMapを準備するために、このクラスが存在してるのかなっていうのがおぼろげながら見えてきました。 気づく事がいっぱいありました。 どうもありがとうございます。
swordone

2016/05/19 16:06

非staticな自分自身のクラスのインスタンスを持つクラスもありますよ。プログラマが明示的に使うものではありませんが。 LinkedListのような連結リストの場合、データをノードと呼ばれるもので管理し、自分自身の前後のノードを自分自身のノードのインスタンスに持つような構造になっています。 無限入れ子インスタンスになるのは、メンバ変数の宣言の段階でインスタンス生成している場合ですね。
TrueOgre2

2016/05/20 06:07

コメントありがとうございます。 線形リスト、言われてみれば、自分自身と同じ型のメンバ変数保持していますね。 並び順のひとつ前のインスタンスを、保持しておく必要がありますものね。 納得です。 クラスって型の宣言なのに、中で自分のインスタンを保持してることが 気持ち悪くて、気持ち悪くて、しょうがなかったんですが、皆様の説明を 聞いて、気持ち悪さが和らぎました。 特に、線形リストを記述する時の考え方では、全く違和感無かったです。 どうもありがとうございます。 今回のクラスをUMLで書くと、◇が4つあり、自分自身に4本の線が結ばれてる形 なのですかね。 普通は、自己結合のcompositionを描かないのかも知れないけど、描いた図を想像したら 少し分かりやすいかもって思ってしまいました。
HogeAnimalLover

2016/05/21 08:33 編集

>>線形リスト はい。その通り、自身と同じクラスの「参照」を持つだけであれば、リスト構造等でも同様の形が出てきます。この例では「インスタンス生成も含めて」行われていたので上記の表現をしました。あしからず。 >>クラス図 インスタンス数だけ線を結ぶってこと?オブジェクト図ならわかるけど、クラス図だと不自然だと思います。まあいずれにしろ、これが単独のシステムではないだろうのでUMLを書くのはもう少し視野を広げてからだと思います。
TrueOgre2

2016/05/20 17:09

コメントどうもありがとうございます。 HogeAnimalLover さんの回答に、1番沢山ひらめきを貰ったので、ベストアンサーにさせて頂きました。 クラス図ではなくて、オブジェクト図なんですね。もっと勉強しなければと思う次第です。 どうもありがとうございました。
guest

0

1-たぶん名前はないと思います。しかし、コード自体はコマンドパターンだと思います。
また、コードはenumが導入される前に列挙型を表すために使われていたコードだと思います。

2-privateはclass外からのアクセスを禁止する修飾子です。
該当の個所はclass内のstatic初期化ブロックなのでstaticな変数に.でアクセスできます。

投稿2016/05/19 15:04

yona

総合スコア18155

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

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

TrueOgre2

2016/05/19 16:30

回答ありがとうございます。 デザインパターンは勉強中で、コマンドパターンについて理解を深めておきます。 定数をenumに置き換えるリファクタリングありますね。 static初期化ブロックなら、static変数にアクセス出来る、納得です。 どうもありがとうございました。
guest

0

  1. 特にキーワードはないかと。あえて言うなら「定数」でしょうか?

Commandクラス内に、予め決められたCommandオブジェクトを置いていることになります。
public staticなので、Commandクラスからインスタンスを作成することなくこれらのオブジェクトを使うことができます。
またfinalなので、外部からオブジェクトごと置き換えられる心配もありません。可変オブジェクトなら内部を書き換えることもできますが、これは不変オブジェクトのようなので問題ありません。

  1. privateはこのクラス内からのみアクセス可能という意味です。_nameにアクセスしているのは同じクラス内からなので、問題なくアクセス可能です。

投稿2016/05/19 14:57

swordone

総合スコア20651

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

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

TrueOgre2

2016/05/19 16:09

回答ありがとうございます。 各Commandオブジェクトを準備しておく為のクラスなのですね。 2について、インスタンスが違うとprivateにアクセス出来ないような 間違った理解をしていた事に気づきました。 クラスが同じだと、インスタンスが異なっても、アクセス出来るのですね。 どうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問