Java中多态相关的要点和细节注意
1、Java中为什么多态使用父类型做参数,可以接收所有子类对象,但是反过来却不行呢?
这个问题涉及到Java中的多态性(polymorphism)和继承(inheritance)。为了理解为什么父类型可以接收所有子类对象,而反过来却不行,我们需要深入了解面向对象编程中的类型兼容性。
1. 多态性与继承:父类可以接收子类对象
在Java中,多态性是指一个对象可以以多种形式表现。在继承关系中,子类对象可以被赋值给父类类型的引用变量,这叫做向上转型(upcasting)。
原因:子类继承了父类的所有非私有方法和属性,因此它至少具备了父类的特性(方法和属性)。这样,父类类型的引用变量可以安全地指向任何子类对象。
这符合面向对象编程中的"里氏替换原则"(Liskov Substitution Principle,LSP),即任何能够使用父类对象的地方都应该能够使用子类对象,而不影响程序的正确性。
代码示例:
// 父类 class Animal { void sound() { System.out.println("动物发出声音"); } } // 子类 class Dog extends Animal { @Override void sound() { System.out.println("狗汪汪叫"); } } class Cat extends Animal { @Override void sound() { System.out.println("猫喵喵叫"); } } public class Main { public static void main(String[] args) { // 父类引用可以指向子类对象 Animal myDog = new Dog(); Animal myCat = new Cat(); // 调用子类的重写方法 myDog.sound(); // 输出: 狗汪汪叫 myCat.sound(); // 输出: 猫喵喵叫 } }
解释:
- 在这里,
Animal是父类,Dog和Cat是子类。 Animal myDog = new Dog();和Animal myCat = new Cat();是典型的向上转型,父类引用Animal指向子类对象Dog或Cat。- 虽然引用类型是
Animal,但由于多态性,程序会根据实际对象的类型来调用Dog或Cat的sound()方法(动态绑定)。
2. 为什么子类不能接收父类对象?
相反,子类类型不能指向父类对象,这叫做向下转型(downcasting),它并不是自动安全的。因为父类可能不具备子类的特性,所以直接赋值会导致不兼容的情况。
要安全地进行向下转型,必须使用显式的类型转换,并且需要保证父类对象确实是子类实例,否则会发生ClassCastException。
原因:子类可能有比父类更多的特性(方法和属性),如果子类引用指向一个父类对象,子类试图调用父类中不存在的方法或属性,就会导致错误。
代码示例:
class Animal { void sound() { System.out.println("动物发出声音"); } } class Dog extends Animal { void bark() { System.out.println("狗汪汪叫"); } } public class Main { public static void main(String[] args) { // 父类引用指向父类对象 Animal animal = new Animal(); // 子类引用不能直接指向父类对象 // Dog myDog = animal; // 编译错误 // 需要显式进行类型转换(向下转型) if (animal instanceof Dog) { Dog myDog = (Dog) animal; // 安全向下转型 myDog.bark(); } else { System.out.println("animal不是Dog的实例"); } } }
解释:
- 在上面的代码中,
Animal类没有bark()方法,而Dog类有。因此,不能直接将Animal类型的对象赋值给Dog类型引用。 - 如果试图直接执行
Dog myDog = animal;会导致编译错误,因为编译器无法保证animal具有Dog的特性。 - 使用
instanceof关键字可以检查对象的实际类型,在确保对象是Dog实例后,再进行显式的类型转换。
3. 总结:
- 父类可以接收子类对象(向上转型),因为子类具备父类的所有特性,程序员可以放心使用父类的所有方法和属性,而不用担心程序崩溃。
- 子类不能接收父类对象(向下转型),因为父类可能没有子类特有的方法和属性,这样赋值会导致不兼容性,需要显式地进行类型转换并进行类型检查。
- Java的多态性允许我们通过父类引用来操作子类对象,这提供了灵活性,尤其在需要处理一组不同的子类对象时,可以统一通过父类接口来处理它们。
2、关于类型强制转换,Java14新引入的特性,写法注意理解和掌握。



浙公网安备 33010602011771号