Aka*_*nya 7 java overriding overloading variadic-functions
计划1
class B
{
public void m1(int x)
{
System.out.println("Super class");
}
}
class A extends B
{
public void m1(int... x)
{
System.out.println("Sub class");
}
}
class test1
{
public static void main(String args[])
{
B b1 = new B();
b1.m1(10);
A a = new A();
a.m1(10);
B b2 = new A();
b2.m1(10);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
计划2:
class B
{
public void m1(int... x)
{
System.out.println("Super class");
}
}
class A extends B
{
public void m1(int x)
{
System.out.println("Sub class");
}
}
class test1
{
public static void main(String args[])
{
B b1 = new B();
b1.m1(10);
A a = new A();
a.m1(10);
B b2 = new A();
b2.m1(10);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
各位大家好,有人可以解释是否存在覆盖/超载导致输出?
T.J*_*der 11
这个问题根本没有压倒一切,只是超载.覆盖将涉及A定义具有与相应方法相同的签名的方法B(例如,如果它们都具有m1(int)).在这两个示例中都没有这样做,因为参数类型不同(intvs. int...).
JLS§15.12.2:编译时间步骤2:确定方法签名涵盖了方法签名解析的机制(选择使用哪个重载).如果存在任何歧义,Java编译器将在由引用类型(在您的情况下,变量的类型)定义的接口上选择它可以采用的最具体的方法.
请注意,它是重要的引用类型,而不是引用引用的对象的类型.引用的类型(在您的情况下为变量)定义了对象的接口.(这是通用OOP意义上的"接口",而不是以它命名的Java特定事物.)编译器只能从该接口中可用的方法中进行选择.
在此背景下,原因相当清楚:
计划1:
b1是类型B,B只有m1(int),并m1(10)匹配它.a是类型A; A既有m1(int)(来自B)也有自己的m1(int...); 前者是更具体的,所以B的m1(int)被使用.b2是类型B而且B只有m1(int).计划2:
b1是类型B,B只有m1(int...),不是m1(int).a是类型A,并且同时A具有m1(int...)(from B)和它自己的类m1(int); 后者是更具体地,等A的m1(int)使用.b2是类型B,B只有m1(int...),不是m1(int).您的任何示例都没有覆盖,因为重写需要具有相同名称和签名的方法才能出现在超类和子类中.大多数示例都没有方法重载,因为只有一个版本m1可供编译器选择.
在第一个片段中,编译时类型的引用B只能看到m1(int x).编译时类型的引用可以A看到这两种方法,但m1(int x)仍然是首选,因为它与您的方法调用更好地匹配(如果没有其他方法与传递的参数相匹配,则只能在方法重载分辨率中选择使用varargs的方法,并且'包含varargs).因此,在所有三种情况下都调用超类方法.
在第二个片段中,编译时类型的引用B只能看到m1(int... x),这就是在第一和第三种情况下调用该方法的原因.编译时类型的引用可以A看到这两种方法,并且这次m1(int x)再次是首选,因此为第二种情况调用子类方法.