有 Java 编程相关的问题?

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

Java接口和多态性初学者

在Java中,有没有办法在其父引用类型变量中创建子对象,并且仍然可以访问任何实现的接口,而不必强制转换接口类型或使用接口引用来存储对象

几乎像是手动多态


共 (2) 个答案

  1. # 1 楼答案

    即使列出所有实现的接口是可能的,但我会尽量避免它,因为它闻起来像是糟糕的设计,而且这肯定不是一件常见的事情

    另一方面,一件非常常见的事情是测试对象是否是某个类/接口的子类型。请看这个演示:

    class Parent { }
    
    interface MyInterface {
        void foo();
    }
    
    class Child extends Parent implements MyInterface {
        @Override
        public void foo() {
            System.out.println("Foo");
        }
    }
    
    void main() throws Exception {
        List<Parent> list = new ArrayList<>();
        list.add(new Parent());
        list.add(new Child());
        for (Parent p : list) {
            if (p instanceof MyInterface) {
                MyInterface cased = (MyInterface) p;
                cased.foo();
            }
        }
    }
    

    这里有一个Parent的列表,对于所有也实现MyInterface的列表,您可以做一些特殊的事情,甚至在对对象进行大小写后从MyInterface调用方法

    如果确实需要列出所有接口,请使用reflection

    void main() throws Exception {
        List<Parent> list = new ArrayList<>();
        list.add(new Parent());
        list.add(new Child());
        for (Parent p : list) {
            Class<?>[] interfaces = p.getClass().getInterfaces();
            for (Class<?> i : interfaces) {
                Method firstMethod = i.getMethods()[0];
                firstMethod.invoke(p, new Object[0]);
            }
        }
    }
    

    这段代码将查看列表中每个Parent对象实现的所有接口,并从对象上的每个接口调用第一个方法

    然而,对反射的需求非常少(我在两年的编程中使用过一次)

  2. # 2 楼答案

    不,这是不可能或不适当的。我们使用对父类/接口的引用来将对象用于某些抽象功能。例如:

    public interface Command {
        public void execute();
    }
    
    public class SomeCode      implements Command { }
    public class SomeOtherCode implements Command { }
    
    public class Test {
    
        public Test {
    
            List<Command> list = new ArrayList<>();
    
            list.add(new SomeCode());
            list.add(new SomeOtherCode());
    
            runCommands(list);
        }
    
        public void runCommands(List<Command> list) {
             for (Command c : list)
                   list.execute();
        }
    }
    

    因此,我们正在使用命令之间共享的抽象功能(execute())。如果我们想使用特定的方法,那么逻辑上我们必须使用强制转换。这就是引用超类/接口的要点,也是使用casting的要点