标签:状态 spl inf abstract 避免 play eth sdn ted
多态是继封装、继承之后,面向对象的第三大特性。 生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如飞的动作,昆虫、鸟类和飞机,飞起来也 是不一样的。可见,同一行为,通过不同的事物,可以体现出来的不同的形态。多态,描述的就是这样的状态。一个对象拥有多种形态,这就是对象的多态性。例如:小明是一个学生(学生形态),但也是一个人(人类形态)。
多态: 是指同一行为,具有多个不同表现形式。
前提
多态体现的格式:
或者
访问成员变量的两种方式:
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,执行的是子类重写 后方法。 口诀:编译看左边,运行看右边。
在多态的代码当中,成员方法的访问规则是:看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); } }
代码执行后的结果
实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用(多态规定,执行的是子类重写的方法),更能体现出多态的扩展性与便利。
向上转型
向上转型:多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。 当父类引用指向一个子类对象时,便是向上转型。 向上转型一定是安全的。
例如
向下转型
向下转型:父类类型向子类类型向下转换的过程,这个过程是强制的。 一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型。
例如:
注意事项:
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误。也就是说,不能调用子类拥 有,而父类没有的方法。编译都错误,更别说运行了。这也是多态给我们带来的一点"小麻烦"。所以,想要调用子 类特有的方法,必须做向下转型。
如果创建了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(); } } }
代码执行后的结果
标签:状态 spl inf abstract 避免 play eth sdn ted
原文地址:https://www.cnblogs.com/wurengen/p/11973737.html