Java可变参数类型与重写,重载的讨论

Java中的可变长参数可以这样表示:

String...args

而其与String s(即单参数)方法的多态性成了一个很有意思的问题。

package cn.xujin;

public class Regex2
{
	public static void main(String args[])
	{
		Base a = new Child();
		a.test("one");//Base
		//a.test("22","123");//error,编译错误
		
		Child b = (Child)a;
		b.test("one");//Base
		b.test("one","two");//Child
		
	}
}

class Base{
	public void test(String s){
		System.out.println("Base");
	}
}
class Child extends Base{
	public void test(String...args){
		System.out.println("Child");
	}
}

运行上述程序可以知道:

a是一个Child类型,可是被Base引用,调用a.test("one")调用的是Base类中的;而a.test("one","two");不能编译,是因为Base类中无两个参数的test方法

b也是一个Child类型,被Child类型引用,b.test("one")调用的是Base类中的,而b.test("one","two");调用的是Child类中的变长参数方法。


Base类中只有一个单参数的方法,而Child类中有一个单参数的方法和一个变长参数的方法。当调用单参数方法时,发生冲突,此时虚拟机会不管变长参数方法,而直接调用完全匹配的那个方法。


我们看到,两个以上参数的情况符合函数重载(Overload);而单参数的情况并不符合重写(Override)的规则。可以说,这是一种很特殊的重载。

因而:

两个及以上参数的时候,按照重载(Overload)来;而单参数的情况下,调用a.test("one"),Base仅有单参数方法,所以必须调用Base中的test方法,输出“Base”。调用b.test("one"),Child有可变参数方法也有继承来的单参数方法,所以虚拟机会不管变长参数方法,而直接调用完全匹配的那个方法,输出“Base”。



我们再来看一种情况来验证上述观点:

package cn.xujin;

import java.util.regex.*;
public class Regex2
{
	public static void main(String args[])
	{
		Base a = new Child();
		a.test("one");//Base
		a.test("one","two");//Base
		
		Child b = (Child)a;
		b.test("one","two");//Base
		b.test("one");//Child
	}
}

class Base{
	public void test(String...args){
		System.out.println("Base");
	}
}
class Child extends Base{
	public void test(String s){
		System.out.println("Child");
	}
}

与上面同理,Base类中只有一个可变参数的方法,而Child类中有一个单参数的方法和一个变长参数的方法。

单参数的情况下,调用a.test("one"),Base仅有可变参数方法,所以必须调用Base中的test方法,输出“Base”。调用b.test("one"),Child有可变参数方法也有继承来的单参数方法,所以虚拟机会不管变长参数方法,而直接调用完全匹配的那个方法,输出“Child”。


今天我又遇到这么一种情况,不是父类子类的关系:

package cn.xujin;

import java.util.regex.*;
public class A{
	public String doit(int x, int y){
		return "a";
	}
	public String doit(int...vals){
		return "b";
	}
	
	public static void main(String...args){
		A a = new A();
		System.out.println(a.doit(3, 4));//a
	}
}

这种情况下,虚拟机会先抛开可变长参数的方法,查找有没有能直接匹配的方法,如果找到再运行,否则去查找可变长参数的方法。


你可能感兴趣的:(java)