Java多态,我真是看立刻很多次,记了很多次,但是还是容易忘,容易不理解,其实根本原因就是没在实际应用过,不知道具体场景,今天我也终于实际用到了,大彻大悟了。
接下来我一层层的,给大家抛开迷雾。
首先开看一段最简单的多态代码。
// 父类 Animal
class Animal {public void makeSound() {System.out.println("动物发出声音");}
}// 子类 Dog 继承自 Animal
class Dog extends Animal {@Overridepublic void makeSound() {System.out.println("狗发出汪汪的声音");}
}// 子类 Cat 继承自 Animal
class Cat extends Animal {@Overridepublic void makeSound() {System.out.println("猫发出喵喵的声音");}
}public class Main {public static void main(String[] args) {Animal dog = new Dog(); // 父类引用指向子类对象Animal cat = new Cat(); // 父类引用指向另一个子类对象dog.makeSound(); // 调用 Dog 的 makeSound 方法cat.makeSound(); // 调用 Cat 的 makeSound 方法}
}
这就是一个很简单的,父类引用指向子类对象,调用对应子类的方法,没错我以前学的都是这个,这感觉什么多不多态的,没啥用啊,这我都知道是哪个子类, 我直接用子类去定义就好了啊, 干嘛还用父类去接受子类的对象。
你是对的,没毛病,我就一直是这个疑惑所有一直没搞懂。/(ㄒoㄒ)/~~
再看一段代码。
class Animal {public void makeSound() {System.out.println("动物发出声音");}
}// 子类 Dog 继承自 Animal
class Dog extends Animal {@Overridepublic void makeSound() {System.out.println("狗发出汪汪的声音");}
}// 子类 Cat 继承自 Animal
class Cat extends Animal {@Overridepublic void makeSound() {System.out.println("猫发出喵喵的声音");}
}public class Main {public static void main(String[] args) {Animal animal;// 根据输入内容自动识别是哪个子类String input = "dog"; // 可以替换为 "dog" 或者 "cat" 测试不同情况if (input.equalsIgnoreCase("dog")) {animal = new Dog(); // animal 引用指向 Dog 对象} else if (input.equalsIgnoreCase("cat")) {animal = new Cat(); // animal 引用指向 Cat 对象} else {animal = new Animal(); // 默认情况下指向 Animal 对象}animal.makeSound(); // 根据具体指向的对象来调用相应的 makeSound 方法}
}
这里我们把这个main函数想成是 前端的调用,这样可以if判断到底是哪个子类了, 但是这就还是有问题, 我还是在写代码的时候就知道是哪个子类, 那我还用父类干哈,这不是自己给自己找事吗。
ok,接着往下看。
import java.lang.reflect.InvocationTargetException;// 父类 Animal
class Animal {public void makeSound() {System.out.println("动物发出声音");}
}// 子类 Dog 继承自 Animal
class Dog extends Animal {@Overridepublic void makeSound() {System.out.println("狗发出汪汪的声音");}
}// 子类 Cat 继承自 Animal
class Cat extends Animal {@Overridepublic void makeSound() {System.out.println("猫发出喵喵的声音");}
}// 动物工厂类
class AnimalFactory {public static Animal createAnimal(String animalType) {try {Class<?> clazz = Class.forName(animalType);return (Animal) clazz.getDeclaredConstructor().newInstance();} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {e.printStackTrace();}return null;}
}public class Main {public static void main(String[] args) {String animalType = "Cat"; // 根据输入选择要创建的子类类型Animal animal = AnimalFactory.createAnimal(animalType);if (animal != null) {animal.makeSound();}}
}
嗯,看完这个代码,是不是大彻大悟了。这个代码我们在全程一直不知道到底是哪个子类了,是哪个子类全靠我们前端传递的animalType 参数来判断。这样是不是就不是多次一举使用多态了。
我也是到了这里,才真正明白了多态的用法, 更详细分,其实这种写法叫做动态多态,其实我也觉得这才是多态最应该应用的场景,能够解放我们在开发阶段去手动判断子类的操作。