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" 调用的方法。在树中,会有 类 Composite
和 Leaf
的对象。这些都继承自 Component
,但当然是不同的。 Composite
是一个容器对象,也是一个对象本身,而Leaf
只是一个对象。我想更改我的代码,以便仅当 first
是 Composite
的实例时才执行行 for(Component c : first.caseComponents)
,否则它会尝试迭代 Leaf
而不是可能的。如果 first
是 Composite
?
,我怎样才能做到只输入 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来表达是极不合适的。
代码:
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" 调用的方法。在树中,会有 类 Composite
和 Leaf
的对象。这些都继承自 Component
,但当然是不同的。 Composite
是一个容器对象,也是一个对象本身,而Leaf
只是一个对象。我想更改我的代码,以便仅当 first
是 Composite
的实例时才执行行 for(Component c : first.caseComponents)
,否则它会尝试迭代 Leaf
而不是可能的。如果 first
是 Composite
?
使用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来表达是极不合适的。