深入解析Java多态进阶学习

目录
  • 1.动态绑定机制
    • 实例A
    • 实例B
    • 实例C
  • 2.多态数组
  • 3.多态数组的高阶用法
  • 4.多态参数
  • 5.多态参数的高阶用法

1.动态绑定机制

java的动态绑定机制非常重要

实例A

我们来看一个实例:

阅读上面的代码,请说明下面的程序将输出什么结果:

程序将会输出40和30,这个实例很简单,直接看运行类型即可,该代码的运行类型为B,所以会调用B类的方法

实例B

我们将上面的代码变通一下,将子类中的如下代码块注销:

随后继承机制会访问父类的sum方法:

那么这里有一个问题,此处的getI(),会执行子类的还是父类的呢?

当调用对象方法的时候,该方法会和该对象的内存地址/运行类型绑定

代码的运行类型依然是B,所以此处会执行子类的getI()方法,结果输出为30

实例C

现在我们再变通以下上面的代码

再将子类中如下的代码块注销:

继承机制会执行父类的sum1方法:

那么这里有一个问题,此处的i,会使用子类的还是父类的呢?

属性没有动态绑定机制,哪里声明,哪里使用(使用当前类的)

此处的i在父类进行声明,所以会选用父类的i属性,结果为20

2.多态数组

定义:

数组的定义类型为父类类型,但是保存的实际元素类型为子类类型

Person父类:

/**
 * 多态数组父类
 */
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String say() {
        return name + '\t' + age;
    }
}

Student子类:

/**
 * 多态数组学生子类
 */
public class Student extends Person{
    private double score;

    public Student(String name, int age, double score) {
        super(name, age);
        this.score = score;
    }

    // 重写父类的say方法
    public String say() {
        return super.say() + '\t' + score;
    }
}

Teacher子类:

/**
 * 多态数组教师子类
 */
public class Teacher extends Person {
    private double sal;

    public Teacher(String name, int age, double sal) {
        super(name, age);
        this.sal = sal;
    }

    public double getSal() {
        return sal;
    }

    public void setSal(double sal) {
        this.sal = sal;
    }

    public String say() {
        return super.say() + '\t' + sal;
    }
}

测试多态数组的使用:

public class Test {
    public static void main(String[] args) {
        // 多态数组的使用
        Person[] persons = new Person[5];
        persons[0] = new Person("dahe",20);
        persons[1] = new Student("wangwei",11,100);
        persons[2] = new Student("zhangsan",12,60);
        persons[3] = new Teacher("wang",33,15000);
        persons[4] = new Teacher("li",55,25000);

        // 循环遍历多态数组,调用say方法
        for (int i = 0; i < persons.length; i++) {
            String out = persons[i].say(); // 动态绑定机制,编译类型永远都是Person
            // 运行类型是根据实际情况由JVM机决定
            System.out.println(out);
        }
    }
}

输出:

dahe    20
wangwei    11    100.0
zhangsan    12    60.0
wang    33    15000.0
li    55    25000.0

3.多态数组的高阶用法

现在,教师子类新增了教学方法:

public void teach() {
    System.out.println("老师:" + getName() + "正在讲课!");
}

学生子类新增了学习方法:

public void study() {
    System.out.println("学生:" + getName() + "正在学习!");
}

那么,有没有办法通过多态数组来访问他们子类对应的独有的方法呢?事实上,可以通过巧妙使用instanceof来解决:

变通一下,改变多态数组的循环操作:

// 循环遍历多态数组,调用say方法
for (int i = 0; i < persons.length; i++) {
    String out = persons[i].say(); // 动态绑定机制,编译类型永远都是Person
    // 运行类型是根据实际情况由JVM机决定
    System.out.println(out);
    if (persons[i] instanceof Student) {
        // 向下转型
        Student student = (Student) persons[i];
        student.study();
    } else if (persons[i] instanceof Teacher) {
        Teacher teacher = (Teacher) persons[i];
        teacher.teach();
    }
}

输出:

dahe    20
wangwei    11    100.0
学生:wangwei正在学习!
zhangsan    12    60.0
学生:zhangsan正在学习!
wang    33    15000.0
老师:wang正在讲课!
li    55    25000.0
老师:li正在讲课!

大功告成!多态数组即强大又完美!

4.多态参数

方法定义的形参类型为父类类型,实参类型允许为子类类型

