我正在为一块电路板建模,我想尽可能地使它变得通用,我也想不惜一切代价避免投射,因为它是一种不好的做法!
此外,我的代码现在完全正常工作,但我知道,一旦我开始使用Cell类并扩展它,它就会出现问题!
Cell.java
public class Cell<T> {
private t value;
public Cell(T value) {
this.value = value;
}
// setters and getters
}
Board.java
import java.lang.reflect.Array;
public abstract class Board<T, E extends Cell<T>> {
protected E[][] cells;
protected Board(Class<? extends E> c) {
cells = (E[][])Array.newInstance(c, 6, 7);
}
protected void resetBoard(T resteVal) {
for (int i = 0; i < cells.length; i++)
for (int j = 0; j < cells[i].length; j++)
cells[i][j]= (E) new Cell<T>(); //HERE IS THE QUESTION
}
}
Game.java
public interface Game {
boolean islegalMove();
boolean isWin();
void move();
void resetGame();
void getScore();
}
Connect4.java
public class Connect4<E extends Cell<Integer>> extends Board<Integer,E> implements Game {
public Connect4(Class<? extends E> c) {
super(c);
}
// override methods
}
答案 0 :(得分:1)
将此protected E[][] cells;
替换为protected Cell<T>[][] cells;
public abstract class Board<T, E extends Cell<T>> {
protected Cell<T>[][] cells;
@SuppressWarnings("unchecked")
public Board(Class<? extends E> c) {
cells = (E[][])Array.newInstance(c, 6, 7);
}
protected void resetBoard(T resteVal) {
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) {
Cell<T> cell = new Cell<T>();
cell.setValue(resteVal);
cells[i][j] = cell; //HERE IS MY REPLACEMENT
}
}
}
}
答案 1 :(得分:1)
我认为问题出在架构上。
您已定义Board
类(例如,它可以是可扩展的)。
然后定义一个抽象Cell
,它可以使用自定义public abstract class Board<T, E extends Cell<T>> {
// why do not use T[][] cells instead?
protected final E[][] cells;
protected Board(E[][] cells) {
this.cells = cells;
}
// we hole Cell instances inside this class, so no need to create new ones
protected void resetBoard(T resetVal) {
for (int i = 0; i < cells.length; i++)
for (int j = 0; j < cells[i].length; j++)
cells[i][j].setValue(resetVal);
}
}
。
public final class MagicBoard<T> extends Board<T, MagicBoard.MagicCell<T>> {
public MagicBoard(Supplier<MagicCell<T>> supplier) {
//noinspection rawtypes,unchecked
super(new MagicCell[6][7]);
}
public static final class MagicCell<T> extends Cell<T> { }
}
最后,我们可以使用具体的单元格实例来打击具体主板。
Board
恢复:
抽象类Supplier
不应该关于具体的单元格实例创建。最大值,它可以接受来自子类的Cell
将此工作委托给具体的类'MagicBoard'(只有这个类知道应该创建什么类型的Cell
。)
尽量避免无用的Board
实例创建。如果您将其保留在Cell
内并且不在其外部共享,则重复使用它。只需重置该值。
问题!我不知道整个代码,但如果您的Cell
只包含一个值,则可以避免使用protected final T[][] cells;
并使用{{1}相反(我认为,Board
应包含使用Cell
的所有逻辑,但单元本身不应该非常聪明 - 只需保持简单的值)。但这只是我的意见。