polymorphism java_Java基础-面向对象第三大特性之多态(polymorphism)

Java基础-面向对象第三大特性之多态(polymorphism)

作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.多态概述

多态是继封装,继承之后,面向对象的第三大特性,多态的前提是继承。

从现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三即是学生也是人。即出现两种形态。Java作为面向对象的语言,同样可以描述一个事物的多种形态。如Student类继承了Person类,一个Student的对象便既是Student,又是Person。

最终多态体现为父类引用变量可以指向子类对象。多态的前提是必须有子父类关系或者类实现接口关系,否则无法完成多态。在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。

二.多态调用的三种形式

多态调用方法,方法必须运行子类的重写!

1>.多态的定义格式:就是父类的引用变量指向子类对象。

1 父类类型 变量名 = new子类类型();2 变量名.方法名();

2>.普通类多态定义的格式

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classFather{8 public voidshow(){9 System.out.println("父类的show方法!");10 }11 }12

13 class Son extendsFather{14 public voidshow(){15 System.out.println("子类重写父类的show方法!");16 }17 }18

19 public classMyInterfaceDemo{20 public static voidmain(String[] args){21 //Java中,对象的多态性,调用公式:“父类类型或者接口类型 变量 = new 子类对象();”

22 Father f = newSon();23 f.show();24 }25 }26

27

28

29 /*

30 以上代码执行结果如下:31 子类重写父类的show方法!32 */

3>.抽象类多态定义的格式

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 abstract classFather{8 public abstract voideat();9 }10

11 class Son extendsFather{12 public voideat(){13 System.out.println("儿子喜欢吃米饭!");14 }15 }16

17 public classMyInterfaceDemo{18 public static voidmain(String[] args){19 //抽象类Father,子类是Son

20 Father f = newSon();21 f.eat();22 }23 }24

25

26

27 /*

28 以上代码执行结果如下:29 儿子喜欢吃米饭!30 */

4>.接口多态定义格式

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 interfaceFather{8 public abstract voidsmoking();9 }10

11 class Son implementsFather{12 public voidsmoking(){13 System.out.println("儿子会抽烟!");14 }15 }16

17 public classMyInterfaceDemo{18 public static voidmain(String[] args){19 //接口Father,实现类Son

20 Father f = newSon();21 f.smoking();22 }23 }24

25

26

27 /*

28 以上代码执行结果如下:29 儿子会抽烟!30 */

三.多态中成员变量的特点

1>.成员变量(编译运行全看父类)

a>.编译的时候,参考父类中有没有这个变量,如果有,编译成功,没有则编译失败;

b>.运行的时候,运行的是父类中的变量值;

2>.成员方法(编译看父类,运行看子类。)

a>.编译的时候,参考父类中有没有这个方法,如果有,编译成功,没有则编译失败

b>.运行的时候,运行的是子类的重写方法;

3>.静态成员方法

没有多态性。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classFather{8 int age = 30;9 public voidshow(){10 System.out.println("Father的方法");11 }12 }13

14 class Son extendsFather{15 int age = 8;16 public voidshow(){17 System.out.println("Son的方法");18 }19 }20

21 public classMyInterfaceDemo{22 public static voidmain(String[] args){23 Father f = newSon();24 System.out.println(f.age);25 f.show();26 }27 }28

29

30

31 /*

32 以上代码执行结果如下:33 3034 Son的方法35 */

四.instanceof关键字

我们了解多态之后,会发现一个对象的数据类型不一定会保持不变。当我们想要确定一个对象是否是某个类时,就会用到比较运算符,只不过它很特殊,不能赢大于小于或是等于号直接进行判断,而是要用到关键字,即instanceof,它只能用作比较引用数据类型,用来比较一个引用类型的变量,是不是这个类型的对象。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 abstract classPerson{8 public abstract voidsleep();9 }10

11

12 class Student extendsPerson{13 public voidsleep(){14 System.out.println("学生在休息!");15 }16 }17

18 class Teacher extendsPerson{19 public voidsleep(){20 System.out.println("老师在休息!");21 }22 }23

24 public classPersonDemo{25 public static voidmain(String[] args){26

27 Person p = newStudent();28

29 p = newTeacher();30

31 boolean flag = p instanceofStudent;32

33 System.out.println("引用数据类型'p'是否为Student类型:>>> " +flag);34

35 p.sleep();36 }37 }38

39

