一、重载
方法重载的要求就是两个同一不同:同一个类中方法名相同,参数列表不同。至于方法的其他部分,如方法返回值类型、修饰符等,与方法重载没有任何关系。
为什么方法返回值类型不能用于区分重载的方法?
对于int f(){} 和 void f(){}两个方法,如果这样调用 int result = f();系统可以识别时调用返回值类型为int的方法,但是Java调用方法时可以忽略方法的返回值,如果采用如下方法来调用f();你能判断是调用哪个方法吗?如果你尚且不能判断,那么Java系统也会糊涂,系统一糊涂,那肯定是你错了。
public class Varargs{ public static void test(int a,String... books){ for(String book : books){ System.out.println(book); } } }
如果同一个类定义了test(String... books)和test(String book)方法,如果只传入一个参数,系统会执行重载test(String book)方法,如果需要调用test(String... books)方法,又只想传入一个字符串数组,则可以采用传入字符串数组的形式
test(new String[]{"aaa"});
一般不推荐重载形参长度可变的方法。没有意义,降低了可读性
二、多态
相同类型的变量,调用同一个方法呈现出多种不同的行为特征,这就是多态
package com.hb.lucence.test; public class BaseClass { public int book = 7; public void base(){ System.out.println("父类的普通方法"); } public void test(){ System.out.println("父类的被覆盖的方法"); } }
package com.hb.lucence.test; import org.junit.Test; public class SubClass extends BaseClass{ public String book = "我是一本书"; public void test(){ System.out.println("子类覆盖父类的方法"); } public void sub(){ System.out.println("子类普通方法"); } @Test public void classtest(){ BaseClass bc = new BaseClass(); System.out.println(bc.book);//7 bc.base();//父类的普通方法 bc.test();//父类的被覆盖的方法 System.out.println("---------------------"); SubClass sc = new SubClass(); System.out.println(sc.book);//我是一本书 sc.sub();//子类普通方法 sc.test();//子类覆盖父类的方法 System.out.println("---------------------"); BaseClass polymorphic = new SubClass(); System.out.println(polymorphic.book);//7 polymorphic.test();//子类覆盖父类的方法 } }
与方法不同的是,对象的Field则不具备多态。
引用变量在编译阶段只能调用其编译时类型所具有的方法,但是运行时则执行它运行时类型具有的方法。因此,编写java代码时,引用变量只能调用声明改变量时所用类里包含的方法。例如,通过Object p = new Person()代码定义了一个变量P,则这个P只能调用Object类的方法,而不能调用Person类里定义的方法。
通过引用变量来访问其包含的实例Field时,系统总是试图访问它编译时类型所定义的Field,而不是他运行时候类型所定义的Field。