有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用instanceof根据子类类型对子类执行不同的操作?

我有一个抽象类A和两个子类B和C

在另一个类中,我有一个a的ie:list实例列表。当然,A的列表可以包含可以是B或C的实例的元素

如果实例是B,我想将其添加到驻留在类D中的表A中。 如果实例是C,我想将其添加到表B中,表B也驻留在类D中

如果不使用instanceof,这是可能的吗


共 (5) 个答案

  1. # 1 楼答案

    这里可能有一个解决方案:

    public abstract class A {
        public abstract void addTo(D d);
    }
    
    public class B extends A {
        @Override
        public void addTo(D d) {
            d.addB(this);
        }
    }
    
    public class C extends A {
        @Override
        public void addTo(D d) {
            d.addC(this);
        }
    }
    

    一个简单的D类:

    public class D {
        public void addB(B b) {
            // ...
        }
        public void addC(C c) {
            // ...
        }
    }
    

    然后:

    List<A> list = new ArrayList<A>();
    list.add(new B());
    list.add(new C());
    
    D d = new D();
    for (A a : list) {
        a.addTo(d);
    }
    
  2. # 2 楼答案

    一种可能的方法是让B和C返回一些鉴别器,让将列表中的内容移动到D的表中的类知道应该将它们添加到哪个表中,但最终会达到需要切换或类似操作的程度

    例如:

    public enum TypeOfA { TYPE_1, TYPE_2 }
    
    public abstract class A {
        // your other stuff
        public abstract TypeOfA getType();
    }
    
    public class B extends A {
        public TypeOfA getType() {
            return TypeOfA.TYPE_1;
        }
    }
    
    public class Sorter {
        public void putInTables() {
             for (final A a: this.listOfAs()) {
                 this.getTableFor(a).add(a);
             }
        }
    
        private Table getTableFor(final A a) {
            switch(a.getType()) {
                 case TypeOfA.TYPE_1: return tableA;
                 case TypeOfA.TYPE_2: return tableB;
            }
        }
    }
    

    有了这个解决方案,您可以添加A的更多子类,这些子类与B或C共享相同类型的“鉴别器”,因此您的分类器类将把它们的实例放在相同的表中

    除此之外,你在分类器的逻辑中保留了实际的决定,如果类型_1和类型_2有一些语义含义,那么B和C实际上不需要知道它们为什么要公开它

  3. # 3 楼答案

    您有一个列表L : List<A>,其中包含B extends AC extends A。当您从L获取元素E时,您喜欢将E添加到D.Aif E instanceof B或将E添加到D.Bif E instanceof C

    通过提供一个抽象方法A.visit(D),使用Visitor PatternB.visit(D)将通过调用D.addMeToTableA(this)来实现它,而C.visit(D)将通过调用D.addMeToTableB(this)来实现它

  4. # 4 楼答案

    是的,在a中放置一个方法,在包含表名的B和C中重写该方法

  5. # 5 楼答案

    “如何根据子类类型对子类做不同的事情”,或者换句话说:多态性。当然是可能的,这是OO软件的主要原则之一。您不需要使用instanceOf。getClass或其他形式的元编程,用于解决基本的OO问题

    您可以使用类似的抽象方法:

    public String belongsToTable() {}
    

    在A中,你以一种方式实现;在B中,你以另一种方式实现

    当然,这可能是个坏名字,当然,返回字符串可能是个坏主意,这只是基于a、B、C问题的一个例子。软件开发是关于命名和语义的,下次如果你真的想得到好的建议,而不是一本基本的OO书籍中的一般建议,请使用有意义的名称