多态
多态
-
概述:
//多态是即封装性,继承之后,面向对象的第三大特征。
-
定义
//多态:同一行为,的不同的表现形式 生活中,比如跑的动作,猫,狗,大象,跑起来的动作是不一样的。再比如飞的动作:昆虫,鸟飞起来的动作是不一样的。可见,同意行为,通过不同的事物,可以表现不同的形态。多态描述的就是这样的一种状态。
-
前提条件
1. 继承或者实现(二选其一) 2. 父类的引用指向子类的对象(格式体现) 3. 方法的重写(意义:不重写没意义)
-
多态的表现
多态的表现得格式
父类类型 变量名 = new 子类对象(); 变量名.方法名(); //备注:父类类型指的是子类对象继承的父类类型,或者实现的父接口类型
public class Fu{ public void method(){ System.out.println("这是父类的method方法"); } } public void Zi extends Fu{ @Override public void method(){ System.out.println("这是子类的method方法"); } } //polymorphism 多态 public class Text{ public static void main(String[] args){ //父类类型 变量名 = new 子类对象(); Fu f = new Zi(); //子类没有重写父类的方法输出的是继承的方法 //子类重写父类的方法本质调用的是子类当中重写后的method方法 } } //如果在使用多态方式调用方法时,首先检查父类当中是否有该方法,如果没有,则编译报错,如果有执行的是子类重写后的方法。
-
多态的好处
在实际开发中,父类类型作为方法的形式(形参)(不同于实际参数),传递子类对象(实参)给方法,进行方法的调用,更能体现出多态的扩展性和便利性。
//定义抽象父类 public abstract class Animal{ //定义抽象方法 public abstract void eat(); } //定义子类继承抽象父类 public class Cat extends Animal{ @Override public void eat(){ System.out.println("🐱吃🐟"); } } //定义子类继承抽象父类 public class Dog extends Animal { @Override public void eat() { System.out.println("🐕吃🥩"); } } //测试类 public class Text { public static void main(String[] args) { //根据不同的对象,来表现出不同的吃的内容 Animal c=new Cat(); ShowAnimalEat(c); Animal d=new Dog(); ShowAnimalEat(d); } //调用方法 public static void ShowAnimalEat()(Animal a){ a.eat(); } } //备注用于多态特性的支持,showEat方法当中的Animal类型,是cat和dog的父类类型,父类类型接受子类对象,当然可以把cat和dog对象传递给方法。 //当程序执行过程中。执行eat方法实际上执行的是各自子类对象重写之后的eat方法不仅仅可以做到替代,在扩展性方面,无论之后出现多个子类,都不需要编写首位XxxEat方法了,直接使用ShowAnimalEat()方法了。 //多态的好处,体现在可以使用程序编写更简单,具有良好的扩展性。
-
访问类中的成员变量有两种方式
- 直接通过对象名访问成员变量:看等号左边是谁,优先用谁,没有继续往上找。
- 间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则继续往上找。
//定义父类 public class Fu{ int num=10; //定义成员方法 public void showNum(){ System.out.println(this.num);//访问本类的对象前隐式有一个this. } } //定义子类 public class Zi extends Fu{ int num=20; //子类重写父类方法 @Override public void showNum(){ System.out.println(num); } } //测试类 public class Text{ public static void main(String[] args){ Fu fu = new Zi(); System.out.println(fu.num);//10 fu.showNum;//20 } }
-
引用数据类型的转型
多态的转型分为:向上转型和向下转型
-
向上转型
//多态本身就是子类类型向父类类型向上转型的过程,这个过程是默认的 当一个父类指向了子类对象,便是向上转型 使用格式: 父类类型 变量名 = new 子类类型(); 比如:Animal animal = new cat();
-
向下转型
父类类型向子类类型转换的过程,这个过程是强制的。 一个已经向上转型的子类对象,将父类的引用转为子类引用,可以使用强制类型转换的格式,便是向下转型。 使用格式: 子类类型 变量名 = (子类类型)父类变量名; 比如:Cat cat = (Cat)animal; //如果强制失败可能发生 ClassCastException的异常
- 向上转型一定是安全的,没有问题的,正确的。但是也有一个弊端
- 对象一旦向上转型成父类,那么就无法调用子类原本特有的内容
-
转型的异常
在进行向下转换的过程中,一步小心就出现java.lang.ClassException类型转换异常。 为了避免这中类型转换异常的发生,Java提供了instanceof关键字,给引用变量做类型的效验。
//变量名 instanceof 数据类型 如果变量属于该数据类型,则返回true 如果变量不属于该数据类型,则返回false //所以我们在转化前,我们最好先进性引用变量的类型判断
public class Test { public static void main(String[] args) { // 向上转型 Animal animal = new Cat(); // 向下转型 if (animal instanceof Cat) { // 表明你就是一只猫 Cat cat = (Cat) animal; cat.eat();// 吃鱼 cat.catchMouse();// 逮老鼠 } else if (animal instanceof Dog) { // 表明你就是一只狗 Dog dog = (Dog) animal; dog.lookDoor(); } } }
-