多态的含义

多态,从字面上理解,多态就是一种类型表现出了多种状态。我们就可以利用多态的特征,用统一的标识来完成不同的功能。

多态的类型

1.方法的多态(方法的重载和重写(覆写))

方法重载(overload)指的是通过一个方法名称,根据其传入的参数列表(参数类型、个数和顺序)的不同,所调用的方法执行体也不同,即调用同一个方法名称在一个类中有不同的功能实现。

方法的重写(覆写)是指父类中完成了一个方法的实现,而子类用了同样的方法名完成了不同的功能实现

2.对象的多态性

多态性允许将父类对象设置成为与一个或多个子对象相等的技术,通过赋值之后,父对象就可以根据当前赋值给不同的子对象,然后以子对象的特性运作。多态意味着相同的(父类)信息发送给不同的子对象,每个子对象表现出不同的形态。

多态的一个核心概念就是,子类(派生类)对象可以视为父类(基类)对象,我们举个例子

鱼类、鸟类、马类都继承于父类动物类,对于他们各自的实例化的对象,我们就可以说鱼是动物,鸟是动物,马是动物。

方法的重写override(覆写)

代码演示:

package demo;class People{private String name;private int age;public People(String name, int age) {this.name = name;this.age = age;}public void talk(){System.out.println("我是人,我会说话");}
}class Student extends People{private String name;private int age;public Student(String name, int age) {super(name, age);}public void talk(){System.out.println("我是学生,我会文明的说话");}}
public class InheritDemo {public static void main(String[] args){Student stu = new Student("bigdodo", 20);stu.talk();}
}

代码讲解:父类里有talk()方法,我们用子类Student去继承父类,理应也继承了父类的talk()方法,但是我们可以使用相同方法名,去完成不同实现方法体,这就是方法的重写(覆写)

方法的重载overload

方法重载(overload)指的是通过一个方法名称,根据其传入的参数列表(参数类型、个数和顺序)的不同,所调用的方法执行体也不同,即调用同一个方法名称在一个类中有不同的功能实现。接下里我来给大家演示一下

代码演示:

package demo;class Calculator{public void sum(int a,float b){System.out.println(a+b);}//参数顺序不一样public void sum(float b,int a){System.out.println(a+b);}//参数个数不一样public void sum(int a,int b,int c){System.out.println(a+b+c);}//参数类型不一样public void sum(int a,float b,int c){System.out.println(a+b+c);}
}public class Test {public static void main(String[] args) {Calculator cal = new Calculator();cal.sum(5, 6.0f);cal.sum(6.0f, 5);cal.sum(5, 6, 7);cal.sum(5, 8.0f, 7);}
}

代码讲解:我们定义了一个计算器类型,然后设置了四个不同的求和方法,但用的都是一个方法名,这时候我们如果定义了一定数量的sum()方法,参数列表就算不一样,我们一样可以在测试类用只用同一个名字的sum()方法计算求和即可,但记住,它们不是同一个方法,这就是方法的重载。

对象的多态性

在讲对象的多态性的时候我们需要先了解两个概念:向上转型、向下转型

向上转型

父类对象通过子类对象去实例化,实际上就是对象的向上转型。向上转型不需要进行强制类型转换的,但是向上转型会丢失精度,我们来举个例子

代码演示:

