java 泛型 多态_Java 多态
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 多态相关推荐
- java泛型特点_java泛型简单总结
Java泛型简单总结 1)基本概念: 泛型(Generic Type或Generics)是 对Java语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看做是使用参数化类型时 ...
- java 泛型 恶心_Java的泛型原来这样让人不舒服
Type erasure Java泛型中的类型擦除,意为只在编译时刻进行类型检查,实际在运行时,编译器会自动插入相应的转换(cast)代码. List list = new ArrayList(); ...
- java泛型面试_Java泛型面试问题
java泛型面试 Java面试中的通用面试问题在相当长的时间内在Java 5周围越来越普遍,许多应用程序都转移到Java 5上,并且几乎所有新的Java开发都发生在Tiger(Java 5的代号)上. ...
- java泛型视频教程_Java泛型快速教程
java泛型视频教程 泛型是Java SE 5.0引入的一种Java功能,在其发布几年后,我发誓那里的每个Java程序员不仅会听说过,而且已经使用过. 关于Java泛型,有很多免费和商业资源,而我使用 ...
- java 泛型 擦除_Java泛型和类型擦除
一 前言:初识泛型 废话不说,先来看一段代码: public class Holder { private Object data; public Holder(Object data ){ this ...
- java泛型 包_Java泛型应用浅析
Java泛型应用浅析 Java泛型,饿,这个东西吗,嚼一下还是有必要的.有啥用呢?小弟曾觉着吧,吹牛是条不错的出路,但没一次没有不吹破的.(绕吧^_^) 详解呢,没啥必要了,参见附件解压后Java泛型 ...
- java泛型实例化_java基础-泛型举例详解
泛型 泛型是JDK5.0增加的新特性,泛型的本质是参数化类型,即所操作的数据类型被指定为一个参数.这种类型参数可以在类.接口.和方法的创建中,分别被称为泛型类.泛型接口.泛型方法. 一.认识泛型 在没 ...
- java 泛型示例_Java泛型示例教程–泛型方法,类,接口
java 泛型示例 Java Genrics is one of the most important features introduced in Java 5. Java Genrics是Java ...
- java 泛型参数_Java泛型
一.概述 Java泛型(generics)是JDK 5中引入的一个新特性,泛型提供了编译时类型安全监测机制,该机制允许程序员在编译时监测非法的类型.使用泛型机制编写的程序代码要比那些杂乱地使用Obje ...
- java 泛型转换_Java泛型—类型转换
如下代码编译无法通过: classA{}class B extendsA {}public static void funC(ListlistA) {//... }public static void ...
最新文章
- iOS开发网络——数据缓存
- java 系统 类_JAVA系统类 System的简单整理
- OpenCASCADE:Open CASCADE Application Framework (OCAF)的简介
- python科学计算笔记(一)NumPy中ndarray对象、ufunc运算、矩阵运算
- SpringBoot:搭建第一个Web程序
- .NET Core微服务之基于Exceptionless实现分布式日志记录
- 王者体验服服务器注册人数已满,王者荣耀体验服注册人数达到上限怎么回事?体验服测试最新申请方法...
- java正则表达式匹配xml标签_用正则表达式匹配HTML\XML等文件中的标签
- skcket编程实例
- HTML的iframe标签的滚动条
- libsvm3.22——在matlab(32位和64位)中的安装
- 【UWB】UWB基本定位原理
- Android:手机号码归属地查询
- 300W-LP数据库介绍
- oracle编程弹框函数,取窗口句柄的api函数
- url地址中有特殊符号“引号”引发的错误
- Tensorflow学习之tf.keras(一) tf.keras.layers.BatchNormalization
- 单片机c语言中p1asf,基于51单片机的蓄水池自动控制系统 毕业设计.doc
- js控制,监听 浏览器全屏
- lua和python谁更适用于嵌入MMORPG?