接下来我们来演示以下多态参数的使用:

父类:

/**
 * 多态参数 - 父类
 */
public class Employee {
    private String name;
    private double sal;

    public Employee(String name, double sal) {
        this.name = name;
        this.sal = sal;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getSal() {
        return sal;
    }

    public void setSal(double sal) {
        this.sal = sal;
    }

    // 得到年工资的方法
    public double getAnnual() {
        return 12 * sal;
    }
}

员工子类:

/**
 * 多态参数 - 子类员工
 */
public class Worker extends Employee{
    public Worker(String name, double sal) {
        super(name, sal);
    }

    public void work() {
        System.out.println("普通员工:" + getName() + "正在工作!");
    }

    public double getAnnual() {
        return super.getAnnual();
    }
}

经理子类:

/**
 * 多态参数 - 经理子类
 */
public class Manager extends Employee{
    private double bonus; // 奖金

    public Manager(String name, double sal, double bonus) {
        super(name, sal);
        this.bonus = bonus;
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }

    public void manage() {
        System.out.println("经理:" + getName() + "正在管理!");
    }

    @Override
    public double getAnnual() {
        return super.getAnnual() + bonus;
    }
}

我们来测试一下,求不同岗位的雇员的年薪:

/**
 * 多态参数测试类
 */
public class Test {
    public static void main(String[] args) {
        Worker zhang = new Worker("张工",1000);
        Manager milan = new Manager("milan", 5000, 2000);
        Test test = new Test();
        test.showEmpAnnual(zhang);
        test.showEmpAnnual(milan);
    }

    // 获取员工的年薪,采用多态参数
    public void showEmpAnnual(Employee e) {
        System.out.println(e.getAnnual());
    }
}

输出:

12000.0
62000.0

5.多态参数的高阶用法

我们来对上面的多态参数代码做一个完善,如果传入的是员工,则调用自己的work方法,如果传入的是经理,则调用自己的manage方法

增加一个下面的方法:

public void testWork(Employee e) {
    if (e instanceof Worker) {
        ((Worker) e).work(); // 向下转型
    } else if (e instanceof Manager) {
        ((Manager) e).manage();
    }
}

测试:

test.testWork(zhang);
test.testWork(milan);

输出:

普通员工:张工正在工作!
经理:milan正在管理!

到此这篇关于深入解析Java多态进阶学习的文章就介绍到这了,更多相关Java多态内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 新手小白入门必学JAVA面向对象之多态

    目录 1. 概念 2 . 特点 3. 练习:多态入门案例 4. 多态的好处 5. 多态的使用 6. 练习:多态成员使用测试 7 拓展 7.1 设计汽车综合案例 7.2 多态为了统一调用标准 7.3 静态变量和实例变量的区别 7.4 向上转型和向下转型 总结 1. 概念 多态是面向对象程序设计(OOP)的一个重要特征,指同一个实体同时具有多种形式,即同一个对象,在不同时刻,代表的对象不一样,指的是对象的多种形态. 可以把不同的子类对象都当作父类来看,进而屏蔽不同子类对象之间的差异,写出通用的代码,

  • 详解Java面向对象之多态的原理与实现

    目录 何为多态 代码实现 多态理解 何为多态 定义: 多态是指不同的子类在继承父类后分别都重写覆盖了父类的方法,即父类同一个方法,在继承的子类中表现出不同的形式.系统在运行时(而非编译时),能够根据其类型确定调用哪个重载的成员函数的能力,称为多态性. 特点: (1)多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,就是同一种事物表现出的多种形态. (2)多态就是抽象化的一种体现,把一系列具体事物的共同点抽象出来, 再通过这个抽象的事物, 与不同的具体事物进行对话. (3)对不同类的对象

  • Java由浅入深分析多态的概念

