如何使用instanceof基于子类类型对子类做不同的事情?

时间:2014-03-12 14:01:41

标签: java oop

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

在其他一些课程中,我有A的实例列表,即:List。 A列表当然可以包含可以是B或C实例的元素。

如果实例是B,我想将它添加到位于D类的表A. 如果实例是C,我想将它添加到表B中,表B也位于D类中。

这可以不使用instanceof吗?

5 个答案:

答案 0 :(得分:2)

是的,在A中添加一个方法,在B和C中覆盖包含表名的方法。

答案 1 :(得分:0)

这可能是一个解决方案:

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 :(得分:0)

一种可能的方法是让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共享相同类型的“鉴别器”,因此您的排序器类会将它们的实例放在相同的表中。

除此之外,你在Sorter的逻辑中保留实际的decission,如果TYPE_1和TYPE_2有一些语义含义,B和C实际上不必知道它们为什么暴露它。

答案 3 :(得分:0)

您有一个包含L : List<A>B extends A的列表C extends A。从E获取元素L时,如果E您要D.A添加E instanceof B,或E添加D.B E instanceof C

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

答案 4 :(得分:0)

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

您可以在A中使用抽象方法:

public String belongsToTable() {}

在A中,您以B的一种方式实现,以另一种方式实现。

当然它可能是一个糟糕的名字,当然返回一个字符串可能是一个坏主意,它只是一个基于你的A,B,C问题的例子。关于命名和语义的软件开发,下次请使用有意义的名称,如果你真的需要好的建议而没有你可以在基本的OO书中找到的通用建议。