0

したがって、次のようなカスタムクラスがあります。

public class Cell {
    protected boolean wasActive;

    public Cell() {
    this.wasActive = false;
    }

    public boolean getPreviousActiveState() {
    return this.wasActive;
    }

    public void setPreviousActiveState(boolean previousActiveState) {
    this.wasActive = previousActiveState;
    }
}

ここで、上記の getPreviousActiveState() メソッドを呼び出す必要がある別のクラスを作成しています。

public class Synapse<Cell> {
    private Cell cell;

    // some other methods... like isConnected

    public boolean getPreviousActiveState() {
    this.cell.getPreviousActiveState; // <= CAN'T BE CALLED. WHY?

    }
}

問題は、クラスを宣言したという事実に関係していることを知っています:

public class Synapse<Cell> 

ただし、Synapse のみが Cell のサブクラスのみを含むことができるように、これを行いました。たとえば、Cell を拡張する VisionCell、AudioCell、Neuron クラスも実装しました。このジェネリックの使用は不必要でしたか? もしそうなら、いつジェネリックを使うべきですか?ありがとう!

4

1 に答える 1

3

means と呼ばれる型パラメーターを定義するとCell、混乱が生じます。名前を に変更しT、不足している括弧のペアをthis.cell.getPreviousActiveState呼び出しに追加します。

class Synapse<T> {
  private T cell;

  // some other methods... like isConnected

  public boolean getPreviousActiveState() {
    return this.cell.getPreviousActiveState(); // <= CAN'T BE CALLED. WHY?
  }
}

現在表示されるエラーは次のとおりです。 The method getPreviousActiveState() is undefined for the type T

これは、コードのどこにも型パラメーターTにメソッドがあることを保証していないことをコンパイラーが伝えるgetPreviousActiveState()方法です。Java ジェネリックは C++ テンプレートとは異なることに注意してください。ジェネリック クラスは、呼び出し元サイトとは無関係に 1 回コンパイルされます。言い換えれば、コンパイラはこのクラスを特定のインスタンス化に対してチェックするのではなく、それ自体が意味を成すかどうかをチェックします。

を保証するためにT必要なのは、このメソッドを定義getPreviousActiveState()する上限を指定することだけです。Tそれ自体を使用できますCell

class Synapse<T extends Cell> {
  private T cell;

  // some other methods... like isConnected

  public boolean getPreviousActiveState() {
    return this.cell.getPreviousActiveState(); // <= Compiles!
  }
}

もちろん、関心のあるメソッドを定義するインターフェースを導入し、このインターフェースを上限として使用することで、コードをより用途の広いものにすることができます。また、Cellこのインターフェースを実装する必要があります。

interface ActiveStateProvider {
  public boolean getPreviousActiveState();  
}

class Cell implements ActiveStateProvider {
  protected boolean wasActive;

  public Cell() {
    this.wasActive = false;
  }

  public boolean getPreviousActiveState() {
    return this.wasActive;
  }

  public void setPreviousActiveState(boolean previousActiveState) {
    this.wasActive = previousActiveState;
  }
}

class Synapse<T extends ActiveStateProvider> {
  private T cell;

  // some other methods... like isConnected

  public boolean getPreviousActiveState() {
    return this.cell.getPreviousActiveState(); // <= Compiles!
  }
}
于 2013-07-20T21:18:33.153 に答える