如题,本文重点不在于介绍什么是多态,所以一些基础的概念就不多说了(需要知道的时候会提一下)。要了解多态的话这里推荐一篇 http://www.cnblogs.com/jack204/archive/2012/10/29/2745150.html
本文要解释的例子也是这篇文章里面的,代码如下:

相关类

class A {
    public String show(D obj) {
        return ("A and D");
    }
    public String show(A obj) {
        return ("A and A");
    }
}
class B extends A {
    public String show(B obj) {
        return ("B and B");
    }
    public String show(A obj) {
        return ("B and A");
    }
}
class C extends B {}
class D extends B {}

思考以下输出结果

A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();

System.out.println("1--" + a1.show(b)); // 1--A and A
System.out.println("2--" + a1.show(c)); // 2--A and A
System.out.println("3--" + a1.show(d)); // 3--A and D
System.out.println("4--" + a2.show(b)); // 4--B and A
System.out.println("5--" + a2.show(c)); // 5--B and A
System.out.println("6--" + a2.show(d)); // 6--A and D
System.out.println("7--" + b.show(b));  // 7--B and B
System.out.println("8--" + b.show(c));  // 8--B and B
System.out.println("9--" + b.show(d));  // 9--A and D

为了方便查看,我把程序的输出结果以注释的形式写在代码里了。上面的代码前3个很好理解,从第4个开始可能很多人就会觉得有一些奇怪了(为什么输出的不是B and B),其实要理解这个很容易,只要默想一下几个基本概念就行了:

  • 什么是重写 (其中一个要求是:参数列表必须与被重写方法的相同)
  • 向上转型和向下转型 (类似于int和long之间的自动转换和强制转换,向上->子转父->自动,向下->父转子->需强制)
  • 理解一句话:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。
    (也就是说 View v = new TextView(context),v.setBackground()的话优先调用TextView的setBackground,如果TextView没有重写setBackground的话才调用父类View的setBackground)

上面的3点一定要理解括号里面说的,下面有用


解释第4点

A a2 = new B();
B b = new B();
System.out.println("4--" + a2.show(b));
输出结果:4--B and A

对于 a2.show(b) ,先看a2是什么类型,没错,是A类型的,A类里面有哪些方法呢,看一眼并没有参数是B的show方法,所以a2.show(b)并不会调用B类里面参数是B的方法 (B类里面参数是B的show方法并不是重写的父类方法,它是B类自己的方法,可以加@Override看看报错不,所以A类型的引用a2调不到这个方法),这就是输出结果不是 B and B 的原因。

然后输出结果为什么是B and A?首先不难想到调用的是 show(A obj) 这个参数是A的方法(自动向上转型),又因为子类B重写了这个方法,所以调用了子类里面的show(A obj)方法(这就是要理解的那个:超类引用变量引用子类对象如果子类重写了方法优先调用子类的方法)

好了,根据第4点的理解思路,其他几个应该很容易看懂了

Java-多态的理解(主要是解释一个网上经典的例子)的更多相关文章

  1. 关于Java中的继承和组合的一个错误使用的例子

    [TOC] 关于Java中的继承和组合的一个错误使用的例子 相信绝大多数人都比较熟悉Java中的「继承」和「组合」这两个东西,本篇文章就主要就这两个话题谈论一下.如果我某些地方写的不对,或者比较幼稚, ...

  2. 关于java多态的理解

    要理解多态,就必须有一个大的理解方向,不然很容易绕进去. 首先知道多态的释义:多态性是指一个名词可以有多种语义. 对于java的多态性学习者来说,就是必须要知道多个同名方法在不同情况下的使用规则. j ...

  3. Java经验杂谈(2.对Java多态的理解)

    多态是面向对象的重要特性之一,我试着用最简单的方式解释Java多态: 要正确理解多态,我们需要明确如下概念:・定义类型和实际类型・重载和重写・编译和运行 其中实际类型为new关键字后面的类型. 重载发 ...

  4. 对java多态的理解

    java多态,如何理解父类引用指向子类对象 要理解多态性,首先要知道什么是“向上转型”. 我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类.我可以通过 Cat c = new C ...

  5. Java多态-如何理解父类引用指向子类对象

    java多态,如何理解父类引用指向子类对象 要理解多态性,首先要知道什么是“向上转型”. 我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类.我可以通过   Cat c = new ...

  6. 考考你对java多态的理解

    请看如下代码, 如果你能不运行得出正确答案, 那你真的超过99%的java程序员了. [本人属于最大头的那部分] public class A{ public String s = "A&q ...

  7. java多态的理解

    面向对象语言中的类有三个特征,封装.继承.多态.封装与继承很好理解,那什么是多态呢? 1.什么是多态? 多态的定义:指允许不同类的对象对同一消息做出响应.即同一消息可以根据发送对象的不同而采用多种不同 ...

  8. java多态的理解----部分非原创

    所谓多态,其实就是对于同一件事情,不同的对象要采取不同的行为,或者同一个对象在不同的情况下需要采取不同的行为方式. 不同的对象要采取不同的行为: 这有两种实现方式:接口实现和子类重新父类方法.这两种实 ...

  9. JAVA学习笔记(一):一个小爬虫的例子

    1.import java.io.*;   java.io.*不是一个文件,而是一组类.它是在java.io包里的所有类,*是通配符,比如a*.txt代表的就是以a开头的所有txt文件,“?”是单个词 ...

随机推荐

  1. for_each_node(node)

    遍历各个pg_data_t节点. 1.定义在include/linux/nodemask.h中 /* * Bitmasks that are kept for all the nodes. */ en ...

  2. debian安装中文字体

    debian刚安装完成之后,因为没有中文字体,会出现方框. 安装中文字体: $ su # apt-get install fonts-arphic-bkai00mp fonts-arphic-bsmi ...

  3. selenium2-框架思想介绍

    为什么要有框架? 可维护性 提高编写脚本效率 提高脚本的可读性 框架的几大要素: 1. driver管理 2. 脚本 3. 数据 4. 元素对象 5. Log 6. 报告 7. 运行机制 8. 失败用 ...

  4. MFC 中 删除一个非空文件夹

    MFC中提供了删除文件夹的一个封装函数 RemoveDirectory(LPCTSTR lpPathName),我们只要把要删除的文件夹的路径传进去就可以删除了,貌似一切如此简单.我象征性的建立一个文 ...

  5. 03011_HttpServletRequest

    1.HttpServletRequest概述 (1)我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代 ...

  6. 【Netty】Netty入门之WebSocket小例子

    服务端: 引入Netty依赖 <!-- netty --> <dependency> <groupId>io.netty</groupId> <a ...

  7. luogu2564 [SCOI2009]生日礼物

    排序枚举左端点,则右端点必定不降 #include <algorithm> #include <iostream> #include <cstring> #incl ...

  8. 如何理解redo和undo的作用

    目录 如何理解redo和undo的作用 redo undo UNDO和REDO的区别 如何理解redo和undo的作用 redo 重做日志(redo)包含所有数据产生的历史改变记录,是oracle在线 ...

  9. 用virtualbox+模拟串口+CDT调试linux内核 TCP/IP协议栈-起步

    经常有人问一台机器如何将hello经网络发送给另一台机器,我确实是不知道,只能看代码了. 说明:本人对内核的研究学习也是刚刚起步,有很多不了解的,所以文中可能会有一些"一本正经的胡扯&quo ...

  10. 紫书第三章训练1 D - Crossword Answers

    A crossword puzzle consists of a rectangular grid of black and white squares and two lists of defini ...