- 多态的介绍:
- 同一个行为具有多个不同的表现形式或形态能力
- 多态的前提:
- 有继承/实现关系
- 有方法重写
- 有父类引用指向子类对象
- 对象多态:
- Animal a1 = new Dog();
- Animal a2 = new Cat();
- 好处:方法的形参定义为父类类型, 这个方法可以接受到该父类的任意子类对象
-
public class mAnimal{ public static void main(String[] args) { Animal a1 = new Dog(); Animal a2 = new Cat(); useAnimal(new Dog()); useAnimal(new Cat()); } public static void useAnimal(Animal a){ a.eat(); } } abstract class Animal{ public abstract void eat(); } class Dog extends Animal{ @Override public void eat(){ System.out.println("狗吃肉"); } } class Cat extends Animal{ @Override public void eat(){ System.out.println("猫吃鱼"); } }
- 行为多态
- 好处:同一个方法,具有多用不同的表现形式,或形态能力
- 多态的成员访问特点:
- 成员变量:编译看左边(父类), 运行看左边(父类)
- 成员方法: 编译看左边(父类), 运行看右边(子类)
-
public class PolymorphismTest { /* 多态的成员访问特点: 1. 成员变量 : 编译看左边(父类), 运行看左边(父类) 2. 成员方法 : 编译看左边(父类), 运行看右边(子类) 在编译的时候, 会检查父类中有没有这个方法 没有 : 编译出错 有 : 编译通过, 但是运行的时候, 一定会执行子类的方法逻辑 原因: 担心你调用的方法, 在父类中是一个抽象方法 -------------------------------------------------------------------------- 多态创建对象, 调用静态成员 : 静态的成员, 推荐类名进行调用 细节: 静态的成员, 可以使用对象名调用, 但这是一种假象 - 生成字节码文件后, 会自动将对象名调用, 改成类名调用 */ public static void main(String[] args) { Fu f = new Zi(); System.out.println(f.num); f.show(); f.print(); // Fu.print(); System.out.println("-----------------"); Inter i = new InterImpl(); i.method(); } } interface Inter { void method(); } class InterImpl implements Inter { @Override public void method() { System.out.println("method..."); } } class Fu { int num = 10; public void show() { System.out.println("Fu...show"); } public static void print(){ System.out.println("Fu...print"); } } class Zi extends Fu { int num = 20; @Override public void show() { System.out.println("Zi...show"); } public static void print(){ System.out.println("Zi...print"); } }
- 多态的好处:提高程序的扩展性
- 多态的弊端: 不能调用子类特有的成员
-
import java.util.Scanner; public class Test { /* ClassCastException : 类型转换异常 在引用数据类型的强转中, [实际类型]和[目标类型]不匹配, 就会出现此异常 */ public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入: 1. 国内订单 2. 国外订单"); OrderService orderService = null; int choice = sc.nextInt(); switch (choice) { case 1: // 创建国内订单的业务类 orderService = new OrderServiceImpl(); //向上转型 break; case 2: // 创建国外订单的业务类 orderService = new OverseasServiceImpl(); break; } // instanceof : 判断左边的引用, 是否是右边的数据类型 if(orderService instanceof OverseasServiceImpl){ OverseasServiceImpl osi = (OverseasServiceImpl) orderService; //向下转型 osi.check(); } orderService.create(); orderService.findOne(); orderService.findList(); orderService.cancel(); orderService.finish(); orderService.paid(); } }