如何摆脱类型转换?
How to get rid of typecasting?
我有一个胖接口:
public interface ISolver {
void solve();
String printMsgs();
boolean hasSolution();
int getLeaderId();
void add(Agent agent);
void add(int item);
void add(String item);
void addAll(Agent[] data);
void addAll(int[] data);
void addAll(String[] data);
public void initiateStartState();
Agent next();
boolean hasNext();
public List<Integer> getLeftSenders();
public List<Integer> getRightSenders();
public List<Integer> getCurrentLeaders();
Agent get(int idx);
}
有两个class继承了这个接口:
public class OneDirectSolver extends Solver{
// some code..
}
public class BiDirectSolver extends Solver{
// some code..
}
Class BiDirectSolver
使用了 ISolver
中声明的所有方法,但 OneDirectSolver
只使用了少数方法。我想遵循接口隔离原则。所以,我在 ISolver
中只留下了常用的方法。特定于 BiDirectSolver
的方法我移动到另一个扩展 ISolver
的接口
public interface ISolver {
void solve();
String printMsgs();
boolean hasSolution();
int getLeaderId();
void add(Agent agent);
void add(int item);
void add(String item);
void addAll(Agent[] data);
void addAll(int[] data);
void addAll(String[] data);
public void initiateStartState();
Agent next();
boolean hasNext();
}
public interface BiDirectSolvable extends ISolver {
public List<Integer> getLeftSenders();
public List<Integer> getRightSenders();
public List<Integer> getCurrentLeaders();
Agent get(int idx);
}
但是现在我遇到了另一个问题。我试着描述一下。所以,我有 2 个 BiDirectSolver
和 OneDirectSolver
:
的客户
public class OneDirectPanel extends MyAbstractPanel {
private OneDirectSolvable solver;
public void setSolver(OneDirectSolver solver) {
this.solver = solver;
}
//some code..
}
public class BiDirectPanel extends MyAbstractPanel {
private BiDirectSolvable solver;
public void setSolver(BiDirectSolvable solver) {
this.solver = solver;
}
// some code
}
现在我想展示我的主要 class 片段,我在其中创建了 OneDirectPanel、BiDirectPanel 和 ISolver 的实例:
public class GUI {
private ISolver solver;
private MyAbstractPanel panelWithPicture;
// a lot of code..
if (comboBoxForMode.getSelectedItem().equals("one direct")) {
solver = new OneDirectSolver();
panelWithPicture = new OneDirectPanel();
panelWithPicture.setSolver((OneDirectSolver)solver);
} else {
solver = new BiDirectSolver();
panelWithPicture = new BiDirectPanel();
panelWithPicture.setSolver((BiDirectSolvable)solver);
}
}
我只看到一个解决方案:
if (comboBoxForMode.getSelectedItem().equals("one direct")) {
OneDirectSolver solver = new OneDirectSolver();
panelWithPicture = new OneDirectPanel();
panelWithPicture.setSolver(solver);
} else {
BiDirectSolvable solver = new BiDirectSolver();
panelWithPicture = new BiDirectPanel();
panelWithPicture.setSolver(solver);
}
但这对我来说是不可能的,因为我必须在求解器创建后对其进行一些操作。我必须在所有情况下都这样做。所以,我在 main class 中进行。
因此,在 main class 中,我必须声明类型为 ISolver 的引用。
更新:
最重要的是,如果我在 main class 中对解算器执行某些操作,它一定会影响 OneDirectPanel 和 BiDirectPanel 中的解算器。
由于您暂时需要更具体的运行时类型,您可以在之后分配给 this.solver
:
private ISolver solver;
...
if (comboBoxForMode.getSelectedItem()
.equals("one direct")) {
OneDirectSolver solver = new OneDirectSolver();
panelWithPicture = new OneDirectPanel();
panelWithPicture.setSolver(solver);
this.solver = solver;
} else {
BiDirectSolvable solver = new BiDirectSolver();
panelWithPicture = new BiDirectPanel();
panelWithPicture.setSolver(solver);
this.solver = solver;
}
首先,您可以将求解器实例作为 MyAbstractPanel 的 属性。这样你就有了一个基础求解器 属性。
public abstract class MyAbstractPanel {
private ISolver solver;
public void setSolver(ISolver solver) {
this.solver = solver;
}
public void someWork(){
this.solver.someWork();
}
// implement this in child class
public abstract void doSomeSpecificWork();
}
//assign solver object
ISolver solver = new OneDirectSolver();
public class BiDirectPanel extends MyAbstractPanel {
public void doSomeSpecificWork(){
((OneDirectSolver)solver).doSomeSpecificWork();
}
// some code
}
因为 solver 是面板的一个属性,我认为在你的 main class 中保留 ISolver 类型的引用不是一个好习惯。希望这有帮助。
我有一个胖接口:
public interface ISolver {
void solve();
String printMsgs();
boolean hasSolution();
int getLeaderId();
void add(Agent agent);
void add(int item);
void add(String item);
void addAll(Agent[] data);
void addAll(int[] data);
void addAll(String[] data);
public void initiateStartState();
Agent next();
boolean hasNext();
public List<Integer> getLeftSenders();
public List<Integer> getRightSenders();
public List<Integer> getCurrentLeaders();
Agent get(int idx);
}
有两个class继承了这个接口:
public class OneDirectSolver extends Solver{
// some code..
}
public class BiDirectSolver extends Solver{
// some code..
}
Class BiDirectSolver
使用了 ISolver
中声明的所有方法,但 OneDirectSolver
只使用了少数方法。我想遵循接口隔离原则。所以,我在 ISolver
中只留下了常用的方法。特定于 BiDirectSolver
的方法我移动到另一个扩展 ISolver
public interface ISolver {
void solve();
String printMsgs();
boolean hasSolution();
int getLeaderId();
void add(Agent agent);
void add(int item);
void add(String item);
void addAll(Agent[] data);
void addAll(int[] data);
void addAll(String[] data);
public void initiateStartState();
Agent next();
boolean hasNext();
}
public interface BiDirectSolvable extends ISolver {
public List<Integer> getLeftSenders();
public List<Integer> getRightSenders();
public List<Integer> getCurrentLeaders();
Agent get(int idx);
}
但是现在我遇到了另一个问题。我试着描述一下。所以,我有 2 个 BiDirectSolver
和 OneDirectSolver
:
public class OneDirectPanel extends MyAbstractPanel {
private OneDirectSolvable solver;
public void setSolver(OneDirectSolver solver) {
this.solver = solver;
}
//some code..
}
public class BiDirectPanel extends MyAbstractPanel {
private BiDirectSolvable solver;
public void setSolver(BiDirectSolvable solver) {
this.solver = solver;
}
// some code
}
现在我想展示我的主要 class 片段,我在其中创建了 OneDirectPanel、BiDirectPanel 和 ISolver 的实例:
public class GUI {
private ISolver solver;
private MyAbstractPanel panelWithPicture;
// a lot of code..
if (comboBoxForMode.getSelectedItem().equals("one direct")) {
solver = new OneDirectSolver();
panelWithPicture = new OneDirectPanel();
panelWithPicture.setSolver((OneDirectSolver)solver);
} else {
solver = new BiDirectSolver();
panelWithPicture = new BiDirectPanel();
panelWithPicture.setSolver((BiDirectSolvable)solver);
}
}
我只看到一个解决方案:
if (comboBoxForMode.getSelectedItem().equals("one direct")) {
OneDirectSolver solver = new OneDirectSolver();
panelWithPicture = new OneDirectPanel();
panelWithPicture.setSolver(solver);
} else {
BiDirectSolvable solver = new BiDirectSolver();
panelWithPicture = new BiDirectPanel();
panelWithPicture.setSolver(solver);
}
但这对我来说是不可能的,因为我必须在求解器创建后对其进行一些操作。我必须在所有情况下都这样做。所以,我在 main class 中进行。 因此,在 main class 中,我必须声明类型为 ISolver 的引用。
更新: 最重要的是,如果我在 main class 中对解算器执行某些操作,它一定会影响 OneDirectPanel 和 BiDirectPanel 中的解算器。
由于您暂时需要更具体的运行时类型,您可以在之后分配给 this.solver
:
private ISolver solver;
...
if (comboBoxForMode.getSelectedItem()
.equals("one direct")) {
OneDirectSolver solver = new OneDirectSolver();
panelWithPicture = new OneDirectPanel();
panelWithPicture.setSolver(solver);
this.solver = solver;
} else {
BiDirectSolvable solver = new BiDirectSolver();
panelWithPicture = new BiDirectPanel();
panelWithPicture.setSolver(solver);
this.solver = solver;
}
首先,您可以将求解器实例作为 MyAbstractPanel 的 属性。这样你就有了一个基础求解器 属性。
public abstract class MyAbstractPanel {
private ISolver solver;
public void setSolver(ISolver solver) {
this.solver = solver;
}
public void someWork(){
this.solver.someWork();
}
// implement this in child class
public abstract void doSomeSpecificWork();
}
//assign solver object
ISolver solver = new OneDirectSolver();
public class BiDirectPanel extends MyAbstractPanel {
public void doSomeSpecificWork(){
((OneDirectSolver)solver).doSomeSpecificWork();
}
// some code
}
因为 solver 是面板的一个属性,我认为在你的 main class 中保留 ISolver 类型的引用不是一个好习惯。希望这有帮助。