Java - 如何检查对象是否是 class 定义中的 class 的实例

Java - How to check if an object is an instance of a class in the class definition

代码:

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

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

,我怎样才能做到只输入 for 语句

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

例如:

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

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

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程序做的是深度优先打印,当然你也可以用队列来累积分量,然后广度优先打印

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