プログラミング初心者です。
Javaのコーディングで下記のような記述をたまに見かけるのですが、どういった目的があるのでしょうか。
public class Parent <T extends Parent<T>>{ ... } public class Child extends Parent<Child>{ ... }
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
class Parent<T extends Parent<T>>
を文字通り解釈すると以下のようになりますね。
- Parent<T>はT型をパラメーターとする型
- ただしT型として指定できるのはParent<T>の派生クラス
質問者さんの疑問は「型パラメータに自分自身が派生であるような型をなぜ限定したいのだろう」ということだと思いますが、それは同種の型が繋がりをもったような構造の場合などで有用になります。
例として次の2つのコードを比べてみて下さい。
java
1//型パラメーターを使わない例 2class Node { 3 Node next; 4 5 Node(Node next) { this.next = next; } 6 // 末尾のノードを返す 7 Node tail() { 8 for (Node n = this; ; n = n.next) 9 if (n.next != null) return n; 10 } 11} 12class MyNode extends Node { 13 int value; 14 MyNode(MyNode next) { super(next); } 15 // 末尾のノードの値を返す 16 int tailValue() { 17 // tailが返すのはNodeであってMyNodeではない。ゆえにキャストが必要 18 return ((MyNode)tail()).value; 19 } 20}
java
1//型パラメーターを使う例 2class Node<T extends Node<T>> { 3 T next; 4 5 Node(T next) { this.next = next; } 6 // 末尾のノードを返す 7 T tail() { 8 for (T n = this; ; n = n.next) 9 if (n.next != null) return n; 10 } 11} 12class MyNode extends Node<MyNode> { 13 int value; 14 MyNode(MyNode next) { super(next); } 15 // 末尾のノードの値を返す 16 int tailValue() { 17 // tailが返すのはMyNodeなので、キャストは不要 18 return tail().value; 19 } 20}
型パラメーターを使わない例ではNodeが提供するメソッドで返せるのはNode型にしかできません。一方で型パラメーターを使う例ではNodeが提供するメソッドで返せる型がT
(派生クラスで任意に指定できる)になるので、MyNodeクラスでNode#tail
が返すものをMyNode
クラスであると限定でき、不格好なキャストをせずにすみます。
普通Javaではキャストを極力せずにすむような設計が好まれます。なぜならキャストをしなくて済むにもかかわらずキャストを使うとそれだけプログラムの間違いがコンパイル時に検出できなくなるからです。実行してみて初めてバグに気づくよりはコンパイル時に間違いに気づけた方がよいという考え方です。
投稿2016/09/24 09:44
総合スコア18394
0
投稿2016/09/24 09:56
編集2016/09/24 09:57総合スコア740
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/09/24 14:06