2

具体的なサブクラスによって初期化する必要がある hashcode フィールドを持つ抽象 Java クラスがあります。初期化メソッドを抽象化することを考えていました。つまり、

abstract class A {
  protected int hashcode;
  // hashcode should be initialized in constructor
  protected A () { hashcode = setHashcode(); }
  abstract int setHashcode() {} // implemented by subclasses
}

しかし、残念なことに、異なるサブクラスは異なる数の引数を受け取る必要がありますsetHashcode。たとえば、クラス B はそのフィールドの 2 つを使用してハッシュコードを計算し、クラス C は 3 つ必要な場合がありますが、スーパーへの呼び出しは B のコンストラクターの最初の行でなければならないため、このスキーム動作しません。この問題を解決する別の方法/設計パターンがあるかどうか疑問に思っていますか?

4

4 に答える 4

2

しかし、スーパーへの呼び出しは B のコンストラクターの最初の行でなければならないため、このスキームは機能しません。

なぜうまくいかないのでしょうか?ハッシュ コードの計算をサブクラスの静的関数に入れると、作成済みのハッシュ コードをスーパークラスのコンストラクターに渡すことができます。

class BaseClass {
    private int hashCode;
    protected BaseClass(int hashCode) {this.hashCode = hashCode;}
}
class DerivedClass : BaseClass {
    private static int calcHash(String str) {
        return str.hashCode();
    }
    public DerivedClass(String s) {
        super(calcHash(str));
    }
}
于 2012-04-10T03:29:03.687 に答える
2

スーパークラスに値を格納する必要はありませんgetHashCode。サブクラスがオーバーライドする抽象を宣言するだけです。

public abstract class Base {
  protected abstract int getHashCode();
}

ストレージ要件に関係なく、メソッドの「意図」が保持されるため、これは優れています。

ちなみに、hashCodeは で既に定義されておりObject、サブクラスによってオーバーライドできます。ハッシュ コードの概念が提供されているものと異なる場合Objectは、名前を変更する必要があります。

于 2012-04-10T03:32:38.097 に答える
1

インターフェイスは初期化に適しているように思えるので、作成したサブクラスはインターフェイスの実装をオーバーロードできます。

于 2012-04-10T03:32:59.407 に答える
0

変化する:

abstract int setHashcode(); 

に:

abstract int getHashcode(Object...objects); 

また、サブクラスは、渡されたオブジェクトの数とタイプを検査する必要があります。

次に、次のような呼び出しを行います。

  hashcode = getHashcode(); 
  hashcode = getHashcode(o1); 
  hashcode = getHashcode(o1,o2); 
于 2012-04-10T03:44:19.987 に答える