重载
1.构造器的重载
因为构造器的名字必须与类名相同,所以同一个类的所有构造器名肯定相同,构成重载;为了让系统能区分不同的构造器,多个构造器的参数列表必须不同。
class Person{
int age;
String name;
public Person(){
}
public Person(int age){
this.age = age;
}
public Person(int age,String name){
this(age);
this.name = name;
}
}
2.方法的重载(overload)
1.定义:在同一个类中,允许存在一个以上的同名方法,只要他们的参数个数或者参数类型不同即可。
两同一不同”:同一个类、相同方法名
参数列表不同:参数个数不同,参数类型不同
2.举例:
Arrays类中重载的sort() / binarySearch()
3.判断是否重载:
跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系!
class Person{
public void getSum(int i,int j){//A
System.out.println("憨憨");
}
public void getSum(double d1,double d2){//B
}
public void getSum(String s,int i){//形参先后顺序不同,也构成重载//C
}
public void getSum(int i,String s){//D
}
public void getSum(int i,int j){//与方法体无关!!!!
return 0;
}
public void getSum(int m,int n){//与参数名无关!!!!
}
private void getSum(int i,int j){//与权限修饰符大小无关!!!!
}
}
4.在通过对象调用方法时,如何确定某一个指定的方法 :
方法名------>参数列表
重写
为什么要重写:父类的功能无法满足子类的需求
方法重写的前提:必须要存在继承的关系!
应用:重写以后,当创建子类对象以后,通过子类对象调用子父类的同名参数的方法时,实际执行的时子类重写父类的方法
重写的规定:方法的声明:权限修饰符 返回值类型 方法名(形参列表) throws 异常的类型
//方法体
}
约定俗称:子类中的叫重写的方法,父类中的叫被重写的方法
A. 子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
B. 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
>特殊情况:1)子类不能重写父类中声明为private权限的方法(看不到)
2)包访问权限一定要特别小心,子类和父类是否是相同的包。
2)的解释:对于包访问权限来说,只有同级目录下的包的类之间可见。对于不同包的Animal和Dog类压根就不知道Animal还有个eat方法,所以无法覆写。
C. 返回值类型:
>父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
>父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A的子类
//这样算重写,String是Object的子类
pulbic Object show(){//父类方法
}
public String show(){//子类方法
}
//这样不是重写,返回值类型不同
pulbic void catch(){//父类方法
}
pulbic int catch(){//子类方法
}
>父类被重写的方法的返回值类型是基本数据类型(比如:double).则子类重写的方法的返回值类型必须是相同的(double)
D.子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型.(可以抛出异常类型更少、异常类型更小、不抛出异常)
子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写),要么都声明为static的(不是重写)。
注意:A 父类的静态方法不能被子类覆盖为非静态方法。 B 父类的静态方法不能被子类覆盖为静态方法。(这两点与上面的那句话表达的是一个意思)
E.静态方法不能被重写
原因:重写依赖于类的实例,而静态方法和类实例并没有什么关系。而且静态方法和类实例并没有什么关系。而且静态方法在编译时就已经确定,而方法重写是在运行时确定的(动态绑定)。(也可以说java多态体现在运行时、而static在编译时、与之相悖)
《JAVA编程思想》中多次的提到:方法是静态的、他的行为就不具有多态性。静态方法是与类、而非单个对象相关联的。
区分方法的重载和重写
重载:不表现为多态性。
重写:表现为多态性。
从编译和运行的角度来看:
重载,是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不同的参数列表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。他们的调用地址在编译期间就绑定了。Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。
所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”;
而对于多态,只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”;
引用一句Bruce Eckel的话:“不要犯傻,如果它不是晚绑定,它就不是多态。”
重写规则补充
1.父类的抽象方法可以被子类通过两种途径重写(即实现和重写)。
2.父类的非抽象方法可以被重写为抽象方法(此时:子类必须为抽象类)。