【问题标题】:Java - How to check if an object is an instance of a class in the class definitionJava - 如何检查对象是否是类定义中的类的实例
【发布时间】:2015-07-24 01:13:42
【问题描述】:

代码:

public class Composite extends Component implements Iterable<Component>{

    private List<Component> caseComponents = new ArrayList<Component>();


    @Override
    public Iterator<Component> iterator(){
        return new CompIterator();
    }



    private class CompIterator implements Iterator{
        int index = 0;

        @Override
        public boolean hasNext(){
            if(index<caseComponents.size()){
                return true;
            }
            return false;
        }

        @Override
        public Object next() {
            if(this.hasNext()){
                return caseComponents.get(index++);
            }
            return null;
        }
    }


    public String breadthFirst() {
        Queue<Component> q = new LinkedList<Component>();
        StringBuilder stringRep = new StringBuilder();
        q.add(this);

        while(q.element()!=null){
            Component first = q.remove();
            System.out.println(first.name);

            for(Component c : first.caseComponents){
                q.add(c);
            }
        }
    }

我正在尝试对复合设计模式的树进行广度优先打印。我已经声明了一个应该由树的“根”调用的方法。在树中,将有 CompositeLeaf 类的对象。它们都继承自Component,但当然是不同的。 Composite 是一个容器对象,也是一个对象本身,而Leaf 只是一个对象。我想更改我的代码,以便仅当firstComposite 的实例时才执行for(Component c : first.caseComponents) 行,否则它将尝试迭代Leaf,这是不可能的。我怎样才能做到只有当firstComposite时才输入for语句?

【问题讨论】:

    标签: java iterator composite iterable


    【解决方案1】:

    使用instanceof 来检查comp 是否是Composite 的实例。

    例如:

    if (comp instanceof Composite) { 
        //do something
    }
    

    【讨论】:

      【解决方案2】:

      您可以重构代码以应用访问者模式:

      public interface ComponentVisitor {
        void visitComposite(Composite composite);
        void visitLeaf(Leaf leaf);
      }
      
      public interface Component {
        void acceptVisitor(ComponentVisitor visitor);
      }
      
      public class Composite implements Component {
        @Override public void acceptVisitor(ComponentVisitor visitor) {
          visitor.visitComposite(this);
        }
      }
      
      public class Leaf implements Component {
        @Override public void acceptVisitor(ComponentVisitor visitor) {
          visitor.visitLeaf(this);
        }
      }
      

      访问者模式是运行时检查和强制转换的编译时安全替代方案,还可以帮助对代码进行静态分析。程序代码如下所示

      public class ComponentPrinter implements ComponentVisitor {
      
        public void printComponent(Component component) {
          component.acceptVisitor(this);
        }
      
        @Override public void visitComposite(Composite composite) {
          for (Component child : composite) {
            printComponent(component);
          }
        }
      
        @Override public void visitLeaf(Leaf leaf) {
          System.out.println("Found leaf: " + leaf);
        }
      }
      

      顺便提一下,demo程序是深度优先打印的,当然你也可以使用队列来累积组件,然后再打印广度优先

      【讨论】:

        【解决方案3】:

        我会完全摆脱 Composite 和 Leaf,并引入一个可以有子节点的 Node 类。如果是,它是一个中间节点;如果不是,那是一片叶子。由于这个属性可以随时改变,所以用不同的类来表达是非常不合适的。

        【讨论】:

        • 这取决于应用程序上下文。例如,GUI 组件可以是 Layout(有子级)或 Button(叶子)。并且按钮无法转换为布局
        • 我同意你的观点 EJP。不幸的是,我无法控制老师交给我的任务。
        • @Raffaele 实际上是一个容器,但可以说这也是糟糕的设计。
        猜你喜欢
        • 2015-08-03
        • 2013-01-14
        • 1970-01-01
        • 2013-05-17
        • 2021-11-20
        • 2017-12-06
        • 1970-01-01
        相关资源
        最近更新 更多