1. 多态和重载的区别
对于面向对象,多态分为编译时多态和运行时多态。其中编译时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的函数,通过编译之后会变成两个不同的函数,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是我们所说的多态性。
2. 多态的实现条件
Java实现多态有三个必要条件:继承、重写、向上转型。
对于java而言,实现多态机制需要遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。这句话对多态进行了一个概括。在继承链中对象方法的调用存在一个优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。
//多态的典型例子
public class A {
public String show(D obj) {
return ("A and D");
}
public String show(A obj) {
return ("A and A");
}
}
public class B extends A{
public String show(B obj){
return ("B and B");
}
public String show(A obj){
return ("B and A");
}
}
public class C extends B{
}
public class D extends B{
}
public class Test {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println("1--" + a1.show(b)); //AA
System.out.println("2--" + a1.show(c)); //AA
System.out.println("3--" + a1.show(d)); //AD
System.out.println("4--" + a2.show(b)); //BA
System.out.println("5--" + a2.show(c)); //BA
System.out.println("6--" + a2.show(d)); //AD
System.out.println("7--" + b.show(b)); //BB
System.out.println("8--" + b.show(c)); //BB
System.out.println("9--" + b.show(d)); //AD
}
}
以a2.show(b)为例,a2是A对象的引用变量,this指的就是A,首先在A类中找show(B),其次再到A类的超类中去找(Object类除外)show(B),再在A类中找show((super)O),(super)B为A类,所以在A类中找show(A)。现在问题变成了在A类中找show(A)。a2的对象类型为B,所以如果B类中重写了A类的方法,那么首先调用B类中的方法,如果B类中不存在该方法,则调用A类的。B类中重写了show(A),所以调用B类的show(A),输出BA。
再以b.show(c)为例,b是B对象的引用变量,首先在B中找show(c),其次在(super)B中找,再到B中找show((super)c),即为show(B)或者show(A),首先找B,再找A,输出BB。
3. 重载的含义
- 方法名称必须相同。
- 参数列表必须不同。
- 方法的返回类型可以相同也可以不相同。
- 仅仅返回类型不同不足以称为方法的重载。
方法的重载始终是靠对象外在的表现类型来进行重载的,和对象的实际类型是什么没有关系
public class Test2 {
public static void main(String[] args) {
// 第一波测试
A a1 = new A();
test(a1); //aaaaaaaaa,根据引用变量的类型来判断调用哪个方法
// 第二波测试
A a2 = new B();
test(a2); //aaaaaaaaa
// 第三波测试
B b1 = new B();
test(b1); //bbbbbbbbb
}
public static void test(A a) {
System.out.println("aaaaaaaaa");
}
public static void test(B b) {
System.out.println("bbbbbbbbb");
}
}
class A{
}
class B extends A{
}