关于位置列表实现中接口实例传入实现类函数的疑问
为啥Position接口的“实例”能传入Node类内部函数?
嘿,我完全懂你现在的困惑——明明是Position接口的“实例”,怎么就能被传入它的实现类Node的内部方法里呢?咱们结合你给的代码一步步掰扯清楚:
首先先把你给出的代码补全一点(方便理解):
// 定义Position接口 public interface Position<E> { Object getElement(); } // 实现Position的Node类 private static class Node<E> implements Position<E> { private E element; // 存储的元素 private Node<E> prev; // 前驱节点引用 private Node<E> next; // 补个常见的后继节点 // 实现接口的方法 @Override public Object getElement() { return element; } // 假设Node内部有个需要接收Position的方法,比如设置前驱 public void setPrev(Position<E> p) { // 关键操作:把Position转型回Node this.prev = (Node<E>) p; } }
核心逻辑拆解:
你手里的Position“实例”本质就是Node对象:Java里接口是不能直接new出来的,所有你拿到的Position类型的对象,底层一定是某个实现了它的类的实例——在这个场景里就是Node。这是Java多态的特性:父类型(接口)可以引用子类型(实现类)的对象。
Node内部敢接收Position,是因为它知道“底细”:在这个数据结构的设计里,外部用户拿到的所有Position实例,都是内部Node类包装后暴露出去的,不会有其他实现Position的类的对象混进来。所以Node内部的方法可以放心地把传入的Position向下转型成Node类型,从而访问Node特有的属性(比如prev、next)或者方法。
这么设计的好处是封装和解耦:对外只暴露Position接口,用户不用关心底层是Node还是其他实现类,大大降低了耦合度;而内部的Node类因为掌控了所有Position实例的来源,所以可以安全地转型操作内部细节,兼顾了抽象性和实现的灵活性。
举个实际场景的例子:比如你用的是一个双向链表,外部调用list.add(element)后,链表内部创建一个Node,然后把它包装成Position返回给你。当你要调用链表的setPrev(pos, anotherPos)方法时,内部的Node类就可以把这两个Position都转成Node,然后修改它们的prev/next引用。
内容的提问来源于stack exchange,提问作者Joe




