Java 多态的特性和概念

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

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

image

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

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

如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
如果当前在 Word 下弹出的就是 Word 帮助;
在 Windows 下弹出的就是 Windows 帮助和支持。
同一个事件发生在不同的对象上会产生不同的结果。

多态的优点

  1. 消除类型之间的耦合关系
  2. 可替换性
  3. 可扩充性
  4. 接口性
  5. 灵活性
  6. 简化性
    多态存在的三个必要条件

继承
重写
父类引用指向子类对象
比如:

public class Test {

public static void main(String[] args) {

show(new Cat()); // 以 Cat 对象调用 show 方法

show(new Dog()); // 以 Dog 对象调用 show 方法

Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}

public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}

abstract class Animal {

abstract void eat();

}

class Cat extends Animal {

public void eat() {

System.out.println("吃鱼");

}

public void work() {

System.out.println("抓老鼠");

}

}

class Dog extends Animal {

public void eat() {

System.out.println("吃骨头");

}

public void work() {

System.out.println("看家");

}

}

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

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

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

吃鱼

抓老鼠

吃骨头

看家

吃鱼

抓老鼠

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

虚方法

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

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

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

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

Employee.java 文件代码:

/ 文件名 : Employee.java /

public class Employee {

private String name;

private String address;

private int number;

public Employee(String name, String address, int number) {

System.out.println("Employee 构造函数");

this.name = name;

this.address = address;

this.number = number;

}

public void mailCheck() {

System.out.println("邮寄支票给: " + this.name

  • " " + this.address);

}

public String toString() {

return name + " " + address + " " + number;

}

public String getName() {

return name;

}

public String getAddress() {

return address;

}

public void setAddress(String newAddress) {

address = newAddress;

}

public int getNumber() {

return number;

}

}

假设下面的类继承Employee类:

/ 文件名 : Salary.java /

public class Salary extends Employee

{

private double salary; // 全年工资

public Salary(String name, String address, int number, double salary) {

super(name, address, number);

setSalary(salary);

}

public void mailCheck() {

System.out.println("Salary 类的 mailCheck 方法 ");

System.out.println("邮寄支票给:" + getName()

  • " ,工资为:" + salary);

}

public double getSalary() {

return salary;

}

public void setSalary(double newSalary) {

if(newSalary >= 0.0) {

salary = newSalary;

}

}

public double computePay() {

System.out.println("计算工资,付给:" + getName());

return salary/52;

}

}

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

/ 文件名 : VirtualDemo.java /

