之前我们的文章讲了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. 1.3 jQuery基础

    使用jQuery需要引用jQuery文件(页面引用多个js文件时jQuery在最前面) <script src="jquery-1.11.2.min.js"></ ...

  2. SEO优化---学会建立高转化率的网站关键词库

    想要优化好一个网站,行业的分析,以及关键词的挖掘是必要的,有一定的关键词排名了,但是转化率和流量方面却很不理想这种情况大部分是只注重了有指数的关键词排名,而忽略了长尾关键词和一些没有指数但是可以带来巨 ...

  3. Codeforces 721E Road to Home

    题意 输入第一行有4个数,分别为\(L,n,p,t\),分别表示总长度为\(L\)的路,中间有\(n\)个互不相交的区间,现在要用长度为\(p\)的小木棒从左往右铺路(木棒不能被折断,也不能有重叠,且 ...

  4. 图片采用base64压缩,可以以字符串的形式传送base64给服务端转存为图片

    (function () { var coverImage = document.querySelector('<div id="coverImage">file< ...

  5. 简述HTML DOM及其节点分类

    在JavaScript中,document这个对象大家一定很熟悉,哪怕是刚刚开始学习的新人,也会很快接触到这个对象.而document对象不仅仅是一个普通的JavaScript内置对象,它还是一个巨大 ...

  6. HTTP 使用期及新鲜度算法

    使用期算法: /* * age_value 当代理服务器用自己的头部去响应请求时,Age标明实体产生到现在多长时间了. * date_value HTTP 服务器应答中的Date字段 原始服务器 * ...

  7. 图片Base64编码

    我们经常在做Jquery插件的时候需要插入一些自定义的控件,比如说按钮,而我们自己又觉着button标签很丑,而且不同浏览器显示的效果还不一样,这个时候我们需要用到图片,当然,我们可以通过img标签添 ...

  8. ios 数据库存储json数据

    NSData *data = [NSJSONSerialization dataWithJSONObject:info.bdata options:NSJSONWritingPrettyPrinted ...

  9. JAVA_javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name

    tomcat访问https请求返回: javax.net.ssl.SSLProtocolException: handshake alert:  unrecognized_name at sun.se ...

  10. 2015-12-23-( dispaly:table的用法)

    dispaly属性的table和table-cell属性值不怎么常用,主要是浏览器的兼容性不好,大多数都是为了兼容IE6.IE7,此属性IE8以上,谷歌,火狐,oprea等浏览器都支持.  此disp ...