多态的概念:

  简单来说就是事物在运行过程中存在的不同状态,即父类或接口定义的引用变量指向子类或具体实现类的实例对象。程序调用方法在运行期才进行动态绑定,而不是引用变量的类型中定义的方法。

多态存在的前提:

1、存在继承关系,子类继承父类;

2、子类重写父类的方法;

3、父类引用指向子类对象。

具体实例:

1、定义一个父类:Animal

 package demo;

  class Animal{
int num = 10;
static int age = 20;
public void eat() {
System.out.println("动物吃饭");
}
public static void sleep() {
System.out.println("动物睡觉");
}
public void run() {
System.out.println("动物奔跑");
}
}

2、子类:Cat继承Animal

 package demo;

 public class Cat extends Animal{
int num=80;
static int age=90;
String name="TomCat";
@Override
public void eat() {
// TODO Auto-generated method stub
System.out.println("猫吃饭");
}
public static void sleep(){
System.out.println("猫在睡觉");
}
public void catchMouse() {
// TODO Auto-generated method stub
System.out.println("猫抓老鼠");
}
}

3、测试类:Test1

 package demo;

 public class Test1 {

     public static void main(String[] args) {
Animal am=new Cat();
am.eat();
am.sleep();
am.run();
System.out.println(am.num);
System.out.println(am.age);
//以下两行注释内容稍后解释
//am.catchMouse();
//System.out.println(am.name);
} }

以上三段代码充分体现了多态存在的前提条件:

1、存在继承关系:Cat 类继承了Animal类;

2、子类要重写父类方法:子类Cat重写(override)了父类Animal的两个方法eat(),sleep(),其中eat()为普通方法,sleep()为静态方法(static);

3、父类引用指向子类对象:测试类中Animal am=new Cat();,语句在堆内开辟了一块内存分配给子类(Cat),并把栈内存中的父类(Animal)的引用指向了这个Cat对象。

测试类运行后的结果:

可以看出:

  1、子类Cat重写的父类Animal的普通方法eat()的输出结果为“猫吃饭”;

     2、子类Cat重写的父类Animal的静态方法sleep()的输出结果为“动物睡觉”;

  3、未被子类Cat重写的父类Animal的普通方法run()的输出结果为“动物奔跑”;

  4、子类Cat继承的父类Animal属性,输出结果分别为父类属性;

  5、输出子类Cat特有属性和方法则会报错。

因此,根据以上分析可以总结出多态成员访问的特点:

Animal am=new Cat();

成员变量:

编译看左(父类),运行看左(父类);

成员方法:

编译看左(父类),运行看右(子类),输入动态绑定;

静态方法:

编译看左(父类),运行看左(父类),静态方法被提升到类级别,算不上重写,所以访问还是看父类;

多态以后不能使用子类特有的属性和方法,在子类Cat中有一个特有的属性String name="TomCat";并且还有一个特有的抓老鼠的方法catchMouse()。但是在测试类Test1中,尝试调用子类的特有方法和打印子类特有的属性时,就会报错。

  那么如果想要使用子类特有的属性和方法该怎么办呢?可以把这个父类引用指向的子类对象强制转换为子类Cat类型,这样am就是子类Cat类型的引用,指向的也是Cat对象了,这样就能够使用子类的一些属性和方法了。

 package demo;

 public class Test1 {

     public static void main(String[] args) {
Animal am=new Cat();
am.eat();
am.sleep();
am.run();
System.out.println(am.num);
System.out.println(am.age);
//以下两行注释内容稍后解释
//am.catchMouse();
//System.out.println(am.name);
System.out.println("-------------------------");
Cat ct=(Cat)am;
ct.eat();
ct.sleep();
ct.run();
ct.catchMouse();
System.out.println(ct.num);
System.out.println(ct.age);
System.out.println(ct.name);
} }

  执行强转语句Cat ct=(Cat)am;后,ct就指向了最开始在堆内存中创建的那个Cat对象了。这就是多态的功能,使用起来十分的灵活,觉少了多余对象的创建,不用为了使用子类的某个方法再去堆内存中开辟一块新的空间给一个新的子类对象了。

花木兰替父从军的例子:

  大家都知道花木兰替父从军的例子,花木兰替父亲花弧从军。那么这时候花木兰是子类,花弧是父类。花弧有自己的成员属性年龄,姓名,性别。花木兰也有这些属性,但是很明显二者的属性值完全不一样。花弧有自己的非静态成员方法‘骑马杀敌’,同样花木兰也遗传了父亲一样的方法‘骑马杀敌’。花弧还有一个静态方法‘自我介绍’,每个人都可以问花弧姓甚名谁。同时花木兰还有一个自己特有的非静态成员方法‘涂脂抹粉’。但是,现在花木兰替父从军,女扮男装。这时候相当于父类的引用(花弧这个名字)指向了子类对象(花木兰这个人),那么在其他类(其他的人)中访问子类对象(花木兰这个人)的成员属性(姓名,年龄,性别)时,其实看到的都是花木兰她父亲的名字(花弧)、年龄(60岁)、性别(男)。当访问子类对象(花木兰这个人)的非静态成员方法(骑马打仗)时,其实都是看到花木兰自己运用十八般武艺在骑马打仗。当访问花木兰的静态方法时(自我介绍),花木兰都是用她父亲的名字信息在向别人作自我介绍。并且这时候花木兰不能使用自己特有的成员方法‘涂脂抹粉’。-----多态中的向上转型

  那么终于一将功成万骨枯,打仗旗开得胜了,花木兰告别了战争生活。有一天,遇到了自己心爱的男人,这时候爱情的力量将父类对象的引用(花弧这个名字)强制转换为子类对象本来的引用(花木兰这个名字),那么花木兰又从新成为了她自己,这时候她完全是她自己了。名字是花木兰,年龄是28,性别是女,打仗依然那样生猛女汉子,自我介绍则堂堂正正地告诉别人我叫花木兰。终于可以使用自己特有的成员方法‘涂脂抹粉’了。从此,花木兰完全回到了替父从军前的那个花木兰了。-----多态中的向下转型

  向上转型向下转型一定是在多态这个前提下,同时向上转型是安全的,向下转型则不安全。比如强制将女儿变成父亲,则女儿可以使用父亲的身份存在,反之,将父亲变成女儿,就变成东方不败了,系统此时就会报错非法类型转换。另外开发中一般利用多态声明形式参数,并将创建子类的匿名对象作为实际参数。

