Java之多态
Posted wurengen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java之多态相关的知识,希望对你有一定的参考价值。
多态的概述
多态是继封装、继承之后,面向对象的第三大特性。 生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如飞的动作,昆虫、鸟类和飞机,飞起来也 是不一样的。可见,同一行为,通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。一个对象拥有多种形态,这就是对象的多态性。例如:小明是一个学生(学生形态),但也是一个人(人类形态)。
定义
多态: 是指同一行为,具有多个不同表现形式。
前提
- 继承或者实现【二选一】
- 方法的重写【意义体现:不重写,无意义】
- 父类引用指向子类对象【格式体现】
多态的体现
多态体现的格式:
- 父类名称 变量名 = new 子类对象;
或者
- 接口名称 对象名 = new 实现类名称();
多态中成员变量的访问特点
访问成员变量的两种方式:
- 直接通过对象名称访问成员变量名称:看等号左边是谁,优先用谁,没有则向上找。
- 间接通过成员方法访问成员变量名称:看该方法属于谁,优先用谁,没有则向上找。
多态中的成员方法的访问特点
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写 后方法。 口诀:编译看左边,运行看右边。
在多态的代码当中,成员方法的访问规则是:看new的是谁,就优先用谁,没有则向上找。
对比:
- 成员变量:编译看左边,运行还看左边。
- 成员方法:编译看左边,运行看右边。
代码举例
定义父类
package My.demo02; public class Father { //定义成员变量 String name = "张三"; //定义成员方法 public void method() { System.out.println("我是父类中的方法"); } public void methodFather() { System.out.println("我是父类中独有的方法,我的名字是" + name); } }
定义子类
package My.demo02; public class Son extends Father { //定义子类成员变量 String name = "李四"; @Override //重写父类的成员方法 public void method() { System.out.println("我重写了父类中的方法,我的名字是:" +name); } }
定义测试类
package My.demo02; public class Test { public static void main(String[] args) { /*父类类型 变量名 = new 子类对象; 父类类型:指子类对象继承的父类类型,或者实现的父接口类型。 */ //多态写法 Father multi = new Son(); //调用子父类重名的方法,编译看父类,实际运行子类中的方法, multi.method(); //调用父类中独有的方法:编译看父类,因为子类中没有相同的方法,所以向上查找 multi.methodFather(); //访问子父类重名成员变量,等号左边的是谁,优先使用谁的成员变量 String name = multi.name; System.out.println(name); } }
代码执行后的结果
多态的好处
实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用(多态规定,执行的是子类重写的方法),更能体现出多态的扩展性与便利。
引用类型转换
- 多态的转型分为向上转型与向下转型两种:
向上转型
向上转型:多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。 当父类引用指向一个子类对象时,便是向上转型。 向上转型一定是安全的。
- 使用格式:父类类型 变量名 = new 子类类型();
- 含义:创建一个子类对象,把它当做父类来看待使用
例如
向下转型
向下转型:父类类型向子类类型向下转换的过程,这个过程是强制的。 一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型。
- 使用格式:子类类型 变量名 = (子类类型) 父类变量名;
- 含义:将父类对象还原成为本来的子类对象
例如:
注意事项:
- 必须保证对象创建的时候就dog对象,才能向下转型为dog。否则运行时,却报出了 ClassCastException ,类型转换异常!
为什么要转型
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥 有,而父类没有的方法。编译都错误,更别说运行了。这也是多态给我们带来的一点"小麻烦"。所以,想要调用子 类特有的方法,必须做向下转型。
向下转型容易发生的问题
如果创建了A 对象,却把它向下转型成为B 对象,在运行时,会报出了 ClassCastException ,类型转换异常!为了避免ClassCastException的发生,Java提供了 instanceof 关键字,给引用变量做类型的校验,格式如下:
代码举例
定义接口Animal
定义实现类Cat
package myDemo04; public class Cat implements Animal{ @Override public void eat() { System.out.println("我喜欢吃鱼"); } public void CatRun(){ System.out.println("我是猫,跑起来没有声音"); } }
定义实现类Dog
package myDemo04; public class Dog implements Animal { @Override public void eat() { System.out.println("我喜欢吃骨头"); } public void DogRun(){ System.out.println("我是狗,跑的好快好快"); } }
定义测试类
package myDemo04; public class Test { public static void main(String[] args) { //父类引用指向子类对象就是向上转型: Animal animal = new Dog(); //调用方法,编译看左,运行看右 animal.eat(); // Cat cat = (Cat) animal;创建了Dog对象,转换为Cat对象,运行会报ClassCastException ,类型转换异常! if (animal instanceof Dog) { //将父类引用转为子类引用,便是向下转型。 Dog dog = (Dog) animal; //调用子类中特有的方法 dog.DogRun(); } if (animal instanceof Cat) { //将父类引用转为子类引用,便是向下转型。 Cat cat = (Cat) animal; //调用子类中特有的方法 cat.CatRun(); } } }
代码执行后的结果
以上是关于Java之多态的主要内容,如果未能解决你的问题,请参考以下文章