    目录 1.多态的概念 2.向上转型 2.1概念 2.2常见的向上转型的形式 3.重写 3.1重写的注意事项 在结束继承内容之后便是多态,这同样也是面向对象程序的特性 有一点需要说明:为方便演示,所以我在一个java文件中定义了多个类,但实际上是不推荐这么做的 1.多态的概念 简单来讲就是不同的对象去完成同一个行为,但是产生了不同的状态 一个很简单的例子:学校某个班级的学生参加同一场考试,考试结束后不同的学生的考试成绩都是不同的,有的不及格.有的在及格线上游走.而有的则是高分,那么你在哪个水平~(

  • Java多态实现原理详细梳理总结

    目录 一.概述 引入 定义 二.多态的体现 三.多态的好处 四.引用类型转换 向上转型 向下转型 为什么要转型 转型的异常 一.概述 引入 多态是继封装.继承之后,面向对象的第三大特性.生活中,比如跑的动作,小猫.小狗和大象,跑起来是不一样的.再比如飞的动作,昆虫.鸟类和飞机,飞起来也是不一样的.可见,同一行为,通过不同的事物,可以体现出来的不同的形态.多态,描述的就是这样的状态. 定义 多态: 是指同一行为,具有多个不同表现形式. 二.多态的体现 多态体现的格式: 父类类型 变量名 = new

  • Java实例讲解多态数组的使用

    目录 多态概述 1.向上转型 2.向下转型 多态数组 Arrtest.java Person.java Student.java Teacher.java 多态数组+向下转型 instanceof关键字 Arrtest.java Person.java Student.java Teacher.java 多态概述 多态概念:所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变

  • Java全面分析面向对象之多态

    目录 多态的理解 向上转型 向上转型的三种形式 动态绑定和静态绑定 方法的重写 进一步认识和理解多态 多态的优点 多态的理解 什么是多态呢??从字面理解就是多种形态,也就是不同类实例化出来的对象调用同一种方法,也可以理解为不同类的对象经过同一种行为产生的状态是不同的,这就是多态. 要想理解多态,我们必须要了解向上转型和重写这两个重点然后在来深刻理解多态这一概念,等看完向上转型与重写再来看多态的概念,你就会豁然开朗,一下就通透了不少.因为多态的条件就是向上转型,重写以及继承. 向上转型 首先多态的

  • Java超详细讲解多态的调用

    概念:多态是什么它就相当于区别对待,比如买票这个行为,当普通人买票时,是全价买票:学生买票时,是半价买票:军人买票时是优 先买票.再者就是再举个详细的例子: 最近为了争夺在线支付市场,支付宝年底经常会做诱人的扫红包-支付-给奖励金的活动.那么 大家想想为什么有人扫的红包又大又新鲜8块.10块…,而有人扫的红包都是1毛,5毛….其实这背后也是 一个多态行为.支付宝首先会分析你的账户数据,比如你是新用户.比如你没有经常支付宝支付等等,那么 你需要被鼓励使用支付宝,那么就你扫码金额 = random(

  • 深入解析Java多态进阶学习

    目录 1.动态绑定机制 实例A 实例B 实例C 2.多态数组 3.多态数组的高阶用法 4.多态参数 5.多态参数的高阶用法 1.动态绑定机制 java的动态绑定机制非常重要 实例A 我们来看一个实例: 阅读上面的代码,请说明下面的程序将输出什么结果: 程序将会输出40和30,这个实例很简单,直接看运行类型即可,该代码的运行类型为B,所以会调用B类的方法 实例B 我们将上面的代码变通一下,将子类中的如下代码块注销: 随后继承机制会访问父类的sum方法: 那么这里有一个问题,此处的getI(),会执

  • ReentrantLock从源码解析Java多线程同步学习

    目录 前言 管程 管程模型 MESA模型 主要特点 AQS 共享变量 资源访问方式 主要方法 队列 node节点等待状态 ReentrantLock源码分析 实例化ReentrantLock 加锁 A线程加锁成功 B线程尝试加锁 释放锁 总结 前言 如今多线程编程已成为了现代软件开发中的重要部分,而并发编程中的线程同步问题更是一道难以逾越的坎.在Java语言中,synchronized是最基本的同步机制,但它也存在着许多问题,比如可重入性不足.死锁等等.为了解决这些问题,Java提供了更加高级的

  • Java多态中动态绑定原理解析

    这篇文章主要介绍了Java多态中动态绑定原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 多态是面向对象程序设计非常重要的特性,它让程序拥有 更好的可读性和可扩展性. 发生在继承关系中. 需要子类重写父类的方法. 父类类型的引用指向子类类型的对象. 自始至终,多态都是对于方法而言,对于类中的成员变量,没有多态的说法. 一个基类的引用变量接收不同子类的对象将会调用子类对应的方法,这其实就是动态绑定的过程.在理解动态绑定之前,先补充一些概念.

  • Java多态的全面系统解析

    目录 Java基础知识(多态) 多态 多态的定义和存在的必要条件 多态的定义: 多态存在的三个必要条件 多态的案例 多态的好处 多态的弊端 引用类型转换 1.引用类型转换是什么,为什么需要它? 2.向上转型(自动转换) 3.向下转型(强制转换) 4.向下转型的问题 5.转型的异常 6.instanceof关键字 总结 茫茫人海千千万万,感谢这一秒你看到这里.希望我的能对你的有所帮助!共勉! 愿你在未来的日子,保持热爱,奔赴山海! Java基础知识(多态) 多态 因为在程序运行时才确定具体的类,这

  • Java中jqGrid 学习笔记整理——进阶篇(二)

    相关阅读: Java中jqGrid 学习笔记整理--进阶篇(一) 本篇开始正式与后台(java语言)进行数据交互,使用的平台为 JDK:java 1.8.0_71 myEclisp 2015 Stable 2.0 Apache Tomcat-8.0.30 Mysql 5.7 Navicat for mysql 11.2.5(mysql数据库管理工具) 一.数据库部分 1.创建数据库 使用Navicat for mysql创建数据库(使用其他工具或直接使用命令行暂不介绍) 2. 2.创建表 双击打

  • java爬虫jsoup解析HTML的工具学习

    目录 前言 下载 一个文档的对象模型 获取 Document 对象 解析并提取 HTML 元素 使用传统的操作DOM的方式 选择器 修改获取数据 前言 使用python写爬虫的人,应该都听过beautifulsoup4这个包,用来它来解析网页甚是方便.那么在java里有没有类似的包呢?当然有啦!而且也非常好用.下面隆重介绍jsoup! jsoup 实现了 WHATWG HTML5 规范,能够与现代浏览器解析成相同的DOM.其解析器能够尽最大可能从你提供的HTML文档来创建一个干净的解析结果,无论

  • Java 基础语法之解析 Java 的包和继承

    目录 一.包 1. 概念 2. 使用方式 3. 静态导入 4. 创建包 5. 包的访问权限 6. 常见的系统包 二.继承 1. 概念 2. 语法规则(含 super 使用) 3. protected 关键字 4. 更复杂的继承关系 5. final 关键字 三.组合 四.总结(含谜底) 一.包 1. 概念 根据定义:包是组织类的一种方式 那么为什么要组织类呢? 简单来讲就是保证类的唯一性,就比如在以后的工作中,如果大家一起开发一个项目,大家可能在自己的代码中都写到了一个 Test 类,而如果出现

  • 解析Java编程之Synchronized锁住的对象

    图片上传 密码修改为  synchronized是java中用于同步的关键字,一般我们通过Synchronized锁住一个对象,来进行线程同步.我们需要了解在程序执行过程中,synchronized锁住的到底是哪个对象,否则我们在多线程的程序就有可能出现问题. 看下面的代码,我们定义了一个静态变量n,在run方法中,我们使n增加10,然后在main方法中,我们开辟了100个线程,来执行n增加的操作,如果线程没有并发执行,那么n最后的值应该为1000,显然下面的程序执行完结果不是1000,因为我们

  • 详解Java多态对象的类型转换与动态绑定

    Java多态对象的类型转换 这里所说的对象类型转换,是指存在继承关系的对象,不是任意类型的对象.当对不存在继承关系的对象进行强制类型转换时,java 运行时将抛出 java.lang.ClassCastException 异常. 在继承链中,我们将子类向父类转换称为"向上转型",将父类向子类转换称为"向下转型". 很多时候,我们会将变量定义为父类的类型,却引用子类的对象,这个过程就是向上转型.程序运行时通过动态绑定来实现对子类方法的调用,也就是多态性. 然而有些时候

  • PHP进阶学习之命名空间基本用法分析

    本文实例讲述了PHP进阶学习之命名空间基本用法.分享给大家供大家参考,具体如下: 前言 命名空间(namespace),在编程语言中,是对作用域的一种特殊的抽象.它表示着一个标识符的可见范围.一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的.这样,在一个新的命名空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其他命名空间中. 在PHP中也存在命名空间的用法,由它控制可见范围的这个标识符一般指的就是类和函数. 一.PHP命名空间基础 从广义上来

随机推荐