江湖上传闻,面向对象之所以厉害,是因为它拥有封装、继承与多态三项神技,只要三板斧一出,号令天下谁敢不从。前面费了老大的劲才讲清楚封装和继承,那么多态又是怎样的神乎其神呢?下面先通过一个简单的例子来说明多态的使用场景。
首先把鸡这种家禽通过面向对象来表达,方便起见只定义两个属性(名称和性别),以及一个call方法,定义好的鸡类代码如下所示:

//定义一个鸡类
public class Chicken { // 定义一个名称属性
public String name;
// 定义一个性别属性
public int sex; // 定义一个叫唤方法
public void call() {
System.out.println("半夜鸡叫");
}
}

接着从上面的Chicken类派生出公鸡类Cock,将公鸡的性别固定设置为雄性,同时重写call这个叫唤方法。公鸡类的代码示例如下:

//定义一个继承自鸡类的公鸡类
public class Cock extends Chicken { public Cock() {
// 公鸡的性别固定为雄性
sex = 0;
} // 重写了公鸡的叫唤方法
public void call() {
System.out.println("喔喔喔");
}
}

同样编写母鸡类Hen继承自Chicken类,将母鸡的性别固定设置为雌性,同时重写call这个叫唤方法。母鸡类的代码示例如下:

//定义一个继承自鸡类的母鸡类
public class Hen extends Chicken { public Hen() {
// 母鸡的性别固定为雌性
sex = 1;
} // 重写了母鸡的叫唤方法
public void call() {
System.out.println("咯咯咯");
}
}

最后在外部创建一个Chicken鸡类的实例,先将公鸡实例赋值给这个鸡类实例chicken,紧接着调用chicken的call方法;再将母鸡实例赋值给鸡类实例chicken,紧接着调用chicken的call方法。按此步骤编写的测试调用代码见下:

//演示类的多态性
public class TestChicken { public static void main(String[] args) {
// 鸡类的实例变成了一只公鸡
Chicken chicken = new Cock();
// 此时鸡类的叫声就变为公鸡的叫声
chicken.call();
// 鸡类的实例变成了一只母鸡
chicken = new Hen();
// 此时鸡类的叫声就变为母鸡的叫声
chicken.call();
}
}

运行以上的测试代码,观察到以下的日志信息:

喔喔喔
咯咯咯

由日志结果可见,尽管chicken本来是鸡类的实例,然而两次调用chicken的call方法,却没有输出鸡类的叫声,而是先后打印了公鸡类的叫声和母鸡类的叫声。这个现象便是多态特性的一个实际运用,所谓多态,意思是有多种状态,好比古人的卸甲归田,穿上盔甲去打仗就是士兵,卸下盔甲去种田就是农民。多态的实现依赖于继承,先声明一个父类的实例,再于合适之时给它分别赋予不同的子类实例,此后操作该实例就仿佛操作子类的实例一般。
引入多态概念的好处是,只要某些类型都从同一个父类派生而来,就能在方法内部把它们当作同一种类型来处理,而无需区分具体的类型。仍以鸡叫为例,不管是公鸡叫还是母鸡叫,都是某种鸡在叫,于是完全可以定义一个叫唤方法,根据输入的鸡参数,让这只鸡自己去叫即可。叫唤方法的具体代码如下所示:

	// 定义一个叫唤方法,传入什么鸡,就让什么鸡叫
private static void call(Chicken chicken) {
chicken.call();
}

这下有了通用的鸡叫方法,外部就能把鸡类的实例作为输入参数填进去。当输入参数为公鸡实例的时候,call方法上演的是公鸡喔喔叫;当输入参数为母鸡实例的时候,call方法上演的是母鸡咯咯叫。

		call(new Cock()); // 公鸡叫
call(new Hen()); // 母鸡叫

  

更多Java技术文章参见《Java开发笔记(序)章节目录

