java基础

JAVA多态及其原理

2018-08-28  本文已影响232人  我呀有一只小毛驴

1、什么是多态?

概念:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。简单的说: “一个接口,多种实现”。

2、为什么要用多态呢?

原因:我们知道,封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态除了代码的复用性外,还可以解决项目中紧偶合的问题,提高程序的可扩展性.。耦合度讲的是模块模块之间,代码代码之间的关联度,通过对系统的分析把他分解成一个一个子模块,子模块提供稳定的接口,达到降低系统耦合度的的目的,模块模块之间尽量使用模块接口访问,而不是随意引用其他模块的成员变量。

3、多态在什么地方用?

可以用在方法的参数中和方法的返回类型中。
在方法中的参数,请看下面的例子:

public abstract class Driver{
    public void run();//让子类来运行
}
class SBenz extends Driver{
    public void run(){
        Console.WriteLine("Benz在以200迈的速度在run");
    }
}
 class JD extends Driver{
    public void run(){
        Console.WriteLine("JD is running...");
    }
 }
 class Person{
    private Driver driver;
    public Person(){
        
    }
    public Person(Driver driver){
        this.driver = driver;
    }
    public void drive(){
        driver.run();
    }
    public void setDriver(Driver driver){
        //运用参数多态,以后不管买什么车都可以
        this.driver = driver;
    }
 }
 static void Main(string[] args){
        Person p = new Person();
        JD jd = new JD();//刚开始没钱就买辆JD吧
        p.setDriver(jd);
        p.drive();
        SBenz benz = new SBenz();//有钱换车了
        p.setDriver(benz);
        p.drive();
 }

在方法的返回类型中,请看下面的例子(工厂模式):

public class CarFactory{
    public Driver factory(String carName){
        if (carName.Equals("JD")){
            return new JD();
        } else if (carName.Equals("Benz")){
            return new SBenz();
        } else {
            Console.WriteLine("对不起,不伺候");
            return null;
        }
    }
 }

4、实现原理:动态绑定

JVM 运行时结构
Java 的方法调用有两类,动态方法调用与静态方法调用。静态方法调用是指对于类的静态方法的调用方式,是静态绑定的;而动态方法调用需要有方法调用所作用的对象,是动态绑定的。类调用 (invokestatic) 是在编译时刻就已经确定好具体调用方法的情况,而实例调用 (invokevirtual) 则是在调用的时候才确定具体的调用方法,这就是动态绑定,也是多态要解决的核心问题。

相关面试题

class A { 
     public String show(D obj)...{ 
        return ("A and D"); 
     } 
     public String show(A obj)...{ 
        return ("A and A"); 
     } 
} 
class B extends A{ 
     public String show(B obj)...{ 
        return ("B and B"); 
     } 
     public String show(A obj)...{ 
        return ("B and A"); 
     } 
} 
class C extends B...{} 
class D extends B...{}

问题:以下输出结果是什么?

A a1 = new A();
    A a2 = new B();
    B b = new B();
    C c = new C();
    D d = new D();
    System.out.println(a1.show(b));   ①
    System.out.println(a1.show(c));   ②
    System.out.println(a1.show(d));   ③
    System.out.println(a2.show(b));   ④
    System.out.println(a2.show(c));   ⑤
    System.out.println(a2.show(d));   ⑥
    System.out.println(b.show(b));     ⑦
    System.out.println(b.show(c));     ⑧
    System.out.println(b.show(d));     ⑨

答案

          ①   A and A
          ②   A and A
          ③   A and D
          ④   B and A
          ⑤   B and A
          ⑥   A and D
          ⑦   B and B
          ⑧   B and B
          ⑨   A and D

分析:

做这种题的话要时时刻刻使用那个优先级顺序: 优先级从高到低:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。
①,②,③调用a1.show()方法,a1 属于A类,A类有两个方法show(D obj)和show(A obj)。①a1.show(b),参数b为A类的子类对象,这里为向上转型,相当于A obj=b;所以调用show(A obj)方法,得到A and A结果。②同理,③参数为d,调用show(D obj),得到A and D。
④,⑤,⑥调用a2.show()方法,A a2 = new B();是向上转型,所以对a2方法的调用,使用A1类的方法show(D obj)和show(A obj),但此时show(A obj)已经被重写为return ("B and A"), ④a2.show(b),调用show(A obj),得到B and A。⑤同理,⑥调用show(D obj),得到A and D。
⑦,⑧,⑨调用b.show()方法,b为B类,B类的show方法有继承的show(D obj),自己的两个show(B obj)、show(A obj)。
⑦调用show(B obj),得到B and B,⑧向上转型,调用show(B obj),得到B and B⑨show(D obj),得到A and D

参考文献

[1]Java多态性理解
[2]java提高篇之理解java的三大特性——多态
[3]java多态实现原理
[4]深入理解java多态性

上一篇下一篇

猜你喜欢

热点阅读