40

41

42 /*

43 以上代码执行结果如下:44 引用数据类型'p'是否为Student类型:>>> false45 老师在休息!46 */

五.多态转型

1>.多态的向上转型

多态常见的就是自动类型提升,将取值范围小的,自动提升为取值范围大的。范围小的,看成是子类,范围大的看成父类。

优点:

这样做的好出就是可以调用子类父类的公共属性(方法)。

缺点:

无法调用子类特有的属性(方法)。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 abstract classPerson{8 public abstract voidsleep();9 }10

11

12 class Student extendsPerson{13 public voidsleep(){14 System.out.println("学生在休息!");15 }16 }17

18 class Teacher extendsPerson{19 public voidsleep(){20 System.out.println("老师在休息!");21 }22 }23

24 public classPersonDemo{25 public static voidmain(String[] args){26

27 //从子类对象往父类变量赋值(自动类型提升,向上转型)

28 Person p = newStudent();29

30 }31 }

2>.多态的向下转型

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 abstract classPerson{8 public abstract voidsleep();9 }10

11

12 class Student extendsPerson{13 public voidsleep(){14 System.out.println("学生在休息!");15 }16 }17

18 class Teacher extendsPerson{19 public voidsleep(){20 System.out.println("老师在休息!");21 }22 }23

24 public classPersonDemo{25 public static voidmain(String[] args){26

27 //从子类对象往父类变量赋值(自动类型提升,向上转型)

28 Person p = newStudent();29

30

31 //从父类类型转向子类类型(向下转型)

32 Student s =(Student)p;33

34 }35 }

3>.多态转型的案例

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 abstract classAnimal{8 public abstract voideat();9 }10

11 class Cat extendsAnimal{12 public voideat(){13 System.out.println("猫吃猫粮!");14 }15

16 public voidcatchMouse(){17 System.out.println("猫抓老鼠!");18 }19 }20

21 class Dog extendsAnimal{22 public voideat(){23 System.out.println("狗吃狗粮!");24 }25

26 public voidrun(){27 System.out.println("狗能跑!");28 }29 }30

31 public classAnimalDemo{32 public static voidmain(String[] args){33 //两个子类,使用两次多态调用

34 Animal a1 = newCat();35 Animal a2 = newDog();36 //a1,a2调用子类父类共有方法,运行走子类的重写方法

37 a1.eat();38 a2.eat();39 /*类型向下转型,强制转换,调用子类的特有,防止发生异常,40 a1属于CatUI小,转成Cat类,a2属于Dog对象,转成Dog类,我们41 可以用关键字instanceof判断。42 */

43 if(a1 instanceofCat){44 Cat c =(Cat)a1;45 c.catchMouse();46 }47

48 if(a2 instanceofDog){49 Dog d =(Dog)a2;50 d.run();51 }52

53 }54 }55

56

57 /*

58 以上代码执行结果如下:59 猫吃猫粮!60 狗吃狗粮!61 猫抓老鼠!62 狗能跑!63 */

六.匿名对象

1>.匿名对象的概念

匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classPerson{8 public voideat(){9 System.out.println("人是铁,饭是钢,一顿不吃饿得慌!");10 }11 }12

13

14 public classPersonDemo{15 public static voidmain(String[] args){16

17 //有名字的对象,引用类型变量,可以反复使用eat方法。

18 Person p = newPerson();19 p.eat();20

21 //匿名对象,没有引用变量,只能使用一次,如果你再通过new调用eat方法的话实际上是又新生成了一个对象。

22 newPerson().eat();23 newPerson().eat();24

25 }26 }

2>.匿名对象的特点

a>.创建匿名对象直接使用,没有变量名;

b>.匿名对象在没有指定其引用变量时,只能使用一次;

c>.匿名对象可以作为方法接受的参数,方法返回值使用;

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classPerson{8 public voideat(){9 System.out.println("人是铁,饭是钢,一顿不吃饿得慌!");10 }11 }12 public classPersonDemo{13 public static voidmain(String[] args){14 //有名字的对象,引用类型变量,可以反复使用eat方法。

15 Person p = newPerson();16 p.eat();17 //匿名对象,没有引用变量,只能使用一次,如果你再通过new调用eat方法的话实际上是又新生成了一个对象。

18 newPerson().eat();19 newPerson().eat();20 method(p);21

22 //匿名方法当实参

23 method(newPerson());24 p =method();25 method(p);26 }27 //方法的返回值是Person类型,方法的return语句,返回的是这个类的对象。就可以用匿名对象来实现。

28 public staticPerson method(){29 return newPerson();30 }31 //调用方法method,传递Person类型对象

32 public static voidmethod(Person p){33 p.eat();34 }35 }36

