ok了家人们,今天我们学习了面向对象-多态,话不多说我们一起来看看吧
一.多态概述
面向对象的第三大特性:封装、继承、多态
我们拿一个生活中的例子来看
生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样
的。再比如飞的动作,昆虫、鸟类和飞机,飞起来也是不一样
的。可见,同一行为,通过不同的事物,可以体现出来的不同
的形态。
多态 : 是指同一行为,对于不同的对象具有多个不同表现形
式。
程序中多态 : 是指同一方法 , 对于不同的对象具有不同的实现。
多态前提条件
继承或者实现【二选一】
父类类型指向子类对象【格式体现】 父类类型 变量名 =
new 子类类型 ();
方法的重写【意义体现:不重写,无意义】
二.多态的定义和使用
2.1 多态定义格式
父类类型 变量名 = new 子类类型();
变量名.方法名();
2.2 普通类多态定义的格式
public class Person {public void run(){System.out.println("run...");}}
public class Student extends Person{@Overridepublic void run() {System.out.println("学生大步跑...");}
}
public class Teacher extends Person{@Overridepublic void run() {System.out.println("老师碎步跑...");}}
public class DemoTest {public static void main(String[] args) {Person p01=new Student();p01.run();Person p02=new Teacher();p02.run(); }}
2.3 抽象类多态定义的格式
public abstract class Animal {public abstract void eat();}
public class Cat extends Animal{@Overridepublic void eat() {System.out.println("猫吃鱼...");}}
public class Dog extends Animal{@Overridepublic void eat() {System.out.println("狗吃肉...");}}
public class DemoTest {public static void main(String[] args) {Animal a1=new Cat();a1.eat();Animal a2=new Dog();a2.eat();}}
2.4 接口多态定义的格式
public interface MyInter {public void fly();}
public class Bird implements MyInter{@Overridepublic void fly() {System.out.println("鸟靠翅膀飞...");}}
public class Plane implements MyInter{@Overridepublic void fly() {System.out.println("飞机靠动力飞...");}}
public class DemoTest {public static void main(String[] args) {MyInter my01=new Bird();my01.fly();MyInter my02=new Plane();my02.fly();}}
三.多态时访问成员的特点
- 多态时成员变量的访问特点:编译看父类,运行看父类
- 多态时成员方法的访问特点:编译看父类,运行看子类
public class Fu {int num=20;public void method(){System.out.println("fu...method...");}}
public class DemoTest {public static void main(String[] args) {Fu fu=new Zi();System.out.println(fu.num);fu.method();}}
public class Zi extends Fu{int num=20;public void method(){System.out.println("zi...method...");} }
四.多态的好处与弊端
- 好处:提高了代码的扩展性。实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展性与便利。
- 弊端:多态的情况下,只能调用父类的共性内容,不能调用子类的特有内容。
public abstract class Animal {public abstract void eat();}
public class Cat extends Animal{@Overridepublic void eat() {System.out.println("猫吃鱼...");}}
public class Dog extends Animal{@Overridepublic void eat() {System.out.println("狗吃肉...");}public void lookHome(){System.out.println("狗看家...");}}
public class DemoTest {public static void main(String[] args) {Animal animal=new Cat();animal=new Dog();/* 父类类型的变量可以接收该父类的所有子类对象 *//*Dog dog=new Dog();method01(dog);Cat cat=new Cat();method02(cat);*/Animal a01=new Dog();//a01.lookHome();无法访问子类独有的方法Animal a02=new Cat(); method(a01);//实参赋值给形参:Animal a01 = new Dog();method(a02);//实参赋值给形参:Animal a02 = new Cat();
}
//优化代码:方法的形参为父类类型,就可以接收该父类的所 有子类对象 public static void method(Animal animal){animal. Eat();
}//定义方法,可以接收Dog类对象和Cat类对象,并在该方法 中调用eat方法public static void method01(Dog dog){dog. Eat();
}public static void method02(Cat cat){ cat. Eat();}
}
4.2 类型转换
- 向上转型:子类类型向父类类型向上转换的过程,这个过程是默认的。
Fu fu = new Zi();
- 向下转型:父类类型向子类类型向下转换的过程,这个过程是强制的。
Aniaml animal = new Cat();Cat c = (Cat)animal;
//向下转型c.catchMouse();
// 可以访问 子类独有的功能,解决多态的 弊端
- instanceof关键字
为了避免ClassCastException 的发生, Java 提供了 instanceof
关键字,给变量做类型的校验。
变量名 instanceof 数据类型如果变量属于该数据类型,返回true。如果变量不属于该数据类型,返回false。
public abstract class Animal {public abstract void eat();}
public class Cat extends Animal{@Overridepublic void eat() {System.out.println("猫吃鱼...");}}
public class Dog extends Animal{@Overridepublic void eat() {System.out.println("狗吃肉...");}public void lookHome(){System.out.println("狗看家...");}}
public class DemoTest {public static void main(String[] args) {Animal animal=new Dog();animal. Eat();//animal.lookHome();//编译报错 无法调用子 类特有的功能Dog dog=(Dog)animal;dog.lookHome();// Cat cat=(Cat)animal; 类型转换异常if(animal instanceof Dog){ Dog d=(Dog)animal;d.lookHome();}}}
五.多态的几种表现形式
5.1 形参多态
public abstract class Animal {public abstract void eat();}
public class Cat extends Animal{@Override public void eat() {System.out.println("猫吃鱼...");}public void catchMouse(){System.out.println("猫抓老鼠...");}}
public class Dog extends Animal{@Overridepublic void eat() {System.out.println("狗吃肉...");}public void lookHome(){System.out.println("狗看家...");}}
public class DemoTest {public static void main(String[] args) {Dog dog=new Dog();method(dog); Cat cat=new Cat();method(cat);}public static void method(Animal animal){animal. Eat();if(animal instanceof Dog){Dog dog=(Dog)animal;dog.lookHome();}if(animal instanceof Cat){Cat cat=(Cat)animal;cat.catchMouse();}}}
5.3 返回值多态
public abstract class Animal {public abstract void eat();}
public class Cat extends Animal{@Overridepublic void eat() {System.out.println("猫吃鱼...");}public void catchMouse(){System.out.println("猫抓老鼠...");} }
public class Dog extends Animal{@Overridepublic void eat() {System.out.println("狗吃肉...");}public void lookHome(){System.out.println("狗看家...");} }
public class DemoTest {public static void main(String[] args) {Cat cat=new Cat();Dog dog=new Dog();Animal a01 = method01(cat);Animal a02 = method01(dog);Animal animal = method02();}public static Animal method01(Animal animal) {//一系列操作,操作后,返回操作后的对象return animal;}public static Animal method02(){/* Dog dog = new Dog(); return dog;*/ return new Cat();}}
ok了家人们明天见