Java 多态

多态是同一个行为具有多个不同表现形式或形态的能力。

多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:

多态性是对象多种表现形式的体现。

现实中,比如我们按下 F1 键这个动作:

如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;

如果当前在 Word 下弹出的就是 Word 帮助;

在 Windows 下弹出的就是 Windows 帮助和支持。

同一个事件发生在不同的对象上会产生不同的结果。

多态的优点1. 消除类型之间的耦合关系

2. 可替换性

3. 可扩充性

4. 接口性

5. 灵活性

6. 简化性

多态存在的三个必要条件

继承

重写

父类引用指向子类对象:Parent p = new Child();

class Shape {

void draw() {}

}

class Circle extends Shape {

void draw() {

System.out.println("Circle.draw()");

}

}

class Square extends Shape {

void draw() {

System.out.println("Square.draw()");

}

}

class Triangle extends Shape {

void draw() {

System.out.println("Triangle.draw()");

}

}

当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。

多态的好处:可以使程序有良好的扩展,并可以对所有类的对象进行通用处理。

以下是一个多态实例的演示,详细说明请看注释:

Test.java 文件代码:

publicclassTest{publicstaticvoidmain(String[]args){show(newCat());//以 Cat 对象调用 show 方法show(newDog());//以 Dog 对象调用 show 方法Animala=newCat();//向上转型a.eat();//调用的是 Cat 的 eatCatc=(Cat)a;//向下转型c.work();//调用的是 Cat 的 work}publicstaticvoidshow(Animala){a.eat();//类型判断if(ainstanceofCat){//猫做的事情Catc=(Cat)a;c.work();}elseif(ainstanceofDog){//狗做的事情Dogc=(Dog)a;c.work();}}}abstractclassAnimal{abstractvoideat();}classCatextendsAnimal{publicvoideat(){System.out.println("吃鱼");}publicvoidwork(){System.out.println("抓老鼠");}}classDogextendsAnimal{publicvoideat(){System.out.println("吃骨头");}publicvoidwork(){System.out.println("看家");}}

执行以上程序,输出结果为:

吃鱼

抓老鼠

吃骨头

看家

吃鱼

抓老鼠

虚函数

虚函数的存在是为了多态。

Java 中其实没有虚函数的概念,它的普通函数就相当于 C++ 的虚函数,动态绑定是Java的默认行为。如果 Java 中不希望某个函数具有虚函数特性,可以加上 final 关键字变成非虚函数。

重写

我们将介绍在 Java 中,当设计类时,被重写的方法的行为怎样影响多态性。

我们已经讨论了方法的重写,也就是子类能够重写父类的方法。

当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。

要想调用父类中被重写的方法,则必须使用关键字 super。

Employee.java 文件代码:

/*文件名 : Employee.java*/publicclassEmployee{privateStringname;privateStringaddress;privateintnumber;publicEmployee(Stringname,Stringaddress,intnumber){System.out.println("Employee 构造函数");this.name=name;this.address=address;this.number=number;}publicvoidmailCheck(){System.out.println("邮寄支票给:"+this.name+""+this.address);}publicStringtoString(){returnname+""+address+""+number;}publicStringgetName(){returnname;}publicStringgetAddress(){returnaddress;}publicvoidsetAddress(StringnewAddress){address=newAddress;}publicintgetNumber(){returnnumber;}}

假设下面的类继承Employee类:

Salary.java 文件代码:

/*文件名 : Salary.java*/publicclassSalaryextendsEmployee{privatedoublesalary;//全年工资publicSalary(Stringname,Stringaddress,intnumber,doublesalary){super(name,address,number);setSalary(salary);}publicvoidmailCheck(){System.out.println("Salary 类的 mailCheck 方法");System.out.println("邮寄支票给:"+getName()+",工资为:"+salary);}publicdoublegetSalary(){returnsalary;}publicvoidsetSalary(doublenewSalary){if(newSalary>=0.0){salary=newSalary;}}publicdoublecomputePay(){System.out.println("计算工资,付给:"+getName());returnsalary/52;}}

现在我们仔细阅读下面的代码,尝试给出它的输出结果:

VirtualDemo.java 文件代码:

/*文件名 : VirtualDemo.java*/publicclassVirtualDemo{publicstaticvoidmain(String[]args){Salarys=newSalary("员工 A","北京",3,3600.00);Employeee=newSalary("员工 B","上海",2,2400.00);System.out.println("使用 Salary 的引用调用 mailCheck --");s.mailCheck();System.out.println("\n使用 Employee 的引用调用 mailCheck--");e.mailCheck();}}

以上实例编译运行结果如下:

Employee 构造函数

Employee 构造函数

使用 Salary 的引用调用 mailCheck --

Salary 类的 mailCheck 方法

邮寄支票给:员工 A ,工资为:3600.0

使用 Employee 的引用调用 mailCheck--

Salary 类的 mailCheck 方法

邮寄支票给:员工 B ,工资为:2400.0

例子解析

实例中,实例化了两个 Salary 对象:一个使用 Salary 引用 s,另一个使用 Employee 引用 e。

当调用 s.mailCheck() 时,编译器在编译时会在 Salary 类中找到 mailCheck(),执行过程 JVM 就调用 Salary 类的 mailCheck()。

e 是 Employee 的引用,但引用 e 最终运行的是 Salary 类的 mailCheck() 方法。

在编译的时候,编译器使用 Employee 类中的 mailCheck() 方法验证该语句,

但是在运行的时候,Java虚拟机(JVM)调用的是 Salary 类中的 mailCheck() 方法。

以上整个过程被称为虚拟方法调用,该方法被称为虚拟方法。

Java中所有的方法都能以这种方式表现,因此,重写的方法能在运行时调用,不管编译的时候源代码中引用变量是什么数据类型。

多态的实现方式

方式一:重写:

这个内容已经在上一章节详细讲过,就不再阐述,详细可访问:Java 重写(Override)与重载(Overload)。

方式二:接口

1. 生活中的接口最具代表性的就是插座,例如一个三接头的插头都能接在三孔插座中,因为这个是每个国家都有各自规定的接口规则,有可能到国外就不行,那是因为国外自己定义的接口类型。

2. java中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现。具体可以看 java接口 这一章节的内容。

方式三:抽象类和抽象方法

详情请看 Java抽象类 章节。

java 泛型 多态_Java 多态相关推荐

  1. java泛型特点_java泛型简单总结

    Java泛型简单总结 1)基本概念: 泛型(Generic Type或Generics)是 对Java语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看做是使用参数化类型时 ...

  2. java 泛型 恶心_Java的泛型原来这样让人不舒服

    Type erasure Java泛型中的类型擦除,意为只在编译时刻进行类型检查,实际在运行时,编译器会自动插入相应的转换(cast)代码. List list = new ArrayList(); ...

  3. java泛型面试_Java泛型面试问题

    java泛型面试 Java面试中的通用面试问题在相当长的时间内在Java 5周围越来越普遍,许多应用程序都转移到Java 5上,并且几乎所有新的Java开发都发生在Tiger(Java 5的代号)上. ...

  4. java泛型视频教程_Java泛型快速教程

    java泛型视频教程 泛型是Java SE 5.0引入的一种Java功能,在其发布几年后,我发誓那里的每个Java程序员不仅会听说过,而且已经使用过. 关于Java泛型,有很多免费和商业资源,而我使用 ...

  5. java 泛型 擦除_Java泛型和类型擦除

    一 前言:初识泛型 废话不说,先来看一段代码: public class Holder { private Object data; public Holder(Object data ){ this ...

  6. java泛型 包_Java泛型应用浅析

    Java泛型应用浅析 Java泛型,饿,这个东西吗,嚼一下还是有必要的.有啥用呢?小弟曾觉着吧,吹牛是条不错的出路,但没一次没有不吹破的.(绕吧^_^) 详解呢,没啥必要了,参见附件解压后Java泛型 ...

  7. java泛型实例化_java基础-泛型举例详解

    泛型 泛型是JDK5.0增加的新特性,泛型的本质是参数化类型,即所操作的数据类型被指定为一个参数.这种类型参数可以在类.接口.和方法的创建中,分别被称为泛型类.泛型接口.泛型方法. 一.认识泛型 在没 ...

  8. java 泛型示例_Java泛型示例教程–泛型方法,类,接口

    java 泛型示例 Java Genrics is one of the most important features introduced in Java 5. Java Genrics是Java ...

  9. java 泛型参数_Java泛型

    一.概述 Java泛型(generics)是JDK 5中引入的一个新特性,泛型提供了编译时类型安全监测机制,该机制允许程序员在编译时监测非法的类型.使用泛型机制编写的程序代码要比那些杂乱地使用Obje ...

  10. java 泛型转换_Java泛型—类型转换

    如下代码编译无法通过: classA{}class B extendsA {}public static void funC(ListlistA) {//... }public static void ...

最新文章

  1. iOS开发网络——数据缓存
  2. java 系统 类_JAVA系统类 System的简单整理
  3. OpenCASCADE:Open CASCADE Application Framework (OCAF)的简介
  4. python科学计算笔记(一)NumPy中ndarray对象、ufunc运算、矩阵运算
  5. SpringBoot:搭建第一个Web程序
  6. .NET Core微服务之基于Exceptionless实现分布式日志记录
  7. 王者体验服服务器注册人数已满,王者荣耀体验服注册人数达到上限怎么回事?体验服测试最新申请方法...
  8. java正则表达式匹配xml标签_用正则表达式匹配HTML\XML等文件中的标签
  9. skcket编程实例
  10. HTML的iframe标签的滚动条
  11. libsvm3.22——在matlab(32位和64位)中的安装
  12. 【UWB】UWB基本定位原理
  13. Android:手机号码归属地查询
  14. 300W-LP数据库介绍
  15. oracle编程弹框函数,取窗口句柄的api函数
  16. url地址中有特殊符号“引号”引发的错误
  17. Tensorflow学习之tf.keras(一) tf.keras.layers.BatchNormalization
  18. 单片机c语言中p1asf,基于51单片机的蓄水池自动控制系统 毕业设计.doc
  19. js控制,监听 浏览器全屏
  20. lua和python谁更适用于嵌入MMORPG?

热门文章

  1. 【Android】日常问题记录
  2. Java JUC学习 - ConcurrentLinkedDeque 详解
  3. Golang 学习笔记(08)—— 文件操作
  4. 算法踩坑4-冒泡排序
  5. linux模块导出符号 EXPORT_SYMBOL_GPLEXPORT_SYMBOL(转)
  6. Memcahce(MC)系列(三)Memcached它PHP转让
  7. Fckeditor漏洞汇总
  8. 面试问题大全(不断添加中)
  9. ssh 免密登录并用脚本群起服务
  10. 关于游戏小说与学习知识的不同