简体   繁体   English

如何摆脱类型转换?

[英]How to get rid of typecasting?

I had a fat interface: 我的界面很胖:

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);    
}

Two classes inherit this interface: 有两个类继承了此接口:

public class OneDirectSolver extends Solver{
    // some code..
}

public class BiDirectSolver extends Solver{
    // some code..
}

Class BiDirectSolver uses all methods declared in ISolver , but OneDirectSolver uses only few methods. BiDirectSolver使用中声明的所有方法ISolver ,但OneDirectSolver只使用一些方法。 I want to follow Interface Segregation Principle. 我要遵循接口隔离原则。 So, I left in ISolver only common methods. 因此,我只在ISolver保留了常用方法。 Methods that specific for BiDirectSolver I move in another interface which extends ISolver 我专门针对BiDirectSolver方法在另一个扩展ISolver接口中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);
}

But now I have another problem. 但是现在我有另一个问题。 I try to describe it. 我试图形容它。 So, I have 2 clients of BiDirectSolver , and OneDirectSolver : 因此,我有2个BiDirectSolverOneDirectSolver客户端:

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
}

And now I want to show fragment of my main class in which I create instances of OneDirectPanel, BiDirectPanel and ISolver: 现在,我想展示我的主类的片段,在其中创建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);
    }
}

I see only one solution: 我只看到一种解决方案:

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);
}

But it is impossible to me because I must to do some actioms with solver after it was created. 但是对我来说这是不可能的,因为在创建求解器后,我必须对它进行一些调整。 I must to do it in all cases. 我必须在所有情况下都这样做。 So, I do it in main class. 所以,我在主班做。 So, in main class I must to declare reference with type ISolver. 因此,在主类中,我必须声明类型为ISolver的引用。

UPD: Most of all, if I do some actions with solver in main class it must affect on solvers in OneDirectPanel and BiDirectPanel. UPD:最重要的是,如果我对主类中的求解器执行某些操作,则它必须影响OneDirectPanel和BiDirectPanel中的求解器。

Since you temporarily need a more specific runtime type, you could assign to this.solver afterwards: 由于您暂时需要一个更特定的运行时类型,因此可以在之后分配给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;
            }

first of all you can put your solver instance as a property of MyAbstractPanel. 首先,您可以将求解器实例作为MyAbstractPanel的属性。 This way you have a base solver property. 这样,您就可以拥有基本的求解器属性。

    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

} }

since solver is a attribute of panel i think it is not a good practice to keep a referance of ISolver type in your main class. 由于求解器是面板的属性,因此我认为在主类中保留对ISolver类型的引用不是一种好习惯。 hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM