多态的概念:

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

多态存在的前提:

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. Linux uniq命令详解

    uniq常见命令参数 用法:uniq [选项]... [文件] 从输入文件或者标准输入中筛选相邻的匹配行并写入到输出文件或标准输出. 不附加任何选项时匹配行将在首次出现处被合并. 长选项必须使用的参数 ...

  2. MySQL数据库的安装与基本操作

    实验要求: 1.安装mysql源码包,并做相关的配置和优化路径,启动服务. 步骤: 1)先查询MySQL软件的安装情况,如果有建议将其卸载, 2)安装光盘自带的ncurses-devel包. 3)My ...

  3. 【Java123】JavaWeb Servlet开发

    http://www.runoob.com/servlet/servlet-intro.html https://www.cnblogs.com/xdp-gacl/tag/JavaWeb学习总结/de ...

  4. leetcode 280.Wiggle Sort 、324. Wiggle Sort II

    Wiggle Sort: 注意:解法一是每次i增加2,题目不是保证3个3个的情况,而是整个数组都要满足要求. 解法一错误版本: 如果nums的长度是4,这种情况下nums[i+1]会越界.但是如果你用 ...

  5. PHP7.0新特性

    http://blog.csdn.net/h330531987/article/details/74364681 反射 闭包 trait 还有数组

  6. Python2.7-textwrap

    textwrap主要针对英文的文本 模块内方法: wrap(text[, width, ...]),把text分成每行width长,返回一个列表,没有结尾的\n.fill(text[, width, ...

  7. loadrunner中pacing的设置

    通常我们在谈到一个软件的“性能”的时候,首先想到的就是“响应时间”和“并发用户数”这两个概念.我们看到的性能需求经常都是这样定义的: “要求系统支持 100 个并发用户” 看到这样的性能需求,我们往往 ...

  8. HDU 3342 Legal or Not(有向图判环 拓扑排序)

    Legal or Not Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  9. rownum与row_number() OVER (PARTITION BY COL1 ORDER BY COL2)

    1)rownum 为查询结果排序.使用rownum进行排序的时候是先对结果集加入伪列rownum然后再进行排序 select rownum n, a.* from ps_user a order by ...

  10. Docker的Mysql数据库:把数据存储在本地目录

    Docker mysql 把数据存储在本地目录,很简单,只需要映射本地目录到容器即可 1.加上-v参数 $ docker run -d -e MYSQL_ROOT_PASSWORD=admin --n ...