Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从泛型列表进行Java动态向下转换_Java_Generics_Rtti_Instanceof_Downcast - Fatal编程技术网

从泛型列表进行Java动态向下转换

从泛型列表进行Java动态向下转换,java,generics,rtti,instanceof,downcast,Java,Generics,Rtti,Instanceof,Downcast,如何在没有instanceof语句的情况下动态向下转换对象? 我读了Bruce Eckel在Java中的思想,还有使用类,还有这样一个主题,但我没有被接触 对我的英语很抱歉 public class GenericTest { static private interface Base { } static private class A implements Base { } static private class B implements

如何在没有instanceof语句的情况下动态向下转换对象? 我读了Bruce Eckel在Java中的思想,还有使用类,还有这样一个主题,但我没有被接触 对我的英语很抱歉

public class GenericTest {


    static private interface Base {
    }


    static private class A implements Base {
    }

    static private class B implements Base {
    }

    static private class C extends B {
    }

    private List<Class<? extends Base>> types;
    private List<Base> objects;

    public GenericTest() {
        types = new ArrayList<Class<? extends Base>>();
        types.add(A.class);
        types.add(B.class);
        types.add(C.class);

        objects = new ArrayList<Base>(Arrays.asList(new A(), new B(), new C()));

        for (Base base : objects) {
            if (base instanceof A)
                test((A) base);
            else if (base instanceof C)
                test((C) base);
            else if (base instanceof B)
                test((B) base);

            for (Class<? extends Base> c : types)
                if (base.getClass().equals(c))
                    test(c.cast(base));
        }
    }

    private void test(A a) {
        System.out.println("A");
    }

    private void test(B b) {
        System.out.println("B");
    }

    private void test(C c) {
        System.out.println("C");
    }

    private void test(Base base) {
        System.out.println("Base");
    }

    public static void main(String[] args) {
        new GenericTest();
    }
}
公共类泛型测试{
静态专用接口库{
}
静态私有类A实现了基类{
}
静态私有类B实现了基类{
}
静态私有类C扩展了B{
}

private List有时,使用
instanceof
表明您的设计存在缺陷,可能违反了面向对象编程的一些基本原则

在您的情况下,根据您的最终目标,我可以监督两个解决方案。第一个解决方案是将
test()
的特定行为封装在类
A
B
C
中。可以通过声明方法
test()来完成
在接口
Base
中,使其成为抽象类并在子类中实现

static private abstract class Base {
    public void test() {
        System.out.println("Base");
    } 
}

static private class A extends Base {
    private void test() {
        System.out.println("A");
    }
}

static private class B implements Base {
    private void test() {
        System.out.println("B");
    }
}

static private class C extends B {
    private void test() {
        System.out.println("C");
    }
}
请注意,层次级别大于3的类不是一个好的做法。继承是两个对象之间可以达到的最高耦合度。这就是为什么我们倾向于这样做


如@SLaks所述,改进设计的第二种方法是使用访问者模式。有关此模式的更多信息,请参阅。关于此主题的推荐阅读内容是和。

有时,使用
instanceof
表明您的设计存在缺陷,可能违反了面向对象编程的一些基本原则

在您的情况下,根据您的最终目标,我可以监督两个解决方案。第一个解决方案是将
test()
的特定行为封装在类
A
B
C
中。可以通过声明方法
test()来完成
在接口
Base
中,使其成为抽象类并在子类中实现

static private abstract class Base {
    public void test() {
        System.out.println("Base");
    } 
}

static private class A extends Base {
    private void test() {
        System.out.println("A");
    }
}

static private class B implements Base {
    private void test() {
        System.out.println("B");
    }
}

static private class C extends B {
    private void test() {
        System.out.println("C");
    }
}
请注意,层次级别大于3的类不是一个好的做法。继承是两个对象之间可以达到的最高耦合度。这就是为什么我们倾向于这样做


第二种改进设计的方法是,正如@SLaks所提到的,使用访问者模式。可以找到关于此模式的更多信息。关于此主题的推荐阅读内容是和。

不清楚您想要做什么,但下面是如何在不使用强制转换和
instanceof
的情况下实现相同的结果

test
方法放在界面
Base
上:

static private interface Base {
    public void test();
}
然后实施它:

static private class A implements Base {
    public void test() {
        System.out.println("A");

}
同样地,对于
B
C
。 那么您的循环应该如下所示:

for (Base base : objects) {
    base.test();
}

如果
base
A
的实例,这将导致调用
A::test
B::test
如果
base
B
的实例,等等。(该方法根据引用对象的运行时类型选择)

test
方法放在界面
Base
上:

static private interface Base {
    public void test();
}
然后实施它:

static private class A implements Base {
    public void test() {
        System.out.println("A");

}
同样地,对于
B
C
。 那么您的循环应该如下所示:

for (Base base : objects) {
    base.test();
}

如果
base
A
的实例,这将导致调用
A::test
B::test
如果
base
B
的实例,等等。(该方法根据引用对象的运行时类型选择)

考虑使用访问者模式。更详细地描述你真正想要达到的目标。在大多数情况下,使用<代码> >至少是可疑的。发布的回答是否回答了你的问题?考虑使用访问者模式。更详细地描述你真正想要达到的目标。使用<代码>实例< <代码>至少是DuiBio。大多数情况下都是我们。贴出的回答回答了你的问题吗?我只是想把实现与类分开。现在,我正在阅读头先设计模式。头先设计模式是一个很好的起点。祝你好运。我只是想把实现与类分开。现在,我正在阅读头先设计模式。头先设计模式erns是一个很好的起点。祝你好运。