問題タブ [diamond-problem]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Java 8の抽象クラスとインターフェースの違いは何ですか?
Java では、抽象クラスとインターフェースの間に微妙ではあるが重要な違いがありました:デフォルトの実装です。抽象クラスはそれらを持つことができましたが、インターフェースはできませんでした。ただし、Java 8 ではインターフェースのデフォルト実装が導入されています。つまり、これはもはやインターフェースと抽象クラスの決定的な違いではありません。
それで、何ですか?
私が知る限り、残っている唯一の違い (おそらく内部の効率性の問題を除いて) は、抽象クラスが従来の Java の単一継承に従うのに対し、インターフェイスは複数の継承 (または必要に応じて複数の実装) を持つことができることです。これは私を別の質問に導きます-
新しい Java 8 インターフェースはダイヤモンドの問題をどのように回避しますか?
c++ - c ++ダイヤモンド継承コンストラクタ?
4番目のクラスのコンストラクターをどのように呼び出すべきか疑問に思っています。クラス A が基本クラスで、クラス B と C がそれを継承します。
4 番目のクラスがクラス B とクラス C の両方を継承するようになりました。クラス D のコンストラクターを呼び出すにはどうすればよいですか?
この方法で試してみましたが、「ClassB::ClassB()â の呼び出しに一致する関数がありません」というメッセージが表示されます
c++ - データ メンバを持たないダイヤモンド (多重継承)
通常のひし形パターンがあるとします。
A
基本クラスにはデータ メンバーがないことに注意してください。実際には、純粋な仮想メソッドを備えたインターフェイスにすぎません。
今私がする場合:
コンパイラは、2 つの A 基底クラスがあるため、キャストがあいまいであることを教えてくれます。
しかし、もし私がそうしたらどうしますか:
A
これで、基本クラスの 1 つへのポインターがあり、実行できますa->foo()
。
これは安全ですか?
私が知りたいのは、この二重アップキャストを実行して、仮想継承のオーバーヘッドなしでインターフェイスへのポインター (データメンバーなし) を持つことができるかどうかです。とにかくポインターをダウンキャストしたり、仮想メソッドを呼び出していない何かをしたりするつもりはありません。
これは 2 つの基本クラスを持つことを意味することはわかっていますが、メンバーがないので問題にならないのでしょうか。
EDIT
: インターフェイスを実装する方法を見つけるのに苦労しています。仮想継承を使用する必要があると思います。
クラスBuffer
(インターフェースクラス)と、BufferImplementation
そこから派生したクラスがあるとします。
ここで、 と インターフェイスの両方から派生する必要があるクラスを持つ別のインターフェイスIOBuffer
(他のインターフェイスから派生する) があるとします。Buffer
IOBufferImplementation
BufferImplementation
IOBuffer
前の例では、Buffer は A、BufferImplementation は B、IOBuffer は C、IOBufferImplementation は D です。
c++ - Doxygen にダイヤモンドの継承グラフを表示させる方法
Doxygen には、コードから継承グラフを生成する非常に優れた機能があります。ただし、共通のベースを持つクラスからの多重継承を使用すると、プロットには 2 つの別個の基本クラスが表示されます (基本クラスの周りの破線で示されるように、仮想継承を使用しているにもかかわらず)
次のような Doxygen プロットを作成するにはどうすればよいですか。. .
そうではありません:(仮想継承なしで起こるように)
c++ - 非 Diamond タイプでの仮想継承
クラスが同じ基本クラスから派生した 2 つのクラスを継承する場合に、ダイヤモンド問題のような問題が発生しない状況で仮想継承が役立つ理由を理解できません。
まだ役立つ(または必要な)場合に、誰かが例や説明を教えてくれませんか?
ありがとう:)
java - Java 8 のインターフェースに対する抽象クラスの設定
これで、Java 8 がインターフェイスにデフォルト メソッドと静的メソッドを導入したことがわかりました。インターフェースはもともと Java で導入され、多重継承で C++ で発生し たひし形の問題
を回避しました。
しかし、Java 8 でインターフェースにデフォルト メソッドが導入されたことに加えて、Java は、以前のバージョンでは回避されていたダイヤモンドの問題も導入しました。
デフォルトのメソッドは、強制的にオーバーライドする必要はありません。
ただし、インターフェイスを使用してひし形の問題が発生した場合、それらのインターフェイスを実装するクラスは、既定のメソッドをオーバーライドする 必要があります。
だから今、私は3つの質問を心に留めています:
- なぜデフォルトのメソッドが必要なのですか?
- インターフェイスにデフォルトのメソッドを持つ代わりに、クラス自体を介して複数の継承を行うことはできませんか?
- とにかくJava 8でそれを導入しなければならなかった場合、以前のバージョンでダイヤモンドの問題を回避する必要は何でしたか?
良い説明や説明へのリンクはありますか?
PS私は、これに関する良い記事を含むリンクをインターネット上で見つけられませんでした.
彼らが言ったのは、抽象クラスがより具体性を与えるということだけです。
同様に、抽象クラスはコンストラクターを持つことができますが、インターフェイスはできません。
繰り返しになりますが、抽象クラスがより具体的であり、コンストラクターを持つことができ、
Java がひし形の問題を導入した場合、なぜ今インターフェースを持たなければならないのでしょうか? 抽象クラスは、多重継承のスタンドアロンとして十分ではないでしょうか?
c++ - ひし形の継承が 2 回派生しました - コンストラクターのパラメーターが異なります - 仮想継承が指定されたベースが見つかりません
タイトルで問題を簡潔に説明するのに苦労したので、問題を理解し、より良いタイトルがある場合はお勧めします.
私の問題を可能な限り小さくしたバージョンを作成しました。その結果、すべての関数がインラインで定義されています。申し訳ありませんが、実際のコードはこのようではありません。
これは私の構造です:
上記のように、オブジェクトが有効かどうかを単純に追跡するインターフェイス + 実装...エンジン/システム内のすべてのオブジェクトがこの単一のオブジェクトから派生すると想像してください。
これで、数値を格納して出力するだけの仮想クラスができました。オブジェクトから派生します。これで「ダイヤモンド」は完成です。
ここで、基本クラスから派生します。この派生クラスについて注意すべきことは、基本クラス (int 値) と同じコンストラクター パラメーターがあることです。
最後に、この派生クラスから派生させます。ただし、このクラスにはコンストラクタ パラメータがないことに注意してください。代わりに、このクラスは、この例では値が 15 であることを内部的に認識している必要があります。
私が期待しているのは、派生 2 をインスタンス化すると、値 15 で派生 1 が構築され、オブジェクトを介して渡されることです。私は次のことをしたいと思います:
しかし、これを試みると、次のようになります。
空の base::base コンストラクターを追加すると、予想どおり m_value が未定義になります (ただし、とにかく試しました)。
明らかな何かが欠けているようです...、誰かがそれを強調できますか?