多态和重载

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{

}

 

你可能感兴趣的:(Java)