之前我们的文章讲了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. 向上滚动或者向下滚动分页异步加载数据(Ajax + lazyload)[上拉加载组件]

    /**** desc : 分页异步获取列表数据,页面向上滚动时候加载前面页码,向下滚动时加载后面页码 ajaxdata_url ajax异步的URL 如data.php page_val_name a ...

  2. XVII Open Cup named after E.V. Pankratiev. GP of SPb

    A. Array Factory 将下标按前缀和排序,然后双指针,维护最大的右边界即可. #include<cstdio> #include<algorithm> using ...

  3. 【转】apache 二级域名设置完整步骤

    原文链接:http://blog.sina.com.cn/s/blog_5375d76b01014fnt.html 最近在折腾网站二级域名的事情,在网上查了很多零碎的文档,不完整,有些也没有自己验证, ...

  4. 【BZOJ】3997: [TJOI2015]组合数学

    题意 \(N \times M\)的网格,一开始在\((1, 1)\)每次可以向下和向右走,每经过一个有数字的点最多能将数字减1,最终走到\((N, M)\).问至少要走多少次才能将数字全部变为\(0 ...

  5. 关于CSS3的小知识点之2D变换

        transition过渡 transition-duration:; 运动时间 transition-delay:; 延迟时间 transition-timing-function:; 运动形 ...

  6. 站内全文检索服务来了,Xungle提供免费全文检索服务

    免费站内全文检索服务来了,是的,你没听错.全文检索相信大家已经不太陌生,主流检索服务有sphinx.xunsearch等,但这些都受服务器限制,对于中小站长尤其是没有服务器实现就困难了,随着数据量的增 ...

  7. 6个奇葩的(hello,world)C语言版(转)

    //下面的所有程序都可以在GCC下编译通过,只有最后一个需要动用C++的编译器用才能编译通过. //程序功能输出   Hello,world! 01.c #define _________ } #de ...

  8. webform 分页

    界面: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx ...

  9. syntax error near unexpected token‘(

    用虚拟机的时候出现这样的: 上网查了资料之后,在括号"( " 前加上"$"字符就暂时不会提示出错了.

  10. Thrift-0.9.2编译安装

    确定安装好了boost1.54以上 确定libevent版本大于1.0 只编译生成cpp库 ./configure --without-java --without-lua --without-pyt ...