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 的一个子类。例如,我还实现了一个 VisionCell、AudioCell 和 Neuron 类,它们都扩展了 Cell。这种使用泛型是不必要的吗?如果是这样,我应该什么时候使用泛型?谢谢!

4

1 回答 1

3

定义一个称为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++ 模板不同:泛型类独立于任何调用站点编译一次。换句话说:编译器不会检查这个类是否适用于任何特定的实例化,而是会检查它本身是否有意义。

为了保证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 回答