一、重载(Overloading)
1、定义:
java重载发生在同一类中,即在类中可以创建方法名相同,但是方法参数列表不同(参数类型、参数个数至少一种不同即可)的方法,具体调用哪个方法由传递给函数的参数列表决定。
由定义可看出重载特征:
(1)方法名必须相同;
(2)参数列表必须不同;
(3)前提条件:方法必须位于同一个类中(平行关系)。
以上3个条件即为判定重载的缺一不可的条件。(重载<===>3条件)
注意:不能以返回类型别作为重载函数的区分标准(即重载与返回类型毫无关系)。想象构造函数就知道了,构造函数是重载的,但它却没有返回类型。
2、意义?
为什么要重载?重载是类内的一种多态。(此处”多态“与标题“Java
重载、重写、多态”的”多态“是两码事,为便于区分自称为“内多态”)。“多态”就是“多种姿态”,就是为了抽象服务的。方法就是行为,当面对具有相同方法名(【类似】)的方法时,选择何种行为将由参数列表决定。所以,我们可以把完成类似行为的方法赋予相同“名字”,具体选用哪种方法由参数列表来完成,所以通过输入不同的值(参数列表)给“黑匣子”,得到不同的结果(行为),而具体选哪一个方法,我们不需要关心,这就是内多态,如下图:
二、重写(Overriding,也叫覆盖)
1、定义:
子类覆盖父类的同名、同参数列表、同返回类型的方法。
由定义可以看出重写的特征:
(1)方法名必须相同;
(2)参数列表(参数类型、参数个数)必须相同;
(3)返回类型必须相同;
(4)前提条件:发生在父、子类之间(层次关系)且要覆盖。
以上4个条件即为判定重写的缺一不可的条件。(重写<===>4条件)
注意:“覆盖”是指能“覆盖”,覆盖后不可见,如子类不能直接调用父类中被覆盖的方法。(什么能覆盖?什么不能覆盖?final、static方法不能被覆盖)
2、意义?
为什么要重写?
(1)改变。我们知道子类会继承父类的属性与方法(当然被限定为private的不能继承)。覆盖就是想改变重父类继承来的方法,但是又不会对父类本身造成影响,只是对父类中该方法不可见而已。
(2)多态(此处“多态”和标题“Java 重载、重写、多态”的“多态”是一回事),后面在解释。
3、有必要谈一下继承:
(1)构造方法不能被继承;
(2)方法和属性可以被继承;
(3)子类构造方法隐式地调用父类的不带参数的构造方法;(为什么要这么做?构造方法就是为了确认对象的创建,我们知道创建子类对象时,会先创建父类对象,所以子类构造方法会隐式调用父类构造方法。为什么是不带参数?若带参数调用哪一个?不带参数的至少有一个默认构造方法可以调用。)
(4)当父类没有不带参数的构造方法时,子类需要使用super显式地调用父类的构造方法,super指的是对父类的引用;super关键字必须是构造方法中的第一行语句。
注意:
(1)在一个构造方法中调用另一个构造方法,需要使用this()的方式调用,this()括号中的参数为目标构造方法中的参数,其中this为指向当前对象。this()必须作为构造方法的第一条语句,即this()之前不能有任何可执行代码。
(2)如果子类构造方法使用super()显示调用父类的某个构造方法,那么在执行的时候就会寻找与super()所对应的构造方法而不会再去寻找父类的不带参数的构造方法。与this一样,super作为构造方法(仅限于构造方法)的第一条执行语句,前面不能有其他的可执行语句。
(3)当两个方法形成重写关系时,在子类中可以通过super.run()形式调用父类的run()方法,其中super.run()不必放在第一行语句(因为此时父类对象已经构造完毕,先调用父类的run()方法,还是先调用子类的run()方法是根据程序的逻辑决定的)。
(4)构造方法不能被继承,更谈不上重写。
例如:
class Fruit{
int a = 0;
int b = 0;
Fruit(){
a = 1;
System.out.println("a:"+a+",b:"+b);
}
Fruit(int b){
this.b = b;
System.out.println("a:"+a+",b:"+b);
}
void run(){
System.out.println("father!");
}
}
public class Apple extends Fruit{
Apple(){
}
Apple(int a){
super(a);
}
void run(){
System.out.println("Child!");
}
public static void main(String[] args){
Apple apple = new Apple();
Apple apple1 = new Apple(2);
apple.run();
}
}
三、多态(Polymorphism)
1、多态的最重要、最核心特征:动态绑定
动态绑定+重写<===>多态<=||=>非动态绑定
由该特征可以判断以下是否具有多态特征:
名称
|
是否具有多态
|
原因
|
属性(基本数据类型)
|
否
|
静态绑定
|
static、final方法
|
否
|
静态绑定
|
构造方法
|
否
|
默认为static方法
|
一般方法
|
是
|
动态绑定
|
2、多态发生在父类与众多子类之间(至少一个子类)。
3、多态几个技巧(绝对不会错,对理解有好处)
(1)看能否为多态就看是否具备两个特征:动态绑定、重写。
(2)Java中 左边决定引用类型,右边决定对象类型。当引用类型与对象类型不一致时需要转型(等号右边向等号左边转型,因为左边才是真正的类型):
//父类Fruit,子类Apple
Fruit f = new Apple();
//引用f的类型为Fruit,生成的对象类型为Apple,故需要向上转型
(3)Java中除了static、fina方法外,其他方法均为动态绑定。
(4)看图:(指向谁,就调用谁的对象(前提是方法没有被覆盖,这一点在static方法易出现错误判断,故这一点不适用与static方法)!!!向下类型转换时,指向谁才能强制转换成谁!!!)
4、重写注意:
(1)静态方法只能继承,不能重写(Override)。即子类不能重写父类的静态方法,但是可以隐藏它。
(注意:静态方法不能覆盖非静态、静态,非静态也不能覆盖静态。)