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

    大家好今晚整理有关mybatis的添加删除修改更新的操作 一.select <!-- 查询学生,根据id --> <select id="getStudent" ...

  2. vue单页面应用刷新网页后vuex的state数据丢失的解决方案

    1. 产生原因其实很简单,因为store里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载vue实例,store里面的数据就会被重新赋值. 2. 解决思路一种是state里的数据全部是通过请求 ...

  3. EF Core中避免贫血模型的三种行之有效的方法(翻译)

    Paul Hiles: 3 ways to avoid an anemic domain model in EF Core 1.引言 在使用ORM中(比如Entity Framework)贫血领域模型 ...

  4. 通过net time同步电脑时间

    net use \\192.168.1.112\ipc$ admin /user:admin #第一个admin是密码,第二个admin是用户名: net time \\192.168.1.112 / ...

  5. 最新Java技术

    最近在网上查资料碰到好多没接触过的技术,先汇总在这里备用,以后慢慢吸收 1. JNA JNI的替代品,调用方式比JNI更直接,不再需要JNI那层中间接口,几乎达到Java直接调用动态库 2. Smal ...

  6. 事件派发dispatchEvent

    1.什么是dispatchEvent? dispatch意为"调度"."派遣",event为"事件".所以dispatchEvent即向指定 ...

  7. [Swift]LeetCode636. 函数的独占时间 | Exclusive Time of Functions

    Given the running logs of n functions that are executed in a nonpreemptive single threaded CPU, find ...

  8. [Swift]LeetCode706. 设计哈希映射 | Design HashMap

    Design a HashMap without using any built-in hash table libraries. To be specific, your design should ...

  9. jquery配合.NET实现点击指定绑定数据并且能够一键下载

    最近在做培训管理系统中遇到一个问题,需求需点击绑定的数据,将指定的附件下载下来,并且是批量下载(绑定的数据非datagrid,后台拼接的绑定). 效果图如下: 大体思路: 1.jquery得到选中的绑 ...

  10. Linux中FTP远程传输,SSH远程连接,以及SCP远程拷贝

    常用服务器ftp.ssh 1. Linux常用服务器构建-ftp服务器 ftp服务器 FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”. 用于 ...