次のような言語は存在しますか?
- 静的に (そして強く) 型付けされている
- ジェネリック (テンプレート) をサポート
- トレイト / 多重継承 / インターフェイス委譲をサポート
- 関数のオーバーロードを許可します (継承されたメンバーも)
基本的に、疑似コードでは、これが必要です:
class Template<SomeType> { void function(SomeType i) {} }
class Composed extends Template<int>, Template<double> { };
Composed composed;
composed.function(3); //calls function(int)
composed.function(2.5); //calls function(double)
ウィキ リストhttp://en.wikipedia.org/wiki/Multiple_inheritance#Implementationsから、次のプログラミング言語でコードを記述しようとしました (Kotlin、Ceylon などの最新の未公開バージョン 1.0 (2013) 言語も含めました)。
- C++はほぼ可能ですが、合成変数のオーバーロードされた関数を解決できません
- Scalaコンパイル エラー: トレイトが 2 回継承されました。間接継承でだまされても、エラーが発生します。Scala での複数のジェネリック mixin 継承に関する他の人の質問も参照してください。
- Eiffelコンパイル エラー: 関数のオーバーロードがありません
- Ceylonトレイトは変数を持つことができません (保護されたメンバーがないため、派生クラスにデータを格納するためのトリックはありません。Ceylon のトレイトは役に立ちません)
- Fantomジェネリック/テンプレートなし
- Kotlinコンパイル エラー: スーパータイプが 2 回表示されます。委任はユニークに見えますが、委任された保護されたメンバーにも変数にもアクセスできないため、役に立ちません。
- 関数のオーバーロードを防いでください。特性はデータを保存できません。特性はメソッドを定義することはできません (本文を含む) - 問題は現在取り組んでいます。
- OCamlコンパイル エラー: 関数のオーバーロードがありません。また、関数のパラメーターの型をチェックしなかったので、実際にはどのように「静的に型付けされた」のでしょうか?!
- Curlコンパイル エラー: 関数のオーバーロードがありません。また、呼び出されない限り関数本体をチェックしないため、実際にどのように「静的に型付け」されているのでしょうか? それはまったくコンパイルされていますか、それとも解釈されていますか?!
- Gosuは悪い冗談です。まったく使用できません。1 つのメソッドで単純なインターフェイスを記述および実装することはできません (エラー: ClassFormatError: Illegal field modifiers)。この言語を実際に使用しているのは誰ですか?!
ところで、リスナーのJavaサポートを別のクラスに入れようとしたときに、この問題を考えました(多くのクラスには、 List<ListenerType> ... addListener(...) ... removeListener(...) があります) )
C++はほとんど動作します:
template <typename T>
class Template { public: void function(T i) {} };
class Composed : public Template<int>, public Template<double> { };
Composed composed;
composed.Template<int>::function(3); //i want: composed.function(3);
((Template<double>&)composed).function(2.5); //i want: composed.function(2.5);
編集: C++ では、問題は継承関数の非表示です。派生クラスで同じ名前だが異なるシグネチャを持つ関数および派生クラス で オーバーライドされた関数が基本クラスの他のオーバーロードを隠すのはなぜですか?も参照 してください。
編集 2: C++ では、テンプレートと部分的な特殊化を使用して、トレイトをより簡単に使用できるようにするための汚いトリックの可能性があります。
#include <iostream>
#include <typeinfo>
class Void { };
template <class A, class B> class CleverTrait;
template <class A, class B> class CleverTrait;
template <class A> class CleverTrait<A, Void>
{
public:
void function(A arg) { std::cout << "Hello for type " << typeid(A).name() << std::endl; }
};
template <class A, class B> class CleverTrait<A, CleverTrait<B, Void> > : public CleverTrait<B, Void>
{
public:
using CleverTrait<B, Void>::function;
void function(A arg) { std::cout << "Hello for type " << typeid(A).name() << std::endl; }
};
class ComposedByClever : public CleverTrait<double, CleverTrait<int, Void> > { };
int main()
{
ComposedByClever composedByClever;
composedByClever.function(5);
composedByClever.function(2.3);
return 0;
}
これは、C++ のこの特定の例が機能することを意味しますが、無関係な特性が関数名を共有している場合、C++ ですべての関数を継承して使用する方法はありません。
編集 3: ミックスインをサポートするプログラミング言語もチェックする必要があります: http://en.wikipedia.org/wiki/Mixins#Programming_languages_that_use_mixins
- Dは機能しますが、文字列操作 mixin を介してのみ機能するため、そのような場合はリファクタリングが壊れます:
mixin(GenerateSomething!("IfClassNameHereManualRenaming"));
編集 4: 「ごす」言語のコメントを追加しました。
編集 5: Gosu プログラミング言語には、インターフェイスが壊れている問題を修正した更新 0.10.2 があります。ただし、ジェネリックと委任を具体化したと主張していても、委任 + 具体化されたジェネリックは機能しません。