重载和重写是什么?
重载指的是有相同方法名,但有不同参数类型或顺序的一类方法
重写指的是子类和父类有相同方法签名,通过多态实现运行时绑定
重载的选择是静态的
对于如下判断集合的函数
class Classifier {
public static String classify(Set<?> set) {
return "Set";
}
public static String classify(List<?> list) {
return "List";
}
public static String classify(Collection<?> collection) {
return "Collection";
}
}
下面调用将打印3次Collection,因为传递的参数为Collection<?>类型,调用哪个重载方法是在编译时做出决定的
Collection<?>[] collections = {
new HashSet<String>(),
new ArrayList<Integer>(),
new HashMap<String, String>().values()
};
for (Collection<?> collection : collections) {
System.out.println(Classifier.classify(collection));
}
正确的方式应该是使用instanceof判断,或避免使用有相同参数数目的重载方法,通过给方法取不同的名称替代重载
public static String classify(Collection<?> c) {
return c instanceof Set ? "Set" :
c instanceof List ? "List" : "collection";
}
重载和装箱
对于如下程序,打印为[-3, -2, -1]、[-2, 0, 2]
Set<Integer> set = new TreeSet<>();
List<Integer> list = new ArrayList<>();
for (int i = -3; i < 3; i++) {
set.add(i);
list.add(i);
}
for (int i = 0; i < 3; i++) {
set.remove(i);
list.remove(i);
}
System.out.println(set);
System.out.println(list);
造成这样的结果是因为List的remove()方法具有重载,第一个为删除指定元素,第二个为删除指定位置的元素
故如果要正确调用删除指定元素,应该如下
list.remove((Integer) i);
list.remove(Integer.valueOf(i));
重写的选择是动态的
对于如下继承结构
class Wine {
String name() {
return "name";
}
}
class SparklingWine extends Wine {
@Override
String name() {
return "SparklingWine";
}
}
class Champagne extends SparklingWine {
@Override
String name() {
return "Champagne";
}
}
如下调用将打印Wine、SparklingWine、Champagne
List<Wine> wineList = new ArrayList<>();
wineList.add(new Wine());
wineList.add(new SparklingWine());
wineList.add(new Champagne());
for (Wine wine : wineList) {
System.out.println(wine.name());
}