一、多态的概念

  在面向对象语言中,多态是指在一棵继承树中的类中可以有多个同名但不同方法体及不同形参的方法。通常有两种途径实现多态:方法的重载和覆盖。

  多态性允许以统一的风格处理已存在的变量及相关的类。多态性使得向系统里增加新功能变得容易。继承性和多态性是降低软件复杂性有有效技术。

二、实现多态

  多态(polymoph)指的是“执行期间(而非编译期间)”判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。多态也叫动态绑定,也叫迟绑定。

  多态的存在有三个必要条件:

  1. 要有继承
  2. 要有方法重写
  3. 父类引用指向子类对象
    package com.duotai;
    /**
    * 狗狗类,宠物的子类
    */
    public class Dog extends Pet {
    private String strain="哈士奇";// 品种
    //无参构造方法
    public Dog(String name,int health,int love,String strain) {
    super(name,health,love);
    this.strain = strain;
    System.out.println("dog类构造方法");
    }
    public String getStrain() {
    return strain;
    }
    public void setStrain(String strain) {
    this.strain = strain;
    }
    //重写父类方法
    public void print() {
    System.out.println("宠物的自白:\n我的名字叫" +
    this.getName() + ",我的品种是" + this.getStrain()+",我的健康值是" + this.getHealth()
    + ",我和主人的亲密程度是" + this.getLove() + "。");
    }
    public void toHospital(){
    if(this.getHealth()<60){
    System.out.println("给狗狗打针、吃药");
    this.setHealth(60);
    }
    }
    }
    package com.duotai;
    /**
    * 企鹅类
    */
    public class Penguin extends Pet {
    private String sex="Q仔";// 企鹅性别
    //构造方法
    public Penguin(String name,int health,int love,String sex) {
    super(name,health,love);
    this.sex = sex;
    System.out.println("penguin类构造方法");
    }
    public String getSex() {
    return sex;
    }
    public void setSex(String sex) {
    this.sex = sex;
    }
    //重写父类方法
    public void print() {
    System.out.println("宠物的自白:\n我的名字叫" +
    this.getName() + ",我的性别是" + this.getSex()+",我的健康值是" + this.getHealth()
    + ",我和主人的亲密程度是" + this.getLove() + "。");
    }
    public void toHospital(){
    if(this.getHealth()<50){
    System.out.println("给企鹅吃药、疗养");
    this.setHealth(70);
    }
    }
    }
    package com.duotai;
    /**
    * 宠物类,狗狗和企鹅的父类
    */
    public class Pet {
    private String name = "无名氏";// 昵称
    private int health = 100;// 健康值
    private int love = 20;// 亲密度
    /**
    * 无参构造方法
    */
    public Pet() {
    System.out.println("父类无参构造方法");
    }
    /**
    * 有参构造方法
    * @param name 昵称
    */
    public Pet(String name,int health,int love) {
    this.name = name;
    this.health = health;
    this.love = love;
    System.out.println("父类有参构造方法");
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public int getHealth() {
    return health;
    }
    public void setHealth(int health) {
    if(health<0||health>100){
    System.out.println("健康值应该在0至100之间,默认值为60");
    this.health=60;
    return;
    }
    this.health = health;
    }
    public int getLove() {
    return love;
    }
    public void setLove(int love) {
    if(love<0||love>100){
    System.out.println("亲密度应该在0至100之间,默认值为15");
    this.love=15;
    return;
    }
    this.love = love;
    } /**
    * 输出宠物信息
    */
    public void print() {
    System.out.println("宠物的自白:\n我的名字叫" +
    this.name + ",我的健康值是" + this.health
    + ",我和主人的亲密程度是" + this.love + "。");
    }
    public void toHospital(){
    }
    }
    package com.duotai;
    /*
    * 主人类
    */
    public class Master {
    // //给狗狗看病方法
    // public void cure(Dog dog){
    // if(dog.getHealth()<60){
    // System.out.println("给宠物打针、吃药");
    // dog.setHealth(60);
    // }
    // }
    // //给企鹅看病方法
    // public void cure(Penguin pgn){
    // if(pgn.getHealth()<60){
    // System.out.println("给宠物吃药、疗养");
    // pgn.setHealth(70);
    // }
    // }
    //给宠物看病
    public void cure(Pet pe){
    pe.toHospital();
    }
    }
    package com.duotai;
    //测试类
    public class Test {
    public static void main(String[] args) {
    // 1、创建宠物对象pet并输出信息
    // Pet pet = new Pet("苏苏",99,60);
    // pet.print();
    Master master = new Master(); //实例化主人对象
    // 2、创建狗狗对象dog并输出信息
    //Dog dog = new Dog("丫丫",45,40,"牧羊犬");
    Pet pdog = new Dog("丫丫",45,40,"牧羊犬"); //向上转型
    master.cure(pdog);
    pdog.print();
    // 3、创建企鹅对象pgn并输出信息
    // Penguin pgn = new Penguin("果果",85,20,"Q妹");
    // pgn.print();
    //同一引用类型 不同的实例
    Pet ppegn = new Penguin("果果",10,20,"Q妹");
    //多态:1、方法重写是实现多态的基础 2、同一引用类型,使用不同的实例而执行不同操作
    master.cure(ppegn); //执行不同操作
    ppegn.print();
    }
    }

三、向上转型和向下转型

  1.向上转型:<父类型>    <引用变量名> = new   <子类型>();
  例如:int i = 3;
     double  a = i;  //自动进行类型转换
        double b = 3.14;
        int c = (int)b;  //强制进行类型转换

  • 将一个父类的引用指向一个子类对象成为向上转型
  • 此时通过父类引用调用的方法是子类覆盖或继承了父类的方法,而不是父类的方法
  • 此时通过父类引用变量无法直接调用子类特有的方法

  2.向下转型:<子类型>    <引用变量名> = (<子类型>)<父类型引用变量>;
   将一个指向子类对象的父类引用赋给一个子类的引用,即将父类类型转换为子类类型
     例如:Dog dog = (Dog)pet;   //将父类引用pet转换为Dog类型

四、instance运算符

 在向下转型的过程中,如果不是转换为真实子类类型,会出现转换异常,java中提供了instance运算符进行类型的判断

public void cure(Pet pe){
if(pe instanceof Dog){
//...
}else if(pe instanceof Penguin){
//.....
}
}

  注意:使用instance时,对象的类型必须和instance后面的参数所指定的类有继承关系,否则会出现编译错误

五、多态的应用

  • 可替换性:多态已存在的代码具有可替换性
  • 可扩充性:对代码具有可扩充性,增加新的子类不影响已存在类的多态性、继承性
  • 接口性:多态时父类想子类提供了一个共同接口,有子类来具体实现
  • 灵活性:多态在应用中体现了灵活多样的操作,提高了使用效率
  • 简化性:简化了引用软件的代码编写和修改过程,尤其是在处理大量对象的晕眩和操作时
  • 2中应用形式:
  1. 使用父类作为方法的形参
  2. 使用父类作为方法的返回值
    package com.abstractInterface;
    /*
    * 动物类
    * @author yutianbao
    * @param
    * @date 2019/3/20 13:32
    * @return
    * @Motto: good good study,day day up
    */
    public abstract class Animals { //抽象类
    //叫
    public abstract void cry();
    }
    /*
    * 狗狗类
    * @author yutianbao
    * @param
    * @date 2019/3/20 13:34
    * @return
    * @Motto: good good study,day day up
    */
    class Dog extends Animals{
    public void cry(){
    System.out.println("狗狗叫:汪汪汪");
    }
    }
    /*
    * 猫类
    * @author yutianbao
    * @param
    * @date 2019/3/20 13:37
    * @return
    * @Motto: good good study,day day up
    */
    class Cat extends Animals{
    public void cry(){
    System.out.println("猫叫:喵喵喵");
    }
    }
    /*
    * 鸭子类
    * @author yutianbao
    * @param
    * @date 2019/3/20 13:37
    * @return
    * @Motto: good good study,day day up
    */
    class Duck extends Animals{
    public void cry(){
    System.out.println("鸭子叫:嘎嘎嘎");
    }
    }

      

    package com.abstractInterface;
    /*
    * 主人类
    * @author yutianbao
    * @param
    * @date 2019/3/20 13:40
    * @return
    * @Motto: good good study,day day up
    */
    public class MasterPerson {
    //捐赠给别人动物
    public Animals domateAnimals(String type){
    Animals animals = null;
    if(type.equals("dog")){
    animals = new Dog();
    }else if(type.equals("cat")){
    animals = new Cat();
    }else if(type.equals("duck")){
    animals = new Duck();
    }
    return animals;
    }
    }

      

    package com.abstractInterface;
    /*
    * 测试类
    * @author yutianbao
    * @param
    * @date 2019/3/20 13:51
    * @return
    * @Motto: good good study,day day up
    */
    public class Test {
    public static void main(String[] args) {
    MasterPerson mPerson = new MasterPerson();
    Animals dog = mPerson.domateAnimals("dog");
    dog.cry();
    Animals cat = mPerson.domateAnimals("cat");
    cat.cry();
    Animals duck = mPerson.domateAnimals("duck");
    duck.cry();
    }
    }

    

Java面向对象 第4节 类的多态性的更多相关文章

  1. Java面向对象 第1节 类和对象

    一.Java 对象和类 面向对象语言三大特性:封装.继承.多态: 对象:描述客观事物的一个实体: 类:类是封装对象的属性和方法的载体,反过来说具有相同属性和行为的一类实体被称为类:类行为:方法:属性: ...

  2. Java面向对象 第3节 类的封装和继承

      一.封装 封装的概念:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的访问和操作. 封装的2个大致原则:1)把尽可能多的东西隐藏起来,对外提供便捷的接口 ...

  3. Java面向对象(一)类和对象

    面向过程和面向对象的区别 面向过程,强调的是功能行为,是将实现一个功能的步骤编写在一个函数中,以函数为最小单位. 面向对象,是将需要的功能封装进一个对象中,使一个对象具有很多的功能特征,以类/对象为最 ...

  4. java面向对象程序设计(下)-枚举类

    在某些情况下,一个类的对象是有限而且固定的,比如季节类,它只有4个对象;再比如行星类,目前只有8个对象,这些实例有限而且固定的类,在Java中被称为枚举类 JDK1.5新增了一个enum关键字,(它与 ...

  5. Java面向对象 第2节 Scanner 类和格式化输出printf

    §Scanner 类 java.util.Scanner 是 Java5 的新特征,我们可以通过 Scanner 类来获取用户的输入. 1.创建 Scanner 对象的基本语法:Scanner s = ...

  6. Java面向对象 第5节 抽象类和接口

    一.抽象类和抽象方法 区分抽象方法和普通方法1)当一个方法被abstract修饰时,该方法成为抽象方法2)抽象类所在的类必须定义为抽象类3)抽象方法不会有具体的实现,而是在抽象类的子类中通过方法重写进 ...

  7. java面向对象编程——第八章 类的高级概念

    8.1访问修饰符: public:该类或非该类均可访问: private: 只有该类可以访问: protected:该类及其子类的成员可以访问,同一个包中的类也可以访问: 默认:相同数据包中的类可以访 ...

  8. Java面向对象 第6节 异常

    一.认识异常 异常是指在程序运行过程中所发生的不正常事件,如文件找不到.网络连接不通或链接中断.算数运算出错.数组下标越界.装在一个不存在的类.对null对象操作.类型转换异常等.异常会中断正在运行的 ...

  9. java面向对象中的String类中12种常用的方法

    1.字符串与字符数组的转换 字符串可以使用toCharArray()方法变成一个字符数组,也可以使用String类的构造方法把一个字符数组变成一个字符串. public class StringAPI ...

