【面试加分项】运行时多态与编译时多态

来源:互联网 发布:plc模块化编程实例 编辑:程序博客网 时间:2024/06/11 21:54

相信大部分人都听说过多态,对多态有过一些了解都知道多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)。但是很少有人会深入研究他,更少人会知道多态分为运行时多态和编译时多态,如果在面试时你能答出这一点肯定可以然你的面试官对你刮目相看。下面就让我们一起来学习一下多态这个磨人的小妖精。

1.多态基础知识:

什么是多态
面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。

多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)

实现多态的技术称为:动态绑定(dynamic binding)

多态存在的三个必要条件
一、要有继承;
二、要有重写;
三、父类引用指向子类对象。

多态的好处:

1.可替换性(substitutability)。多态对已存在代码具有可替换性。例如,draw函数对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
2.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如图8.3 所示。图中超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。
4.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。

2.运行时多态与编译时多态

ps:其实从java多态的定义来说编译多态并不能真正算做多态,有时候我们也叫他静态多态性。ok,让我们进入正题。
编译时多态主要指的是函数的重载,例如有一个类这个C有一个方法F,但是同时存在F(int),和F(String),当我们的代码中有c.F(param)时,编译器会将C类中说有名为F的方法和父类中属性为public且名为F的方法。
接下来编译器会查看param的类型,比如c.F(“hello”)就会挑选F(String)而不是F(int),如果调用c.F(1),编对应的译器就会选择F(int)。如果挑选不到对应的方法或者多个方法对应就会报错。
接下来我们看运行时多态性。
运行时多态性主要运用到动态绑定。就是在运行时动态的确定调用的是哪一个函数。比如:如果A有多个之类,每个子类都有f(Stirng)方法,当我们声明一个A的对象a,对它用不同的子类进行不同的实例化。这样这个方法可以产生不同的效果,也就是实现了多态。接下来让我们看个具体的例子:

public class test {    public static void main(String[] args) {        A b=new B();        A c=new C();        A d=new D();        D d2=new D();        b.say();        c.say();        d.say();        d2.say(1);        d2.say("");     }}abstract class A{    public  abstract void say();}class B extends A{    @Override    public void say() {        System.out.println("this is class b");    }}class C extends A{    @Override    public void say() {        System.out.println("this is class c");    }    public void say(boolean b){        System.out.println("this is class c boolean");    }}class D extends B{    @Override    public void say() {        System.out.println("this is class d");    }    public void say(int i){        System.out.println("this is class d int");    }    public void say(String string){        System.out.println("this is class d string");    }}

执行结果
this is class b
this is class c
this is class d
this is class d int
this is class d string

大家可以对照之前的说明自行理解为什么结果是这个,又不理解的可以评论中提出,我会尽快答复。

1 0