多态

多态表示事物的多种表现形态。在程序中,父类通常描述的是多个子类的共性,子类对象就可以作为一个有个性的父类出现,例如狗类可以作为动物类使用,猫类也可以作为动物来使用。

多态的表现需要在两个类存在继承关系的前提下,子类对象赋值给父类类型引用,例如:Animal a = new Dog();,这样的语法是对的,因为狗类可以称作是一个动物类。

可以结合基本类型的自动类型提升来描述多态,父类表示数据类型较大的变量,子类表示数据类型较小的值,使用较大变量接收较小的值是可以接受的。

多态可以屏蔽不同对象之间的差异,也就是说任何子类在经历多态之后都可以作为父类类型来使用。

构建多态

构建多态也就是将子类类型对象赋值给父类类型引用:

/*new Dog();//创建对象时,对象就已经拥有了类型。Dog d;//声明引用时,引用也拥有了相应的类型。
*/
Dog d = new Dog();//将Dog类型的对象,赋值给Dog类型的引用。
Animal a = new Dog();//将Dog(子类)类型的对象,赋值给Animal(父类)类型的引用。

多态的性质

  1. 对象在创建后,其类型就已经确定,无论放置在任何引用中,其对象的类型都不会改变。
  2. 在多态中,只能调用父类中生命过的方法。因为调用方法的是父类引用,父类是不可能获得子类的方法的。如果子类中存在父类中没有的方法,则在经过多态后并不能通过父类引用进行调用。
  3. 在调用时,实际调用的是子类对象中覆盖父类后的方法。

多态的应用

