4

まず第一に、私は言語理論についてほとんど何も知りませんし、Java 以外の他の言語はほとんど知りませんが、私はクールだと思うアイデアを持っていまし

.言語 x が何年もの間それを持っていた
方法 c: 頭がおかしい
d: 上記のすべて

このアイデアは、構成にコードの再利用を同じように容易にextendsします。

したがって、次のようなクラスがあるとします。

パブリック インターフェイス A {  
    public void methodInA();  
}

そして、次のようなクラスがありました:

公開クラス B {  
    プライベート合成 A;
    パブリックB() {
        // コンストラクター内で A を構築します
    }
}

その後、これを行うことができます:

B myB = 新しい B();
myB.methodInA();

B のクラスに委任を追加する必要はありません。ただし、継承と同じこともできます。つまり、次のようになります。

@オーバーライド
public void methodInA(){
    // B 独自の委譲メソッド
}

欠点は次のとおりです。

  • メソッドはソース コードに隠されているため、呼び出し元がわかりにくくなっていますが、これは次の場合にも当てはまります。extends
  • 構成されたフィールドが同じメソッド シグネチャを共有する場合、競合を解決する必要があります (競合するインターフェイスはこれをどのように解決しますか?)
  • 同じタイプの複数の合成フィールドが必要な場合は、どのフィールドに委譲するかについて明らかな競合が発生します。
  • おそらく私が考えたことのない他の100のこと

私が言うように、私は明らかに言語理論家ではありませんし、それについて何年も考えたこともありません。アイデアが頭に浮かんだだけで、自分がどれほど間違っているかを知りたいと思いました. ちょっとクールだと思います。

4

6 に答える 6

1

クールに聞こえますが、恐ろしい言語構造になっていると思います。同じクラスの複数の「構成」を宣言すると明らかに問題がありますが、それを禁止したとしても、呼び出しが (異なる) 構成されたクラスの複数のメソッドに一致する場合はどうなりますか? どちらがメイン クラスで呼び出されたかを指定する必要があり、そのための追加の構文が必要になります。クラスに public メンバーがいる場合、状況はさらに悪化します。

コンポジションは、多重継承の問題を防ぐために使用されます。このような構成を許可することは、少なくともどのメソッドを呼び出すかを解決するという点では、効果的に多重継承を許可しています。Java の重要な設計上の決定は (正当な理由から) 多重継承を禁止することだったので、これが Java に導入される可能性は低いと思います。

于 2008-10-31T17:46:19.060 に答える
0

クラスがこの機能を使用して単一のクラスを構成できるように制限すると、多少便利になり、議論されている多くの頭痛の種を回避できると思います。

個人的には具象クラスの継承が嫌いです。私は Bloch の「Effective Java」の項目 14 、「継承より構成を優先する」の大きな支持者です。このようなことで、彼がその項目で推奨するイディオムを実装するのが少し簡単になると思います.

正直なところ、自分が何をしているのかを本当に知っていれば、これを処理するコンパイラ注釈を書くことができるに違いありません。したがって、IBar インターフェイスを実装するクラス Bar があると仮定すると、クラスは次のようになります。

public class Foo {

  @Delegate(IBar.class)
  private Bar bar;

  // initialize bar via constructor or setter
}

次に、コンパイル中に Foo を作成して IBar を実装することができ、Foo によってまだ実装されていないそのインターフェイスのメソッドは、最終的に次のように生成されます。

public Baz method1(Qux val) {
  return bar.method1(val);
}

前述のように、クラスごとに 1 つのフィールドのみがこの注釈を使用できるという制限を作成する必要があります。複数のフィールドにこの注釈がある場合、おそらくコンパイル エラーをスローする必要があります。あるいは、何らかの優先順位モデルを渡されたパラメーターにエンコードする方法を考え出すこともできます。

これを書き出すと、ちょっとクールに思えます。来週も遊んでみようかな。私が何かを理解することができれば、これを更新します。

于 2008-10-31T18:17:56.750 に答える
0

一部の言語で「Mixins」と呼ばれるものと、Perl 5 Moose OO システムで「ロール」と呼ばれるものを確認してください。

于 2008-10-31T18:12:00.740 に答える
0

ただし、これを行うことに明確な利点があるかどうかはわかりません。私はあなたが言っている点を理解しています。現時点では、A でメソッドを呼び出すには myB.getAInstance().methodInA() が必要ですが、それを myB.methodInA() にしたいと考えています。

しかし、A のインスタンスが複数ある場合はどうなるでしょうか。メソッド呼び出しはどのように解決されますか? 多くの場合、コンポジションは 1 対多の関連付けを意味するため、B には多くの A インスタンスがあります。その後どうなりますか?

記載されている欠点に同意します。価値がある以上に混乱を招くだけかもしれません。

于 2008-10-31T17:34:44.527 に答える
-1

考慮すべき構成集約の違いもあります。コンパイラは、「is-a」または「has-a」の関係を意味するかどうかをどのように認識しますか?

  • オブジェクトグラフ全体がガベージコレクションの対象になりますか、それともグラフの先頭のみになりますか?

いくつかのORMマッピングツールとそれらの周りのフレームワークは、永続オブジェクト間の関係を提供し、いくつかはカスケード削除(構成用)も提供しますbelongsTohas-many私はあなたが探している単純な構文糖衣を提供する片手で知っていません。

実際、考え直してみると、GroovyのMetaClassとMetaProgrammingのイディオムは、「自動魔法」の委任で非常によく似たものを提供する可能性があります。

于 2008-10-31T17:48:06.200 に答える
-1

C ++では多重継承が許可されています。私はそれが異なることを知っていますが、それは同じ思考プロセスに沿っています。Javaは、多重継承を許可しないように設計されているため、混乱が少なくなり、バグやエクスプロイトが発生します。

あなたが提案したことは、Javaの原則と直接矛盾しています。

そうは言っても、それはかっこいいでしょう(必ずしも役立つとは限りません)。私はC++から切り替えたJavaプログラマーです。私は自分の間違いを犯すことができるのが好きです。

于 2008-10-31T17:52:43.307 に答える