随机推荐

  1. 安装activemq和java代码实现生产和消费

    Apache Active MQ的官网 http://activemq.apache.org/ 下载地址: 国外的网站,网速不好的时候,真的下不下来 http://activemq.apache.or ...

  2. Zabbix4.0+第三方报警平台OneAlert监控报警

    1. 前言 告警将重要信息发送给运维「或者其他相关人」,及时发现并且处理问题.在所有开源监控软件里面,Zabbix 的告警方式无疑是最棒的.告警的方式各式各样,从 Email 告警到飞信.139/18 ...

  3. [Hibernate] inner Join和 left Join

    @Test public void test11(){ Session ss=HibernateUtil.getSession(); //根据员工名称(SCOTT)找到和他所在的部门的其他员工的信息 ...

  4. linux软件管理之yum管理rpm包

    YUM 使用官方源 ==================================================================================== 阿里镜像站 ...

  5. C++中数组声名后不初始化,数组里的值都是0吗?

    这得看数组的申明情况: 1.全局/静态数组 如果申明的是全局/静态数组,系统会把数组的内容自动初始化为0. 2.局部数组 如果申明的是局部数组,数组的内容会是随机的,不一定是0.如函数内声明: int ...

  6. Chained Exceptions in Java

    1. Overview In this article, we’ll have a very brief look at what Exception is and go in depth about ...

  7. babel,webpack-dev-server配置

    github仓库:https://github.com/llcMite/webpack.git 1.什么是webpack? webpack可以看做是模块打包机:它做的事情是,将静态资源当成模块打包成一 ...

  8. LeetCode 总结,二叉树各种类型问题小结

    三大遍历 前序遍历 中序遍历 后序遍历 关于三大基础遍历,必须要条件反射式的记住:三种遍历的迭代方式使用的都是栈,后序遍历必须使用了 两个栈,其余乱七八糟的解决方式统统就不要再记了. 广度遍历: 分析 ...

  9. python全栈开发笔记---------数据类型-----字典dict

    字典 #dict #1.基本结构 info= { "k1" : "v1", #键值对 "k2" : "v2" } ### ...

  10. 使用IntelliJ IDEA开发java web

    前言:由于本人接触java语言时间还比较短,IDE工具eclipse还比较熟悉点,想试试用IntelliJ IDEA来开发java web项目来练练手! 一.下载安装篇 1.安装IntelliJ ID ...