多态的应用实际借助了其“屏蔽不同对象之间的差异”这一作用,使任意子类对象都可以赋值到父类类型的引用中。

  1. 在方法返回值使用多态,可以返回多种类型的对象:

    public class Demo{public static void main(String[] args){FanShouJi fsj = new FanShouJi();//方法的返回值,并不是实际返回什么类型就是什么类型,//而是方法声明的什么类型就是什么类型ShiWu sw = fsj.getShangPin(2);//每个类中,默认存在getClass()方法,此方法用于获得此引用的对象的运行时类型System.out.print(sw.getClass());}
    }
    //当某一方法返回的数据类型是多种的,可以使用父类类型屏蔽它们的差异
    class FanShouJi{public ShiWu getShangPin(int yingBi){if(yingBi == 5){return new Mian();}else if(yingBi == 2){return new Shui();}else if(yingBi == 6){return new BingGan();}//如果参数无法触发任何一个返回语句,则方法声明有误,需要至少返回一次return null;}
    }
    class ShiWu{}
    class BingGan extends ShiWu{}
    class Shui extends ShiWu{}
    class Mian extends ShiWu{}
    
  2. 在参数表中可以获得多种类型的对象:

    public class Demo{public static void main(String[] args){WuCan w = new WuCan();w.chi(new XianCai());}
    }class ShiWu{public String weiDao(){return "未知";}
    }
    class XianCai extends ShiWu{public String weiDao(){return "咸";}
    }
    class ManTou extends ShiWu{public String weiDao(){return "淡";}
    }
    class XiFan extends ShiWu{public String weiDao(){return "甜";}
    }class WuCan{//在此方法上,接收的数据类型有多个,则使用其父类类型屏蔽不同对象之间的差异//在实参对形参进行赋值的时候,就形成了多态public void chi(ShiWu shiWu){System.out.print(shiWu.weiDao());}
    }
    
  3. 在数组中,可以存储多种类型的对象:

    public class Demo{public static void main(String[] args){DongWu zoo[] = {new Gou(),new Mao(),new Ji()};//数组中的元素的类型,并不是实际类型,而是数组声明的类型DongWu dw = zoo[1];System.out.print(dw.getClass());}
    }class DongWu{}
    class Gou extends DongWu{}
    class Mao extends DongWu{}
    class Ji extends DongWu{}
    

对象类型的转换

对象类型的转换与基本类型的转换类似,也具有自动类型提升和强制类型转换。自动类型提升也就是将子类类型对象赋值到父类类型的引用中,也就是多态的过程。在经历多态之后的对象保存在父类类型中,如果要转换成原本类型就要经历强转。

如果经历多态,那引用就只能调用父类声明过的方法,但如果要调用子类中专有的方法,就要经历强转。

对象类型的强转

像基本类型类似,对象类型的强转也是通过小括号的方式进行,小括号中可以书写对象的本来类型或者父类类型:

Animal a = new Dog();
Dog d = (Dog)a;//Dog是子类类型,a是父类类型,使用子类类型引用接收父类类型引用中的内容需要强转!

进行强转时,如果对象类型与强转类型相同或者是对象类型的父类类型,则强转成功,否则将报错。例如强转的类型不是对象的直系父类,或者是对象的兄弟类或者子类,就会报错:

public class Test{public static void main(String[] args){ShengWu sw = new Gou();    //形成多态DongWu dw = (DongWu)sw;  //父类引用中存放的对象,是DongWu的子类,可以转换Gou g = (Gou)sw;     //父类引用中存放的对象,是Dog类,可以转换ZhiWu zw = (ZhiWu)sw; //父类引用中存放的对象,是ZhiWu的侄子类,不可转换。Mao m = (Mao)sw;        //父类引用中存放的对象,是Mao的兄弟类,不可转换。}
}class ShengWu{}class DongWu extends ShengWu{}class ZhiWu extends ShengWu{}class Gou extends DongWu{}class Mao extends DongWu{}

安全的类型强转

无论是对象类型还是基本类型,在强转时都会出现报错或者值溢出的情况。安全的强转指避免对象出现报错或者值溢出,通过检测的方式决定是否要进行转换,而不会改变值的内容。

基本类型转换较为简单,只要确定值能够存放到变量类型的空间里就可以:

int a = ?;//先查看实际的内容是什么,再去进行转换!
//如果要对一个值,进行强转,就可以判断这个变量中的值,是否在byte能接受的范围之内。
if(a>=-128 && a<=127){byte b = (byte)a;
}

对象类型的转换分为两种方式,一种是采用引用中的getClass方法来确定对象的类型,如果与要进行强转的对象类型相同则可以进行转换:

//基本类型进行强转需要将其中的值进行判断
//对象类型的强转,是将对象类型进行判断(判断是否是本类,或者是否是子类(是否可以进行多态))public class Test{public static void main(String[] args){ShengWu[] arr = {new Gou(),new Mao(),new DongWu(),new ZhiWu(),new ShengWu()};ShengWu sw = arr[1];//尝试着将sw转换成Mao类型//Mao m = (Mao)sw;//如果这样进行盲目强转,可能发生强转异常//借助着getClass方法"获得引用中对象的实际类型"//sw.getClass();//这句话就会获得sw的实际类型Mao m2 = new Mao();//这句话是获得一个确定好的真正的Mao对象if(sw.getClass() == m2.getClass()){//这句话是将不确定的sw对象,与确定的m2对象的类型进行匹配//如果sw的对象类型与m2的对象类型相同,则执行强转Mao m3 = (Mao)sw;}else{System.out.print("无法转换!");}}
}class ShengWu{}class DongWu extends ShengWu{}class ZhiWu extends ShengWu{}class Gou extends DongWu{}class Mao extends DongWu{}

使用getClass的方式只能将对象转换为原本的类型,而不能转换为父类类型。而通过instanceof关键字进行判断,就可以将引用转换为当前类型或者其父类类型。语法为:boolean flag = 引用 instanceof 对象类型;,如果引用是对象类型或者对象类型的子类,语句则返回true,否则返回false:

public class Test{public static void main(String[] args){ShengWu[] arr = {new Gou(),new Mao(),new DongWu(),new ZhiWu(),new ShengWu()};ShengWu sw = arr[1];//在此处使用instanceof进行判断,Gou/Mao/DongWu都可以进行转换!//因为instanceof判断的是:引用是否是指定类型或者指定类型的子类。if(sw instanceof DongWu){DongWu m = (DongWu)sw;}else{System.out.print("强转失败!");}}
}class ShengWu{}class DongWu extends ShengWu{}class ZhiWu extends ShengWu{}class Gou extends DongWu{}class Mao extends DongWu{}

Java基础:面向对象特性(多态)相关推荐

  1. Java 基础 - 面向对象(不错N多教程集合)

    著作权归https://pdai.tech所有. 链接:Java 基础 - 面向对象 | Java 全栈知识体系 本文主要介绍Java OOP 面向对象基础和相关类图.@pdai Java 基础 - ...

  2. Java基础-面向对象第二特征之继承(Inheritance)

    Java基础-面向对象第二特征之继承(Inheritance) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.继承的概述 在现实生活中,继承一般指的是子女继承父辈的财产.在程序 ...

  3. 基于Java基础-面向对象实现植物大战僵尸简易版

    基于Java基础-面向对象实现植物大战僵尸简易版 前言 游戏设计 游戏对象 游戏内容 游戏优化 放置植物的优化 移除植物的优化 游戏可玩性的优化 添加游戏背景音乐 后续优化 源码分享 前言 从零开始学 ...

  4. (20)Java基础 --面向对象(1)

    目录 面向对象 一.概述 二.生活举例 三.类与对象的关系 四.类的构成 五.类的定义 类的属性 类的方法 创建实例(对象) 内存分配图 六.对象的基本使用 七.局部变量与成员变量的区别 八.面向对象 ...

  5. java基础提高篇--java的三大特性--多态

    前两篇博文,分别介绍了java的面向对象的两大特性封装和继承,这一篇为介绍一下多态. 首先回顾一下什么是封装.继承. 封装就是隐藏信息,使用抽象的数据类型将数据以及基于数据的操作封装起来,使得外界不能 ...

  6. Java基础-----面向对象

    文章目录 面向对象 类与对象 匿名对象 创建对象的内存分析 栈(stack) 堆(heap) 方法区 PC寄存器 本地方法栈 内部类 成员内部类 局部内部类 匿名内部类 静态内部类 包装类 拆箱和装箱 ...

  7. Java基础 面向对象的详解

    1.1 万物皆对象 我们是怎么认识世界的? 人类从小就不断的接触到各种各类存在世界上的各种生物,然后通过事物的公共特性,将它们归类,所以以后就不会出现见到猫叫老虎.那么我们在现实生活中,是通过具体的某 ...

  8. 黑马程序员——java基础--面向对象(篇一)

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 第一章 1.面向对象     2.成员变量      3.匿名对象     4.封装       ...

  9. java基础面向对象_Java基础面向对象

    一.面向过程的思想和面向对象的思想 面向对象和面向过程的思想有着本质上的区别,作为面向对象的思维来说,当你拿到一个问题时,你分析这个问题不再是第一步先做什么,第二步再做什么,这是面向过程的思维,你应该 ...

  10. Java 基础 - 面向对象(不错)

    算法 剑指 Offer 题解 Leetcode 题解 算法 字节跳动内推 操作系统 计算机操作系统 Linux 网络 计算机网络 HTTP Socket 数据库 数据库系统原理 SQL 语法 SQL ...

最新文章

  1. mysql innodbuffer修改_mysql参数之innodb_buffer_pool_size大小设置
  2. 360修复高危漏洞可以修复吗_360代码卫士助D-LINK修复多个高危漏洞
  3. Win7如何快速打开命令提示符
  4. 全球及中国手持式吸尘器行业供应需求及未来投资潜力预测报告2022-2027年
  5. ansible 容器部署_使用ansible-bender工具构建容器图像
  6. 滴滴新规则明日起试行:将影响一大波人
  7. Jquery Easyui Datagrid创建代码
  8. GitHub新神器,宇宙第一编辑器--VS Code!危
  9. [51单片机] 四相五线减速比为1/64步进电机驱动设计
  10. Python深度学习:Python数据处理及可视化(读书笔记)
  11. 2020年苏大计算机考研872真题及解析
  12. 论文翻译:2021_Performance optimizations on deep noise suppression models
  13. vue 运行启动命令_如何使用Vue启动和运行
  14. 计算机系统结构变革在即?
  15. js+打开php文档,javascript打开word文档的方法_基础知识
  16. 美创科技深度参编的《数据安全治理实践指南(2.0)》发布
  17. IP地址划分【分类:A类 B类 C类 D类 E类】
  18. java加壳工具_加壳工具 - virbox加密空间站 - OSCHINA - 中文开源技术交流社区
  19. 【前缀和】蓝桥杯试题 k倍区间
  20. JSP入门教程:JSP简明教程

热门文章

  1. 音乐节为什么需要网络覆盖?如何搭建临时稳定WiFi?
  2. TRIZ创新方法——特性传递
  3. 【知识图谱】解读知识图谱的技术与应用
  4. matlab simulink波特图,用simulink画波特图
  5. 用python从图片生成视频
  6. 大数据技术之_08_Hive学习_03_查询+函数
  7. 浅谈曲面参数化---顾险峰(老顾谈几何)
  8. 华谊嘉信:依托大数据,构建智能化运营平台!
  9. ARP代理实现同网段不同vlan通信
  10. 委内瑞拉将向OPEC推出Petro币用于国际石油交易