一、多态的概念

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

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

二、实现多态

  多态(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. 线程(四)之Queue

    SynchronousQueue SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加:可以认为Sync ...

  2. [easyUI] datagrid 数据格 可以进行分页

    1. 新建一个GridNode的类: public class GridNode { private Long id; private String title;//投票标题 private Inte ...

  3. Python自学:第二章 使用函数str( )避免类型错误

    age = 23 message = "Happy " + str(age) + "rd Birthday" print(message) 输出位 Happy ...

  4. GoEasy的使用

    GoEasy介绍 http请求短连接,一次请求响应后关闭,而GoEasy建立了客户端与服务器之间的长连接. goeasy支持服务器到客户端的消息发布,客户端到客户端的消息发布 GoEasy用来做什么 ...

  5. 获取GitHub上远程分支内容

    一.clone项目 二.获取远程特定分支的内容 1.查看所有分支 git branch --all # 默认有了ls和master分支,所以会看到如下三个分支 # master[本地主分支] orig ...

  6. 一次完整的http事务的过程

    1.域名解析 2.发起TCP三次握手 3.建立TCP连接以后发起http请求 4.服务器端响应请求,浏览器得到html代码 5.浏览器解析html代码并请求html中的资源 6.浏览器对页面进行渲染呈 ...

  7. caffe drawnet.py 用Python画网络框架

    在caffe中可以使用draw_net.py轻松地绘制卷积神经网络(CNN,Convolutional Neural Networks)的架构图.这个工具对于我们理解.学习甚至查错都有很大的帮助. 1 ...

  8. Ubuntu系统下安装免驱动摄像头

    最近想玩一下视频系列的深度学习模型,便网上淘了一个linux下免驱动的摄像头,直接插上usb接口就行,但是一般还不能直接使用,下面将简单说一下如何使用摄像头: 在你的ternimal下输入以下命令: ...

  9. pip 安装 nexmo

    pip install nexmo报错 是因为缺少 libffi-devel 需要    yum install libffi-devel 然后再执行  pip install nexmo 即可成功

  10. python+appium 自动化1--启动手机京东app

    出处:https://www.cnblogs.com/yoyoketang/p/6128735.html 前言: 环境搭建好了.接下来先体验下如何启动app--1.首先获取包名:2.然后获取launc ...