多态的概念:

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

多态存在的前提:

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. Django之MVC与MTV

    MVC框架 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写 模型 - 视图 - 控制器是一种通常用于开发用户界面的 ...

  2. Shell 脚本合集

    0. 说明  Shell 脚本合集 1. xcall.sh xcall.sh 编写为了为了同时对多台服务器进行操作,编写完成之后,将其发送到 /usr/local/bin 下 #!/bin/bash ...

  3. 关于Excel中的行列转换

    1. 先选择想要的数据进行复制 然后选择你要粘贴的位置点击 “选择性粘贴” 点击  “转置” 完成

  4. 2019 wannafly winter camp

    2019 wannafly winter camp Name Rank Solved A B C D E F G H I J K day1 9 5/11 O O O O O day2 5 3/11 O ...

  5. MySQL数据库常用操作和技巧

    MySQL数据库可以说是DBA们最常见和常用的数据库之一,MySQL的广泛应用,也使更多的人加入到学习它的行列之中.下面是老MySQL DBA总结的MySQL数据库最常见和最常使用的一些经验和技巧,分 ...

  6. 如何将XML文件导入Excel中

    如下图所示为一个规范的XML文件,在Excel中可以将规范的XML文件导入到Excel成为规范的表格.具体有如下几种方法:   工具/原料   Excel 方法/步骤     单击“数据”选项卡下的“ ...

  7. 基于TP5使用Websocket框架之GatewayWorker开发电商平台买家与卖家实时通讯

    https://www.cnblogs.com/wt645631686/p/7366924.html 前段时间公司提了一个新的需求,在商品的详情页要实现站内买家和商品卖家实时通讯的功能以方便沟通促成交 ...

  8. CentOS 7的安装

    一.引导系统之后 界面说明: Install CentOS 7 安装CentOS 7 Test this media & install CentOS  7 测试安装文件并安装CentOS  ...

  9. mysql的查询使用explain的讲解

    摘自:http://www.jb51.net/article/33736.htm 在 explain的帮助下,您就知道什么时候该给表添加索引,以使用索引来查找记录从而让select 运行更快.如果由于 ...

  10. 【css】文本超出行数以省略号显示

    //超出2行省略overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical;-webk ...