package com.atguigu.exer;
//考查多态的笔试题目:
public class InterviewTest1 {
public static void main(String[] args) {
Base1 base = new Sub1();
base.add(1, 2, 3);
Sub1 s = (Sub1)base;
s.add(1,2,3);
}
}
class Base1 {
public void add(int a, int... arr) {
System.out.println("base1");
}
}
class Sub1 extends Base1 {
public void add(int a, int[] arr) {
System.out.println("sub_1");
}
public void add(int a, int b, int c) {
System.out.println("sub_2");
}
}
这里首先Sub1中有两个add函数,其实只有第一个add函数完成了对父类的add函数的重写,为什么重写了呢,因为可变形参和数组其实是同样的,在前面的重载中,就明确了int …arr 和int[] arr这两个形参分别出现在同名函数中是不能同时存在在一个类内的,而是会被编译器当作为一摸一样的函数,那么既然是一模一样的函数,说明这里Sub1对父类的Base1中的add合理的形成了重写,而这一段代码
Base1 base = new Sub1();
base.add(1, 2, 3);
中的多态中调用的子类的重写函数是如何执行的‘,就是首先调用的是base父类中的add函数,但是这个函数在子类中进行了重写,转而执行重写的函数,而重写的函数是子类中的第一个add而不是第二个add,第二个add其实构成的是对第一个add的重载,并且也不构成对父类add的重写,所以执行结果是sub_1
Sub1 s = (Sub1)base;
s.add(1,2,3);
这里进行强转后,编译器就可以看到子类中的方法了,那么父类中有一个add方法,子类中也有一个add方法,这个时候其实调用的就是固定的参数的方法,而不是可变参数的方法,就是说可以看成这两个方法放在同一类中,然后一个是可变形参,一个是多个固定形参,那么调用的话肯定优先选择固定形参。就是这么简单。
当然,这是某教学课程中的说法,我经过实验后发现好像并不是如此,因此给出自己的推理
首先,在向下转型后,调用add方法,首先肯定是先查看子类中有没有此方法,若有满足的方法,即执行,那么这里子类总有满足的方法第二个add,第一个add其实是不满足的,连编译都不能过我们假设,子类sub中只有第一个add方法,即
package com.atguigu.exer;
//考查多态的笔试题目:
public class InterviewTest1 {
public static void main(String[] args) {
Base1 base = new Sub1();
Sub1 s = (Sub1)base;
s.add(1,2,3);
}
}
class Base1 {
public void add(int a, int... arr) {
System.out.println("base1");
}
}
class Sub1 extends Base1 {
public void add(int a, int[] arr) {
System.out.println("sub_1");
}
}
这里会直接编译报错,原因就是子类中已经对父类的方法进行了重写,那么其实父类中被重写的这个方法在编译器眼里已经默认被替换了,那么当你执行add的时候,给了三个实参1,2,3但是编译器找不到对应的可执行方法。尽管这个方法在父类中其实是有的,但由于已经被重写了,所以编译器看不到。而编译器能看到的只有子类中的add方法,但是子类中的add方法的形参是一个int类型,一个int[] 类型所以,自然而然会报编译错误。