package demo;class Animal{public void move(){System.out.println("动物动");}
}class Bird extends Animal{public void move(){System.out.println("鸟儿飞");}
}class Horse extends Animal{public void move(){System.out.println("马儿跑");}
}
class Fish extends Animal{public void move(){System.out.println("鱼儿游");}
}public class Test {public static void main(String[] args) {Animal animal;Fish fish = new Fish();Bird bird = new Bird();Horse horse = new Horse();//将鱼儿对象赋值给animal,调用Fish的move()方法animal = fish;animal.move();//将马儿对象赋值给animal,调用Horse的move()方法animal = horse;animal.move();//将鸟儿对象赋值给animal,调用Bird的move()方法animal = bird;animal.move();}
}

代码运行结果:

代码讲解:这里运用了向上转型,通过赋值之后,父对象就可以根据当前赋值给不同的子对象,然后以子对象的特性运作。

这里还涉及了一个概念的知识点:动态绑定,是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。这就解释了为什么向上转型能够调用子类对象的方法了。

向下转型

所谓向下转型,也就是说父类对象可以转换成子类的对象,但需要注意的是,这时候必须要使用强制类型的转换,举个例子。

代码演示:

package demo;class Animal{public void move(){System.out.println("动物动");}
}class Bird extends Animal{public void move(){System.out.println("鸟儿飞");}public void eat(){System.out.println("鸟儿吃虫子");}
}public class Test {public static void main(String[] args) {Animal animal;Bird bird = new Bird();//将鸟儿对象赋值给animal,调用Bird的move()方法animal = bird;animal.move();//向调用鸟儿吃的方法,无法调用//animal.eat();}
}

代码讲解:我们可以看到鸟类多了一个吃东西的方法,但是在主方法里通过向上转型,animal对象没办法调用子类的eat的方法,这就是精度丢失的问题,这时候我们就需要强制类型转换一下才能够使用

我们修改main()方法

public class Test {public static void main(String[] args) {Animal animal;Bird bird = new Bird();//将鸟儿对象赋值给animal,调用Bird的move()方法animal = bird;animal.move();//向下转型,强制类型转换Bird bird2 = (Bird)animal;bird2.eat();}
}

代码运行结果:

修改后,我们就可以调用子类的方法了

在向下转型中有一点需要注意,上述例子我们通过子类对象赋值给父类对象,通过父类对象去调用子类方法和行为,但有一个问题,我们怎么能够确定我们调用了正确的子类对象的行为呢?即我们怎么确保我们赋值的子类对象使我们想要的呢?java在这问题上给我们提供了一个关键字instanceof,所以我们有必要完善我们的代码,如下:

代码演示:

package demo;  class Animal{  public void move(){  System.out.println("动物动");  }
}  class Bird extends Animal{  public void move(){  System.out.println("鸟儿飞");  }  public void eat(){  System.out.println("鸟儿吃虫子");  }
}  class Fish extends Animal{  public void move(){  System.out.println("鱼儿游");  }  public void eat(){  System.out.println("鱼儿吃");  }
}  public class Test {  public static void main(String[] args) { //声明父类对象,并以子类型实例化Animal animal = new Bird();   //使用instanceof关键字,判断类型是否匹配if(animal instanceof Fish){//向下转型,强制类型转换  Bird bird2 = (Bird)animal;  bird2.eat();}else{System.out.println("类型不匹配");}}
}  

代码讲解:instanceof关键字,使用方法 对象名 instanceof 类名,即判断对象类型是否与类匹配,如果匹配则返回true,不匹配返回false。

总结点评:面向对象第三大特征多态,多态是在继承上的扩展,一定要区别多态和继承的概念,多态有方法的多态性,即方法的重载和重写,还有对象的多态性,而对象的多态性是通过向上、向下转型实现的。

九、面向对象三大特征(三)—— 多态相关推荐

  1. Cris 的Python笔记(十一):面向对象三大特征之多态

    ''' Python 的多态:一个对象可以以不同的形态去呈现,实现方式相比 Java更加简单 因为动态语言的特点,Python 无法实现在代码指向前对方法参数进行检查,所以只要满足指定方法体的要求,任 ...

  2. 实践解读丨Python 面向对象三大特征之多态

    摘要:多态从字面意思上看就是多种形态,在我们python的面向对象里就是不同的对象在接收相同方法或者函数时会产生不同的行为,也就是说,每个对象可以用自己的方式去响应共同的函数,不同的方式实现不同的结果 ...

  3. JAVA面向对象三大特征之一多态

    一.什么是多态? 同类型的对象,变现出的不同形态. 二.多态的表现形式 父类类型   对象名称   =   子类对象: 三.多态的前提 a.有继承/实现关系 b.有父类引用指引子类对象     例子: ...

  4. 面向对象三大特征之多态

    实现多态的三大要素 1.继承关系的父类跟子类 2.子类重写父类的方法 3.父类的引用指向子类的对象 多态的类型 1.向上转型--子类到父类的转换:自动类型转换 语法:父类名 引用变量名=new 子类名 ...

  5. c++面向对象三大特征封装、继承和多态知识总结

    面向对象三大特征:封装,继承,多态: 一.封装:该公开的就公开话,该私有的就隐藏掉,主要是由public,private实现:作用是便于分工和分模块,防止不必要的扩展: 二.继承:就是一种传承,可以把 ...

  6. 面向对象第七章,内存的管理,面向对象三大特征封装、继承、多态

    ###1.内存管理:由JVM来管理的------了解 1)堆: 1.1)存储new出来的对象(包括实例变量) 1.2)垃圾:没有任何引用指向的对象 垃圾回收器(GC)不定时到内存中清扫垃圾, 回收过程 ...

  7. 面向对象三大特征(封装、继承、多态)详解

    面向对象的三大特征 万物皆可归类,类是对于世界事物的高度抽象,不同的事物有不同的关系:一个类自身与外界的封装关系:一个父类与子类的继承关系:一个类和多个类的多态关系. 万物皆对象,对象是具体的世界事物 ...

  8. c++局部对象是什么_面向对象三大特征: 封装

    今日内容 面向对象概述 类和对象的关系 面向对象内存图 private.this关键字和封装 面向对象之构造方法 面向对象三大特征 封装 继承 多态 01. 面向过程和面向对象思想概述 什么是面向过程 ...

  9. Java面向对象三大特征---继承

    系列文章目录 Java面向对象三大特征-多态 Java面向对象三大特征-封装 文章目录 系列文章目录 前言 一.概念 二.举例说明 三.语句格式 三.为何要使用继承 四.super与this关键字 五 ...

  10. 细说面向对象三大特征

    一.软件设计的概况 1. 软件的生命周期 产品提出需求 分析以及规划 软件编码及其调试(自测,联调) 上测试环境,给测试人员测试(提bug) 上 linux 生产服务器(运维人员维护,修改bug,系统 ...

最新文章

  1. 【learning】矩阵树定理
  2. 第五届全国大学生计算机系统能力培养大赛 | 赠书
  3. 简介Gulp, Grunt, Bower, 和 Npm 对Visual Studio的支持
  4. SQL 2005启用组件Ad Hoc Distributed Queries
  5. 一文详解神经网络与激活函数的基本原理
  6. 什么变量在堆内存里存放,什么变量在栈内存里存放
  7. java中判断字段真实长度(中文2个字符,英文1个字符)的方法
  8. Maven精选系列--依赖范围、传递、排除
  9. linux odbc连接数据库失败,在Linux中使用RODBC连接到SQL Server时出错
  10. 【转】[教程] CSS入门3:如何插入CSS样式
  11. C++ 17 标准正式发布:终于能更简单地编写和维护代码了!
  12. 初学者Pytorch 和 Caffe 使用对比
  13. Excel VBA与VSTO基础实战指南 VBA和VSTO权威教材
  14. 一文回顾腾讯数字生态大会·微搭低代码专场
  15. Java 解压 gzip 和 tar.gz 文件
  16. 【无标题】互联网广告投放优势和前景
  17. python程序输出田字格_Python程序练习题5.1-输出更大的田字格。
  18. built a JNCIS LAB系列:Chapter 1 Routing Policy Processing v1.0
  19. Java导入证书失败Keystore was tampered with, or password was incorrect
  20. C语言大学期末考试重点,快点码住,再也不用担心挂科啦

热门文章

  1. 11-Container With Most Water
  2. js获取url参数方法
  3. TCP: SYN ACK FIN RST PSH URG
  4. 用 Handler 给图片加水印
  5. 【OpenGL】OpenGL安装glew扩展库
  6. hdoj 2046 骨牌铺方格(递推)
  7. 深圳信息职业技术学校 计算机辅助设计和制造,大学生职业生涯规划书样稿.doc...
  8. 浙江省单考单招计算机提前招,2018浙江省各校高职提前招生简章汇总及深度解析...
  9. caffe自带可运行的两个例子:mnist和cifar10
  10. yolov5s 目标检测模型实战——火点烟雾检测实战