Java では、型パラメータの境界を定義するためにextends
" " ではなく常に " " を使用する特別な理由があるのだろうか。implements
例:
public interface C {}
public class A<B implements C>{}
は禁止されていますが、
public class A<B extends C>{}
正しい。その理由は何ですか?
Java では、型パラメータの境界を定義するためにextends
" " ではなく常に " " を使用する特別な理由があるのだろうか。implements
例:
public interface C {}
public class A<B implements C>{}
は禁止されていますが、
public class A<B extends C>{}
正しい。その理由は何ですか?
クラスが「実装する」か「拡張する」かの間に、一般的な制約言語に意味的な違いはありません。制約の可能性は 'extends' と 'super' です。つまり、このクラスを他のクラスに割り当て可能にするか (extends)、このクラスをそのクラスから割り当て可能にするか (super) です。
答えはここにあります :
制限付きの型パラメーターを宣言するには、型パラメーターの名前、
extends
キーワード、上限[…] の順に並べます。このコンテキストでは、 extends は一般的な意味でextends
(クラスのように) またはimplements
(インターフェイスのように) のいずれかを意味することに注意してください。
これで少し混乱しますが、オラクルはそれを認識しています。
おそらく、両方の側 (B と C) に関連するのは型だけであり、実装ではないためです。あなたの例では
public class A<B extends C>{}
B もインターフェイスにすることができます。「extends」は、サブインターフェースとサブクラスを定義するために使用されます。
interface IntfSub extends IntfSuper {}
class ClzSub extends ClzSuper {}
私は通常、「Sub extends Super」を「SubはSuperに似ていますが、追加の機能を備えている」、「Clz は Intf を実装している」を「Clzは Intf の実現である」と考えています。あなたの例では、これは一致します: BはCに似ていますが、追加の機能があります。ここで重要なのは機能であり、実現ではありません。
基本型がジェネリック パラメーターである可能性があるため、実際の型はクラスのインターフェイスである可能性があります。検討:
class MyGen<T, U extends T> {
また、クライアント コードの観点からは、インターフェイスはクラスとほとんど区別できませんが、サブタイプの場合は重要です。
extends が許可されている場所と、おそらく必要なもののより複雑な例を次に示します。
public class A<T1 extends Comparable<T1>>
私たちは慣れている
class ClassTypeA implements InterfaceTypeA {}
class ClassTypeB extends ClassTypeA {}
そして、これらの規則からのわずかな逸脱も、私たちを大いに混乱させます。
型バインドの構文は次のように定義されます。
TypeBound:
extends TypeVariable
extends ClassOrInterfaceType {AdditionalBound}
( JLS 12 > 4.4. 型変数 >TypeBound
)
implements
変更する場合は、必ずケースを追加します
TypeBound:
extends TypeVariable
extends ClassType {AdditionalBound}
implements InterfaceType {AdditionalBound}
そして、2 つの同じように処理された節で終わる
ClassOrInterfaceType:
ClassType
InterfaceType
( JLS 12 > 4.3. 参照型と値 >ClassOrInterfaceType
)
ただし、 も処理する必要がありimplements
、事態がさらに複雑になります。
andextends ClassOrInterfaceType
の代わりに が使用される主な理由は、複雑な概念の中で物事を単純に保つためだと思います。問題は、両方をカバーする適切な言葉がなく、どちらかを紹介したくないことです.extends ClassType
implements InterfaceType
extends
implements
<T is ClassTypeA>
<T is InterfaceTypeA>
extends
インターフェースと一緒に使用すると多少混乱しますが、より広い用語であり、両方のケースを説明するために使用できます。型を拡張するという概念に注意を向けるようにしてください(クラスを拡張せず、インターフェースを実装しません)。型パラメーターを別の型で制限すると、その型が実際に何であるかは問題になりません。それがその上限であり、そのスーパータイプであることだけが重要です。