java中多态的实现机制的更多相关文章

  1. 深入Java核心 Java中多态的实现机制(1)

    在疯狂java中,多态是这样解释的: 多态:相同类型的变量,调用同一个方法时,呈现出多中不同的行为特征, 这就是多态. 加上下面的解释:(多态四小类:强制的,重载的,参数的和包含的) 同时, 还用人这 ...

  2. 关于java中多态的理解

    java三大特性:封装,继承,多态. 多态是java的非常重要的一个特性: 那么问题来了:什么是多态呢? 定义:指允许不同类的对象对同一消息做出响应.即同一消息可以根据发送对象的不同而采用多种不同的行 ...

  3. 个人对Java中多态的一些简单理解

    什么是多态 面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. 多态的定义:指允许不同类的对象对同一消息做出响应.即同一 ...

  4. Java中多态的一些简单理解

    什么是多态 .面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. .多态的定义:指允许不同类的对象对同一消息做出响应.即 ...

  5. java中的动态代理机制

    java中的动态代理机制 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现 ...

  6. 从虚拟机指令执行的角度分析JAVA中多态的实现原理

    从虚拟机指令执行的角度分析JAVA中多态的实现原理 前几天突然被一个"家伙"问了几个问题,其中一个是:JAVA中的多态的实现原理是什么? 我一想,这肯定不是从语法的角度来阐释多态吧 ...

  7. java中的安全模型(沙箱机制)

    java中的安全模型(沙箱机制) java安全沙箱(一)之ClassLoader双亲委派机制 java安全沙箱(二)之.class文件检验器 java安全沙箱(三)之内置于Java虚拟机(及语言)的安 ...

  8. Java中的内存处理机制和final、static、final static总结

    Java中的内存处理机制和final.static.final static总结   装载自:http://blog.csdn.net/wqthaha/article/details/20923579 ...

  9. 深度剖析java中JDK动态代理机制

    https://www.jb51.net/article/110342.htm 本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定 ...

随机推荐

  1. 【转】MySQL双主一致性架构优化

    [原文]https://www.toutiao.com/i6594414914838725133/ 一.双主保证高可用 MySQL数据库集群常使用一主多从,主从同步,读写分离的方式来扩充数据库的读性能 ...

  2. Xmind在win10更改用户设置后出现Invalid Configuration Location 错误的解决办法

    错误原因: 因为一开始新建win10用户时,使用的是中文用户名,导致了部分软件比如IDEA读取C盘中配置文件时报错.我用管理员权限修改用户姓名为英文后,IDEA的问题虽然已经解决,但Xmind却报出了 ...

  3. 题解 P1120 【小木棍 [数据加强版]】

    题面 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编程帮 ...

  4. 第二次SDN上机作业

    SDN第二次作业 1.安装floodlight fatter树在floodlight上的连接显示 2.生成拓扑并连接控制器floodlight,利用控制器floodlight查看图形拓扑 floodl ...

  5. phpstorm 的.idea 目录加入.gitignore无效的解决方法

    无效的原因是:对应的目录或者文件已经被git跟踪,此时再加入.gitignore后就无效了, 解决办法: 先执行 git rm -r --cached .idea 再重新加入.gitignore文件 ...

  6. ECStore图片云端集群存储实践-又拍云存储

    通过又拍云存储REST API ,为ECStore新增图片存储引擎,从而达到图片数据与主站数据分离.提高网站性能. 图片存储引擎相关文件添加与修改 一共涉及到ECStore 2个APP 的文件添加和修 ...

  7. luogu P3690 【模板】Link Cut Tree (动态树)

    嘟嘟嘟 LCT竟然看了整整一天,但好歹是看懂了. 教程这里不写,强烈推荐 闪狐大佬的博客 . 但是还是有几句想说的. 1.尽管LCT和splay很像,但是有一些细节还是不一样的.首先是rotate,我 ...

  8. Scala学习之路 (十)Scala的Actor

    一.Scala中的并发编程 1.Java中的并发编程 ①Java中的并发编程基本上满足了事件之间相互独立,但是事件能够同时发生的场景的需要. ②Java中的并发编程是基于共享数据和加锁的一种机制,即会 ...

  9. css里颜色的那些事儿(合法颜色值)

    css中主要有六种方法指定颜色: 1.十六进制颜色 2.RGB颜色 3.RGBA颜色 4.HSL色彩 5.HSLA颜色 6.预定义/跨浏览器的颜色名称 前三种是我们最常见的,也是用的最多的,而后三种对 ...

  10. 🈲Eclipse通过jdbc连接数据库制作简单登陆界面【新手必看】

    一.前言: 做网站开发,要求有多种搭配方式,前台技术可以使用PHP.ASP.JSP.ASP.NET.CGI等任何一种: 需要用到的基础语言用的最多的就是HTML/CSS.JS.JAVA.XML这些了, ...