之前我们的文章讲了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. 学习微信小程序之css5

    文本的装饰(下划线) 文本的位置,缩进

  2. 复利计算APP版-----娱乐一下

    先不说那么多,下载地址来一个:http://pan.baidu.com/s/1eSz2GBg 目前版本号为:0.3 lastest 软件上线了!三平台首发! 下载地址: http://shouji.b ...

  3. 【APICloud】APICloud基础学习与快速入门

    前言:回顾这几天学习情况,总的来说APICloud官网它的学习资料和社区还是足够了,但是我必须吐槽一句,实在是过于混乱了,视频资料文档资料它一股脑地都堆在了那里,这几天基本处于在各个地方跳转,然后现在 ...

  4. LeetCode 387. First Unique Character in a String

    Problem: Given a string, find the first non-repeating character in it and return it's index. If it d ...

  5. 同步机制 note

    1.信号量与互斥体的不同之处: 不需要由最初获取它的那个线程来释放. 信号量可以用来调停对资源池的访问. 2. 条件变量: 允许任意复杂的条件表达式作为等待条件,允许更复杂的调度策略.

  6. echo.js 延迟加载图片控件

    echo.js的github地址:https://github.com/toddmotto/echo   echo是一个独立的JavaScript.轻量级的.延迟图片加载插件,echo压缩后体积不到1 ...

  7. monodroid 调用 JNI Native 的一些问题

    在Android版本开发的过程中,需要使用一些用JNI开发的NDK的native库.这里谈一谈踩到的坑,给大家参考. 虽然java的程序我还算熟悉,但是没有了解过 JNI Native 的开发,一般是 ...

  8. HDU 2509 Nim博弈变形

    1.HDU 2509  2.题意:n堆苹果,两个人轮流,每次从一堆中取连续的多个,至少取一个,最后取光者败. 3.总结:Nim博弈的变形,还是不知道怎么分析,,,,看了大牛的博客. 传送门 首先给出结 ...

  9. LINUX 编译安装 PHP 环境

    今天终于有时间 总结一下 linux 的编译安装 php 环境同学给我发了他写的文档 ,基本就可以实现编译安装了我同学文章地址: http://penghui.link/articles/2016/0 ...

  10. 【WPF】WPF中的List<T>和ObservableCollection<T>

    在WPF中 控件绑定数据源时,数据源建议采用 ObservableCollection<T>集合 ObservableCollection<T> 类:表示一个动态数据集合,在添 ...