Java开发笔记(五十一)多态的发生场景的更多相关文章

  1. Java开发笔记(十一)常见的数学函数

    前面介绍了Java编程的四则运算,虽然提供了基础的加减乘除符号,但是数学上还有其它运算符号,包括四舍五入用到的约等号≍.求绝对值的“| |”.开平方的“√ ̄”,这些运算符形态各异,而且并非ASCII码 ...

  2. Java开发笔记(序)章节目录

    现将本博客的Java学习文章整理成以下笔记目录,方便查阅. 第一章 初识JavaJava开发笔记(一)第一个Java程序Java开发笔记(二)Java工程的帝国区划Java开发笔记(三)Java帝国的 ...

  3. Java开发笔记(一百五十一)Druid连接池的用法

    C3P0连接池自诞生以来在Java Web领域反响甚好,业已成为hibenate框架推荐的连接池.谁知人红是非多,C3P0在大型应用场合中暴露了越来越多的局限性,包括但不限于下列几点:1.C3P0管理 ...

  4. Java开发笔记(五十三)关键字final的用法

    前面介绍了多态的相关用法,可以看到一个子类从父类继承之后,便能假借父类的名义到处晃悠.这种机制在正常情况之下没啥问题,但有时为了预防意外发生,往往只接受当事人来处理,不希望它的儿子乃至孙子来瞎掺和.可 ...

  5. Java开发笔记(八十五)通过字符流读写文件

    前面介绍了文件的信息获取.管理操作,以及目录下的文件遍历,那么文件内部数据又是怎样读写的呢?这正是本文所要阐述的内容.File工具固然强大,但它并不能直接读写文件,而要借助于其它工具方能开展读写操作. ...

  6. Java开发笔记(八十一)如何使用系统自带的注解

    之前介绍继承的时候,提到对于子类而言,父类的普通方法可以重写也可以不重写,但是父类的抽象方法是必须重写的,如果不重写,编译器就直接在子类名称那里显示红叉报错.例如,以前演示抽象类用法之时,曾经把Chi ...

  7. Java开发笔记(四十五)成员属性与成员方法

    前面介绍了许多数据类型,除了基本类型如整型int.双精度型double.布尔型boolean之外,还有高级一些的如包装整型Integer.字符串类型String.本地日期类型LocalDate等等,那 ...

  8. Java开发笔记(六十五)集合:HashSet和TreeSet

    对于相同类型的一组数据,虽然Java已经提供了数组加以表达,但是数组的结构实在太简单了,第一它无法直接添加新元素,第二它只能按照线性排列,故而数组用于基本的操作倒还凑合,若要用于复杂的处理就无法胜任了 ...

  9. Java开发笔记(七十五)异常的处理:扔出与捕捉

    前面介绍的几种异常(不包含错误),编码的时候没认真看还发现不了,直到程序运行到特定的代码跑不下去了,程序员才会恍然大悟:原来这里的代码逻辑有问题.像这些在运行的时候才暴露出来的异常,又被称作“运行时异 ...

随机推荐

  1. Oracle 闪回 找回数据

    使用闪回技术,实现基于磁盘上闪回恢复区的自动备份与还原. 一.恢复表对象 1.创建学生表 create table STUDENT ( idno INTEGER, name VARCHAR2(30), ...

  2. mysql中Table is read only的解决方法

    首先去到mysq的bin目录 cd /usr/local/mysql/bin 执行如下mysqladmin ./mysqladmin -p flush-tables 接着输入数据库存的root密码即可

  3. unittest测试套件

    测试套件就是测试集,测试集是测试用例的集合. a.按用例顺序执行(addtest) 当addtest与unittest的测试规则冲突时,仍然按照ASCII码的顺序执行. import unittest ...

  4. Windows 查询端口占用

    1.找到端口的进程ID(PID)(例如:8080) Windows系统: netstat -ao | find " Windows以外的其他平台: lsof -i: 2.杀死你找到的进程ID ...

  5. FCC(ES6写法) Inventory Update

    依照一个存着新进货物的二维数组,更新存着现有库存(在 arr1 中)的二维数组. 如果货物已存在则更新数量 . 如果没有对应货物则把其加入到数组中,更新最新的数量. 返回当前的库存数组,且按货物名称的 ...

  6. LVM学习笔记

    LVM Logical Volume Manager Volume management creates a layer of abstraction over physical storage, a ...

  7. 非对称加密技术中,iFace [ 爱妃链 ]人脸密钥技术排名第三,将弥补区块链现有不足

    最近,区块链领域,出现了一个比较热门技术的讨论,人脸密钥技术,可能大家还对这个名词感到很陌生,但是熟悉加密技术的技术大牛可能一听就能够明白大体的意思了,但是也正是这一熟悉而陌生的技术名词,掀起了区块链 ...

  8. java中子类继承父类程序执行顺序问题

    Java中,new一个类的对象,类里面的静态代码块.非静态代码.无参构造方法.有参构造方法.类的一般方法等部分,它们的执行顺序相对来说比较简单,用程序也很容易验证.比如新建一个测试父类. public ...

  9. Python内置函数(19)——eval

    英文文档: eval(expression, globals=None, locals=None) The arguments are a string and optional globals an ...

  10. UE4 打包C++项目到win32平台报错 could not find mspdbcore.dll

    解决方法: 将Visual Studio中相应系统(如32位对应x86.64位对应x64)下的 ms.*.dll 等一系列文件拷贝到 C:\Windows\System32\ 路径下.踩坑:不能只拷贝 ...