37

38

39 /*

40 以上代码执行结果如下:41 人是铁,饭是钢,一顿不吃饿得慌!42 人是铁,饭是钢,一顿不吃饿得慌!43 人是铁,饭是钢,一顿不吃饿得慌!44 人是铁,饭是钢,一顿不吃饿得慌!45 人是铁,饭是钢,一顿不吃饿得慌!46 人是铁,饭是钢,一顿不吃饿得慌!47 */

七.内部类

1>.内部类概念

a>.什么是内部类

将类写在其它类的内部,可以写在其它类的成员位置和局部位置,这时写在其它类内部的类成为内部类,其它类也称为外部类。

b>.什么时候使用内部类

在描述事物时,若一个事物内部还包含其它可能包含的事物,比如在描述汽车时,汽车中还包含这发动机,这时发动机就可以使用内部类来描述。

c>.内部类分类

内部类分为成员内部类和局部内部类。我们定义内部类时,就是一个正常定义类的过程,同样包含各种修饰符,继承与实现关系等。在内部类中可以直接访问外部类的所有成员。

2>.成员内部类的调用格式

内部类可以使用外部类成员,包括私有变量。外部类要使用内部类的成员,必须建立内部类对象。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classOuter{8 private int a = 100;9 classInner{10 public voidinner(){11 System.out.println("内部类方法inter " +a);12 }13 }14 }15

16 public classInnerClassDemo{17 public static voidmain(String[] args){18 //创建内部类对象in

19 Outer.Inner in = new Outer().newInner();20 //调用内部类方法

21 in.inner();22 }23 }24

25

26 /*

27 以上代码执行结果如下:28 内部类方法inter 10029 */

3>.成员内部类的同名变量调用

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classOuter{8 int a = 100;9 classInner{10 int a = 200;11 public voidinner(){12 int a = 300;13 System.out.println("内部类局部变量(内部类成员方法)访问:>>> "+a);14 System.out.println("内部类成员变量访问:>>> "+ this.a);15 System.out.println("外部类成员变量访问:>>> "+ Outer.this.a);16 }17 }18 }19

20 public classInnerClassDemo{21 public static voidmain(String[] args){22 //创建内部类对象in

23 Outer.Inner in = new Outer().newInner();24 //调用内部类方法

25 in.inner();26 }27 }28

29

30 /*

31 以上代码执行结果如下:32 内部类局部变量(内部类成员方法)访问:>>> 30033 内部类成员变量访问:>>> 20034 外部类成员变量访问:>>> 10035 */

3>.局部内部类

局部内部类,定义在外部类方法中的局部位置。与访问方法中的局部变量相似,可通过调用方法进行访问。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 classOuter{8 public voidout(){9 classInner{10 public voidinner(){11 System.out.println("局部内部类方法!");12 }13 }14 //创建我们定义的Inner对象

15 Inner in = newInner();16 //调用创建好的对象的方法,这样不管谁只要能调用out方法就会触发调用Inner类中的inner()方法啦!

17 in.inner();18 }19 }20

21 public classInnerClassDemo{22 public static voidmain(String[] args){23 newOuter().out();24 }25 }26

27

28 /*

29 以上代码执行结果如下:30 局部内部类方法!31 */

4>.匿名内部类

a>.匿名内部类概念

内部类是为了应对更为复杂的类间关系。查看源代码中会涉及到,而在日常业务中很难遇到,这里不做赘述。最长用到的内部类就是匿名内部类,它是局部内部类的一种。定义的匿名内部类有两个含义:第一,临时定义某一指定类型的子类;第二,定义后即刻创建刚刚定义的这个子类的对象。

b>.定义匿名内部类的作用与格式

匿名内部类是创建某个子类对象的快捷方式。

1 /*

2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/

4 EMAIL:y1053419035@qq.com5 */

6

7 interfaceSmoking{8 public abstract voidsmoking();9 }10

11 public classSmokingDemo{12 public static voidmain(String[] args){13 //这就是用匿名对象实现接口并调用接口中的方法,切记不要忘记调用smoking()了哟!

14 newSmoking(){15 public voidsmoking(){16 System.out.println("运维不喜欢吸烟!");17 }18 }.smoking();19 }20 }21

