同一个类中两种同名方法的调用
- 问题
假如继承一个类的同时实现了一个接口,父类和接口中的方法名是一样的,该如何办?
如果修改父类或接口中的方法名,这样肯定会引起很多不必要的修改。而且如果继承的是第三方SDK中的方法,那就是无法修改的。
- 具体应用
public class HashMap extends AbstractMap
implements Map, Cloneable, Serializable {
/**
* Basic hash bin node, used for most entries. (See below for
* TreeNode subclass, and in LinkedHashMap for its Entry subclass.)
*/
static class Node implements Map.Entry {
final int hash;
final K key;
V value;
Node next;
Node(int hash, K key, V value, Node next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public final K getKey() { return key; }
public final V getValue() { return value; }
// 这个toString()是Map.Entry从Object继承而来的
public final String toString() { return key + "=" + value; }
}
}
测试代码:
public static void main(String[] args) {
HashMap map = new HashMap<>();
map.put("age", 18);
System.out.println("map toString(): " + map.toString());
System.out.println("value toString(): " + map.get("age").toString());
}
// 输出
map toString(): {age=18}
value toString(): 18
可以看出,map
本身和node
是不同的toString()
实现。假如没有内部类的使用,是不可能同时存在两个相同的方法的。(其实内部类,会被编译到另一个class文件中)
很好的实现隐藏
public class ArrayList extends AbstractList
implements List, RandomAccess, Cloneable, java.io.Serializable {
/**
* 这里是提供给外部调用的地方
*/
public Iterator iterator() {
return new Itr();
}
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
Itr() {}
public boolean hasNext() {
return cursor != size;
}
......
}
}
上面是ArrayList
的部分实现,可以看出我们调用iterator()
,方法其实拿到的是一个Itr
的实例,这个内部类,通过向上转型为接口后,隐藏了内部的实现。JDK中Iterator
的实现绝大多数采用了这种方式。
突破 java不允许的多继承
在java中是不允许同时继承多个类的,通过内部类的方式可以解决这个问题
public class HashMap extends AbstractMap
implements Map, Cloneable, Serializable {
final class Values extends AbstractCollection {
......
public final void forEach(Consumer super V> action) {
Node[] tab;
if (action == null)
throw new NullPointerException();
if (size > 0 && (tab = table) != null) {
int mc = modCount;
for (int i = 0; i < tab.length; ++i) {
for (Node e = tab[i]; e != null; e = e.next)
action.accept(e.value);
}
if (modCount != mc)
throw new ConcurrentModificationException();
}
}
......
}
// 这里是调用内部类的地方
public Collection values() {
Collection vs = values;
if (vs == null) {
vs = new Values();
values = vs;
}
return vs;
}
}
HashMap
中的Values
,其实就是一个集合,但是HashMap
需要继承AbstractMap
,所以需要通过内部类的方式,实现继承AbstractCollection
。
总结
- 同一个类中两种同名方法的调用
- 实现具体的方法隐藏
- 突破 java不允许的多继承
- private class 未完待续
我的个人博客,有空来坐坐