6

私は、ロールプログラミングに役立つJavaの「拡張機能」を書いています(まあ、完成しています)。
私は自分のコードをjavaccでJavaコードに変換します。私のコンパイラは、宣言されたすべてのクラスにいくつかのコードを追加します。より明確にするための例を次に示します。

MyClass extends String implements ObjectWithRoles { //implements... is added
    /*Added by me */
    public setRole(...){...}
    public ...
    /*Ends of stuff added*/
    ...//myClass stuff
}

宣言するすべての単一クラスにImplements..と必要なメソッドを追加します。かなりラフですね。

1つのクラスでメソッドを記述し、すべてのクラスがそれを拡張する方がよいでしょう。しかし..クラスがすでに別のクラスを拡張している場合(例のように)?

プログラマーがJavaよりもはるかに多くのこと、いくつかの新しい予約語とその使用法を知っている必要がないため、ロールを管理する一種のラッパーを作成したくありません。

私の考えはjava.lang.Object..を拡張することでしたが、それはできません。(右?)
他のアイデア?

私はここで新しいですが、私はこのサイトをフォローしているので、読んでくれてありがとう、そしてあなたが与えるすべての答え!(私は英語をお詫びします、私はイタリア人です)

4

6 に答える 6

6

そのような拡張機能がどのように機能するかを調査したい「研究」プロジェクトのようなものである場合は、Objectクラスの独自の実装を提供できます。既存のオブジェクト実装をコピーし、setRoleメソッドなどを追加-Xbootclasspath:.:/usr/lib/jvm/java-6-sun/jre/lib/rt.jarして、javaコマンドにパラメーターとして指定するだけです。.(実際に調べる前に、でapiクラスを探しrt.jarます。)

于 2010-05-18T08:35:18.677 に答える
3
  • あなたは拡張することができますObject-すべてのクラスがそれを拡張します。
  • 多重継承のようなものが必要なようです-Javaにはそのようなものはありません
  • 機能を追加したい場合は、オブジェクトコンポジションを使用してください。つまり、

    YourClass extends Whatever implements ObjectWithRoles {
        private RoleHandler roleHandler;
        public RoleHandler getRoleHandler() {..} // defined by the interface
    }
    

そして、すべてのメソッドがに配置されますRoleHandler

于 2010-05-18T08:29:33.477 に答える
3

この問題を解決するには、継承ではなく構成を使用することを検討する必要があります。そうすれば、継承時に「ワンショット」を使い切ることなく、必要な機能を提供できます。

たとえば、JDKは、sとsの起動PropertyChangeSupportを管理するために使用できるクラスを提供します。を起動するクラスを作成する場合は、インスタンス変数を埋め込み、すべてのメソッド呼び出しをそれに委任することができます。これにより、継承の必要がなくなり、既存のクラス階層を新しい機能で補完できるようになります。PropertyChangeListenerPropertyChangeEventPropertyChangeEventPropertyChangeSupport

public class MyClass extends MySuperClass {
  private final PropertyChangeSupport support;

  public MyClass() {
    this.support = new PropertyChangeSupport(this);
  }

  public void addPropertyChangeListener(PropertyChangeListener l) {
    support.addPropertyChangeListener(l);
  }

  protected void firePropertyChangeEvent() {
    PropertyChangeEvent evt = new ...
    support.firePropertyChangeEvent(evt);
  }
}
于 2010-05-18T08:29:55.910 に答える
2

すべてのオブジェクトに役割を追加することについて話している場合は、注釈ベースのソリューションも検討します。クラスに @Role("User") のような注釈を付けます。別のクラスでは、そのロール値を抽出して使用できます。

実行時に保持する注釈が必要だと思います。リフレクションを使用して注釈が存在するかどうかを実行時に確認し、getAnnotationを使用してその注釈を取得できます。これは、すべてのクラスを自動的に拡張するよりもずっときれいだと思います。

まさにそのようなソリューションを使用するフレームワークがいくつかあると思うので、どこかにサンプルコードがあるはずです。

于 2010-05-18T08:44:01.363 に答える
1

あなたがしていることをしているなら、継承はおそらく正しいイディオムではありません。デコレータパターンを検討することをお勧めします。これにより、パラメータとして機能の少ない他のクラスを取り、それにいくつかの追加機能を追加して、既存の機能を既存のクラスに委任するクラスを構築します。実装が多くのデコレータに共通している場合は、その機能を、共有でき、すべてのデコレータに委任できるクラスに配置することを検討することをお勧めします。必要なものに応じて、多種多様なクラスで類似しているがまったく同じではないデコレータを作成するために、ダブルディスパッチまたはリフレクションが適切な場合があります。

また、コメントで指摘されているように、Stringは「final」と宣言されているため、拡張できません。したがって、オブジェクトを委任/装飾するソリューションを実際に検討する必要があります。たとえば、文字列をラップし、getString()またはtoString()を介して文字列へのアクセスを提供するが、Stringクラスの上に追加機能を追加するオブジェクトがあるとします。

一部のオブジェクトを追加の属性に関連付けるだけの場合は、マップHashMapなど)を使用します。

于 2010-05-18T08:35:03.077 に答える
1

あなたが本当にやりたいことは、モンキー パッチ、つまりコードを変更せずに既存のクラスの動作を変更することです。

残念ながら、Java はこれをサポートしておらず、代わりに使用できるミックスインなどもサポートしていません。そのため、Groovy のようなより動的な言語に切り替える気がない限り、コンポジションなどの洗練されていないソリューションを使用する必要があります。

于 2010-05-18T08:46:29.603 に答える