22 /*

23 以上代码执行结果如下:24 运维不喜欢吸烟!25 */

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/506711.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java如何把png转换成jpg_Java实现将png格式图片转换成jpg格式图片的方法【测试可用】...

Java实现将png格式图片转换成jpg格式图片的方法【测试可用】发布于 2020-4-9|复制链接摘记: 本文实例讲述了Java实现将png格式图片转换成jpg格式图片的方法。分享给大家供大家参考,具体如下:javaimport java.awt.Color;import java.awt.image.BufferedIm…

php反序列化漏洞 freebuf,最全的PHP反序列化漏洞的理解和应用

原创:f1r3K0php反序列化漏洞,又叫php对象注入漏洞,是一种常见的漏洞,在我们进行代码审计以及CTF中经常能够遇到。01学习前最好提前掌握的知识PHP类与对象(https://www.php.net/manual/zh/language.oop5.php)PHP魔术方法(https://s…

php按数字分页类,PHP简单实现数字分页功能示例

本文实例讲述了PHP简单实现数字分页功能。分享给大家供大家参考&#xff0c;具体如下&#xff1a;header ( Content-Type: text/html; charsetutf-8 );//分页$page$_GET[page];$allcount 100;$page_size 10;$page_show 5;$page_count ceil($allcount/$page_size);if($page <…

php 瀑布流布局,CSS3实现瀑布流布局的方法

这次给大家带来CSS3实现瀑布流布局的方法&#xff0c;CSS3实现瀑布流布局的注意事项有哪些&#xff0c;下面就是实战案例&#xff0c;一起来看一下。以前使用瀑布流都要用js&#xff0c;现在有了css3&#xff0c;可以轻松实现了。掌握点&#xff1a;1、column-count 把p中的文本…

php 文章列表,ThinkPHP初学者:主页,获取一个文章列表

在之前的文章&#xff0c;已经实现了注册登录的功能&#xff0c;主要熟悉TP与HTML、JS交互&#xff0c;数据库的基本操作等。接下来就要登录到主页&#xff0c;熟悉一下列表的处理&#xff0c;以及数据库多表联查操作。为了简化模型&#xff0c;列表的字段仅有文章标题、简介、…

JAVA中数字格式异常,java - Java数字格式异常 - 堆栈内存溢出

当我遇到NumberFormatException时&#xff0c;我正在CodeChef平台上解决问题。首先&#xff0c;我使用Scanner处理输入&#xff0c;然后使用BufferedReader 。 但是他们都不起作用&#xff01;这是我的代码&#xff1a;import java.io.*;import java.util.*;import java.text.*…

java excel 打勾,两种方法教你如何在excel文件中打勾

两种方法教你如何在excel文件中打勾方法一&#xff1a;通过复选框功能打勾本方法是通过Excel文件中的开发工具栏中的功能实现打勾的。有时候如果我们在Excel文件中找不到“开发工具”功能&#xff0c;这时我们可以通过“Excel选项”功能来进行设置。首先我们点击Excel文件左上角…

数字图像matlab心得,Matlab数字图像处理的学习建议

如果是软实力,学好数学才是王道!和机器学习和计算机视觉相关的数学(转载)(以下转自一位MIT牛人的空间文章&#xff0c;写得很实际&#xff1a;)作者&#xff1a;Dahua感觉数学似乎总是不够的。这些日子为了解决research中的一些问题&#xff0c;又在图书馆捧起了数学的教科书。…

php js登录,php+js实现单点登录

phpjs实现单点登录2020年08月14日 00:45:23阅读数&#xff1a;110登录信息表DROP TABLE IF EXISTS fly_admin_login_info;CREATE TABLE fly_admin_login_info (id int(11) unsigned NOT NULL AUTO_INCREMENT,admin_id int(11) unsigned DEFAULT NULL,email varchar(80) DEFAULT…

php 本站已运行了多少天,本站已运行了多少天”代码(js版+php版)

最初用的是js的脚本&#xff0c;代码如下&#xff1a;var urodz new Date(“4/15/2010″); //建站时间var now new Date();var ile now.getTime() – urodz.getTime();var dni Math.floor(ile / (1000 * 60 * 60 * 24));document.write(dni)后来发现&#xff0c;这个脚本对客…

php class类 教程,PHP类(Class)入门教程第2/2页

用正确的小汽车对象学习和熟悉类的概念很多书讲到类总喜欢拿小汽车来做例子&#xff0c;但是有些例子实在是又臭又烂误人子弟&#xff0c;骗人钱财&#xff0c;毁人前程&#xff0c;弱智低级到瞎编一个什么 set_color()函数来教人。实在是白白糟踏了好东西。今天在phpx.com又看…

php 控制器 模板,php学习笔记(一)php模板与控制器

/welcome/index.phpif(!isset($_REQUEST[fn])){include from.html.php;}else{$firstname $_REQUEST[fn];$lastname $_REQUEST[lastname];if($firstname 孙 and $lastname 哥){$aa 欢迎登陆&#xff0c;我的国王&#xff01;;}else{$aa 欢迎登陆 .htmlspecialchars($first…

android jni java调用c,Android与JNI(一) ---- Java调用C 静态调用

第一、通过eclipse新建一个工程名为HelloJni的android工程&#xff0c;并编译。第二、右键工程-->Android Tools --> Add Native Support,出现如下界面&#xff0c;名字默认就可以了&#xff0c;点击finish。第三、我们在MainActivity类中加入要调用的native代码public n…

ocid oracle,Oracle数据库基础:新手推荐

Oracle数据库的主要特点(1.)支持多用户&#xff0c;大事务量的事务处理(2.)在保持数据库安全性和完整性方面性优越。(3.)支持分布式数据处理。将分布在不同物理位置的数据库用通信网连接起来&#xff0c;在分布式数据库管理系统的控制下&#xff0c;组成一个逻辑上统一的数据库…

oracle存储过程 取时间格式,Oracle存储过程获取YYYY-MM-DD的时间格式

环境&#xff1a;Oracle 10g,11g 问题重现&#xff1a;PL/SQL中命令窗口下&#xff0c;发现存储过程得到的时间格式不符合预期要求。 SQLgt; select sysdate fro环境&#xff1a;Oracle 10g,11g问题重现&#xff1a;PL/SQL中命令窗口下&#xff0c;发现存储过程得到的时间格式不…

oracle归档日志 delete obsolete 保留一次全备,DELETE OBSOLETE不删除归档日志以及归档的备份集...

今天遇到一个奇怪的事情&#xff0c;使用OBSOLETE不删除归档日志&#xff0c;而且也不删除过期的归档的BACKUP SET从delete obsolete的概念来看如下&#xff1a;The REPORT OBSOLETE and DELETE OBSOLETE commands work in two steps:For each datafile for which there are fu…

oracle 12 sqlplus 使用,oracle 12.2 sqlplus history

12.1开始使用sqlplus显示用户上次登录时间&#xff0c;12.2提供了一个记录历史sql的功能&#xff0c;类似于操作系统的history&#xff0c;根目录下的.history文件&#xff0c;不过功能比操作系统的history要强大&#xff0c;可以指定删除/运行/编辑历史记录里面的某一条SQL&am…

execl执行linux命令,使用execl运行Linux命令

我需要通过编写C语言程序列出当前目录中具有644权限的所有文件.我不能使用system()并且必须使用execl()才能使用系统调用.这是我在代码中使用的一行&#xff1a;execl("/usr/bin/find", "find . -maxdepth 1 -perm 644", (char *)NULL);问题是代码正在搜索…

Linux里面lvs的基础命令,Linux中使用ipvsadm配置LVS集群的基本方法

LVS集群有DR、TUN、NAT三种配置模式&#xff0c;可以对www服务、FTP服务、MAIL服务等做负载均衡&#xff0c;下面通过搭建www服务的负载均衡实例&#xff0c;讲述基于DR模式的LVS集群配置。一、 Director Server的配置  在Director Server上配置LVS负载均衡集群&#xff0c;有…

linux 内核 睡眠,linux内核对S3C2410睡眠模式的支持有哪些?

一、S3C2410支持4种供电模式(1)NORMAL MODE耗电最大、可以通过关闭具体控制器的时钟来节电(2)SLOW MODE在此模式下可以没有内部PLL&#xff0c;耗电情况依赖于外部时钟的频率(3)IDLE MODEFCLK被关断&#xff0c;主要由于CPU core节电。可以任何通过外部中断唤醒(4)Power_OFF MO…