之前我们的文章讲了Java的封装和继承,封装讲的时候,并没有体现出来封装的强大之处,反而还要慎用封装。因为这时的封装还没有和多态联系到一起,还无法看出向上转型的厉害之处。

多态,是指同一个行为具有多种的表现形式。同一个方法根据调用对象的不同而产生多种结果。对于Java而言,多态就是程序中定义的引用变量,和调用方法的代码在编译的时候就决定好了,但引用变量所指向的对象,却是在运行时才确定的。举一个很简单的例子,人要工作。这里工作是一个方法,但一个作家工作就是写文章,一个程序员工作却是写代码。工作的执行者不同,工作的内容也不同。这就是一种多态。

多态的实现

对于我们而言,实现多态要如下的准备。

  1. 继承
  2. 方法覆写
  3. 向上转型

对于Java ,则是通过动态绑定来实现。我们先理解一下什么是动态绑定,才方便后面去利用多态的特性。

动态绑定

绑定是指将一个方法调用同一个方法主体关联起来。

动态绑定是值在运行时根据对象的类型进行绑定,而与之对应就是静态绑定,在编译期就进行绑定,在Java里面只有final static private 和构造方法是静态绑定的。

我们已经知道了一般方法的调用是在运行时根据对象的类型进行调用的,换句话说,不管你在代码里是怎么写的,在运行时才会真正决定调用方法的对象是哪个。

实现形式

之前继承的文章里面,我们已经知道是可以通过向上转型将一个子类转型成父类,那么我们就可以写出下面的代码

Animal animal = new Dog();

如果Dog覆写了Animal中的方法,那么调用这个被覆写的方法时根据上面的动态绑定的规则,我们就知道实际调用的对象是Dog,那么执行的也会是Dog类的那个方法。具体的例子如下:

public class Animal {
public void run() {
System.out.println("动物在奔跑");
}
} public class Cat extends Animal {
@Override
public void run() {
System.out.println("猫在奔跑");
}
} public class Dog extends Animal{
@Override
public void run() {
System.out.println("狗在奔跑");
} public static void main(String[] args) {
Animal[] animal = {new Dog(),new Cat()};
animal[0].run();
animal[1].run();
}
}
//运行的结果
狗在奔跑
猫在奔跑

在这个例子里面,我们可以看到多态的应用,在父类中定义一个通用的run方法,在子类中去实现不同的run方法,然后将子类的对象赋给父类的引用,就可以根据子类的不同 去调用不同的run方法了。这里面,多态的实现满足了上面的三点,首先是继承关系,其次,在子类中覆写父类的方法,最后,对子类的对象进行向上转型,产生多态。

多态的好处

我们在上个例子基础上在添加一段代码:

public class Log {
public void print(Animal animal) {
System.out.println(new Date().toString());
animal.run();
} }
//我们将Dog类,修改成下面这个样子
public class Dog extends Animal{
@Override
public void run() { System.out.println("狗在奔跑");
} public static void main(String[] args) {
Animal[] animal = {new Dog(),new Cat()};
for (Animal item : animal) {
new Log().print(item);
}
}
}
运行的结果如下:
Wed Jul 13 17:07:40 CST 2016
狗在奔跑
Wed Jul 13 17:07:40 CST 2016
猫在奔跑

在上面的例子中,如果我们不采用多态,那么我们在Log中就要根据不同的对象,生成不同print方法,这样修改起来异常的麻烦。而采用多态的话,我们只需要在方法中编写父类的对象调用方法的代码,但在运行时传入子类的对象,就会动态绑定到子类上,调用子类实现的方法。这样做,在添加新的动物类的时候,我们也不用修改我们的print方法,不用改变已经编写好的代码,那么也不会影响已经实现的方法。多态成功的区分开了"改变的事物和未改变的事物"。这给我们编程带来极大的便利。

Java 浅析三大特性之一多态的更多相关文章

  1. Java 浅析三大特性之一继承

    上文Java 浅析三大特性之一封装我们说到Java是一个注重编写类,注重于代码和功能复用的语言.Java实现代码复用的方式有很多,这里介绍一个重要的复用方式--继承. 在介绍继承之前,我们要明确一点, ...

  2. java-----理解java的三大特性之多态

    的java提高篇(四)-----理解的java的三大特性之多态 面向对象编程有三大特性:封装,继承,多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外 ...

  3. [转]理解java的三大特性之多态

    java提高篇(四)-----理解java的三大特性之多态   面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外 ...

  4. java提高篇(四)-----理解java的三大特性之多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

  5. java提高篇(三)-----理解java的三大特性之多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

  6. 理解 Java 的三大特性之多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

  7. 理解java的三大特性之多态(三)

    摘自:http://cmsblogs.com/?p=52 面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已 ...

  8. (转)java提高篇(四)-----理解java的三大特性之多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

  9. java基础(三)-----java的三大特性之多态

    面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承 ...

随机推荐

  1. Python3的tkinter写一个简单的小程序

    一.这个学期开始学习python,但是看了python2和python3,最后还是选择了python3 本着熟悉python的原因,并且也想做一些小程序来增加自己对python的熟练度.所以写了一个简 ...

  2. DOM性能瓶颈与Javascript性能优化

    这两天比较闲,写了两篇关于JS性能缺陷与解决方案的文章(<JS特性性能缺陷及JIT的解决方案>,<Javascript垃圾回收浅析>),主要描述了untyped,GC带来的问题 ...

  3. Visual Studio 2015 Update 2正式版下载地址

     转载自:王彬的博客 地址:http://blog.sina.com.cn/s/blog_55f899fb0102wcwg.html Visual Studio Professional 2015(带 ...

  4. js与多行字符串

    JS里并没有标准的多行字符串的表示方法,但是在用模板的时候,为了保证模板的可阅读性,我们又不可避免的使用多行字符串,所以出现了各种搞法,这里以一段jade的模板作为示例,简单总结和对比一下. 字符串相 ...

  5. 【BFS】POJ 3414

    直达 -> POJ 3414 Pots 相似题联动–>HDU 1495 非常可乐 题意:两个壶倒水,三种操作,两个桶其中一个满足等于C的最少操作,输出路径.注意a,b互倒的时候能不能倒满, ...

  6. 【JBOSS】User not found SA

    启动JBOSS 发现报User not found: SA 错误, 找了老半天才找到处理方法,异常日志如下: java.sql.SQLException: User not found: SA at ...

  7. 使用logrotate分割Tomcat的catalina日志

    切割catalian日志的方式有很多种,比如shell脚本的.cronolog或者通过配置log4j等等这些都可以实现.但今天我要介绍是使用logrotate来按日期生成日志. 原文是一个外国博主的文 ...

  8. HDU 5976 数学,逆元

    1.HDU 5976 Detachment 2.题意:给一个正整数x,把x拆分成多个正整数的和,这些数不能有重复,要使这些数的积尽可能的大,输出积. 3.总结:首先我们要把数拆得尽可能小,这样积才会更 ...

  9. id选择器、类选择器、属性选择器

    在网页编辑时,通常要对样式进行各种设置.我们借助CSS样式设计中的选择器,就能很好很方便的对它们进行管理和设置了. 今天,跟大家分享一下几个常用的选择器:id选择器.类选择器.属性选择器. id选择器 ...

  10. 20155315庄艺霖--对做中学的理解及对c语言和Java的看法

    关于做中学的理解及技能训练的思考 在写这篇博客之前,我首先阅读了娄老师的博客,对做中学的概念很感兴趣.我们常说知识要学以致用,做中学强调的是在用的过程中有新的收获和体会来进一步巩固学习.细数我学过的课 ...