public class VirtualDemo {

public static void main(String [] args) {

Salary s = new Salary("员工 A", "北京", 3, 3600.00);

Employee e = new Salary("员工 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 的 mailCheck() 方法时,编译器会去 Employee 类查找 mailCheck() 方法 。
在编译的时候,编译器使用 Employee 类中的 mailCheck() 方法验证该语句, 但是在运行的时候,Java虚拟机(JVM)调用的是 Salary 类中的 mailCheck() 方法。
以上整个过程被称为虚拟方法调用,该方法被称为虚拟方法。

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

多态的实现方式

方式一:重写:

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

方式二:接口

  1. 生活中的接口最具代表性的就是插座,例如一个三接头的插头都能接在三孔插座中,因为这个是每个国家都有各自规定的接口规则,有可能到国外就不行,那是因为国外自己定义的接口类型。
  2. java中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现。具体可以看 java接口 这一章节的内容。

原文地址:https://blog.51cto.com/14226273/2384665

时间: 2024-10-10 15:57:28

Java 多态的特性和概念的相关文章

黑马程序猿——JAVA面向对象的特性:封装,继承,多态

                                       - ----------android培训.java培训.java学习型技术博客.期待与您交流!------------  一.java面向对象的特性.封装.继承.多态         封装 封装是对象和类概念的主要特性. 封装.也就是把客观事物封装成抽象的类.而且类能够把自己的数据和方法仅仅让可信的类或者对象操作,对不可信的进行信息隐藏. 继承 面向对象编程 (OOP) 语言的一个主要功能就是"继承".继承

黑马程序员——JAVA面向对象的特性:封装,继承,多态

                                       - ----------android培训.java培训.java学习型技术博客.期待与您交流!------------  一.java面向对象的特性,封装.继承.多态         封装 封装是对象和类概念的主要特性. 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏. 继承 面向对象编程 (OOP) 语言的一个主要功能就是"继承".继承是

(1) 深入理解Java面向对象三大特性 封装 继承 多态

转眼已经工作快6年了,最开始做了2年J2EE:然后整了2年的数据仓库,主要是Cognos的报表开发:现在从事4G LTE核心网的开发,用的语言任然是Java,但写代码的机会不多,基本都是看代码找BUG,偶尔做点new feature也是在比较成熟的框架上复制.粘贴.修改,大部分时间还是在理解业务,钱多.事少.离家近,当时来这家公司图的是后面2点,2年过去了,英文水平有所提升,对敏捷开放也有一定的了解,但技术方面明显退步了或者说没有进步吧,本来以前也不怎么好,因为工作上用不到,自己也没怎么学习,所

java提高篇(四)_理解java的三大特性之多态 转自 http://cmsblogs.com

多态就是指程序中定义 的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该 引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定.因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让 引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个 运行状态,这就是多态性 一. 向上转型

Java多态特性:重载和覆写的比较

Java重载: 在同一个类中 方法具有相同的名字,相同或不同的返回值,但参数不同的多个方法(参数个数或参数类型) public class MethoDemo{ public static void main(String args[]){ int one = add(10,20) ; // 调用整型的加法操作 float two = add(10.3f,13.3f) ; // 调用浮点数的加法操作 int three = add(10,20,30) ; // 调用有三个参数的加法操作 Syst

[转]理解java的三大特性之多态

java提高篇(四)-----理解java的三大特性之多态 面向对象编程有三大特性:封装.继承.多态. 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法. 继承是为了重用父类代码.两个类若存在IS-A的关系就可以使用继承.,同时继承也为实现多态做了铺垫.那么什么是多态呢?多态的实现机制又是什么?请看我一一为你揭开: 所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在

java多态中哪些成员具备多态特性

在多态的学习中,当子类继承父类时,子类中的变量哪些具备多态特性,哪些不具备多特特性. 代码: class Father{ public static int x=10; public int y=11; public Father(){ System.out.println("Father"); } public static void info(){ System.out.println("Father's static info method!"); } pub

Java面向对象-面向对象编程之基本概念

面向对象这个概念,每本书上的说法定义很多. 我自己根据我的经验,自己归档总结了下, 所谓面向对象,就是 以基于对象的思维去分析和解决问题,万物皆对象: 面向对象经常和面向过程放一起讨论: 这里举例, 比如要造一辆自行车,假如以面向过程的思维搞,张三先搞轮子, 李四再搞车架,王五再搞链条,赵六再搞脚踏板...最终拼拼凑凑,搞出一辆勉强能骑的车: 但是,假如某个部件要调整下,其他部件要调整的东西太多了,有时候搞不好还得重头开始搞: 面向过程的缺点就是 扩展性 维护性差,但是也是有优点的,就是速度快:

深入理解JAVA多态原理

之前一直知道多态是什么东西,平时敲代码也经常用到多态,但一直没有真正了解多态底层的运行机制到底是怎么样的,这两天才研究明白点,特地写下来,跟各位同学一起进步,同时也希望各位大神指导和指正. 多态的概念:同一操作作用于不同对象,可以有不同的解释,有不同的执行结果,这就是多态,简单来说就是:父类的引用指向子类对象.下面先看一段代码 1 package polymorphism; 2 3 class Dance { 4 public void play(){ 5 System.out.println(