2026/3/9 16:53:02
网站建设
项目流程
wordpress建站站长之家,微商城网站开发视频,海报制作在线,内网门户网站建设方案Java 多态 (Polymorphism)多态是面向对象三大特性中最核心、最灵活的特性。它意味着 “同一行为#xff0c;多种实现”。一、多态的基本概念定义#xff1a;同一种类型的对象#xff08;或引用#xff09;#xff0c;在不同的情况下表现出不同的行为和状态。核心表现形式多种实现”。一、多态的基本概念定义同一种类型的对象或引用在不同的情况下表现出不同的行为和状态。核心表现形式向上转型java父类类型 引用名 new 子类对象();例如javaAnimal a new Dog(); // 多态 Animal b new Cat(); // 多态这里的Animal是编译时类型而Dog或Cat是运行时类型。多态的前提条件三者缺一不可有继承关系或实现关系接口。有父类或接口引用指向子类对象即向上转型。有方法的重写否则多态调用方法没有实际意义。二、多态的优势降低耦合度提高扩展性方法参数或容器如集合使用父类类型可以接受任何子类对象代码通用性更强。便于维护当需要新增一种子类时无需修改使用父类引用的代码。代码简洁统一的接口不同的实现。示例体现扩展性的优势javaclass Animal { public void eat() { System.out.println(动物吃东西); } } class Dog extends Animal { Override public void eat() { System.out.println(狗吃骨头); } } class Cat extends Animal { Override public void eat() { System.out.println(猫吃鱼); } } // 饲养员类 - 核心优势体现 class Keeper { // 参数使用父类类型可以接收任何Animal子类对象 public void feedAnimal(Animal a) { a.eat(); // 运行时执行具体子类的eat方法 } } public class Main { public static void main(String[] args) { Keeper keeper new Keeper(); Animal dog new Dog(); Animal cat new Cat(); keeper.feedAnimal(dog); // 输出狗吃骨头 keeper.feedAnimal(cat); // 输出猫吃鱼 // 未来新增一个Tiger类Keeper类完全无需修改 // keeper.feedAnimal(new Tiger()); } }三、多态调用成员的特点记忆口诀这是理解多态行为的关键成员类型编译阶段看左边运行阶段看右边说明成员变量检查父类中是否有该变量访问父类中的该变量编译和运行都看左边父类成员方法检查父类中是否有该方法声明执行子类中重写后的该方法编译看左边运行看右边子类示例javaclass Fu { int num 10; public void show() { System.out.println(Fu show); } } class Zi extends Fu { int num 20; Override public void show() { System.out.println(Zi show); } public void special() { System.out.println(Zi special); } } public class Test { public static void main(String[] args) { Fu obj new Zi(); // 多态 // 访问成员变量看左边(Fu) System.out.println(obj.num); // 输出10 // 调用成员方法编译看左边(Fu)运行看右边(Zi) obj.show(); // 输出Zi show // obj.special(); // 编译错误因为编译看左边Fu类中没有special方法声明 } }四、多态的弊端与解决方案类型转换弊端在多态的形式下父类引用不能调用子类特有的方法或访问子类特有的变量。解决方案使用引用数据类型转换。1. 向上转型 (Upcasting)自动进行子类类型转换为父类类型。Animal a new Dog();// 安全因为狗一定是动物。2. 向下转型 (Downcasting)强制进行父类类型转换为子类类型。语法子类类型 引用名 (子类类型) 父类引用;目的为了“还原”对象的真实子类类型以便调用子类特有的功能。示例javaAnimal a new Dog(); // 向上转型 Dog d (Dog) a; // 向下转型将a强制转换为Dog类型 d.lookHome(); // 现在可以调用Dog特有的方法了3. 转型的风险与安全校验如果转型的目标类型与对象的真实类型不匹配会抛出ClassCastException类型转换异常。javaAnimal a new Cat(); Dog d (Dog) a; // 运行时错误ClassCastException: Cat cannot be cast to Dog安全转型使用instanceof关键字作用在转型前进行判断避免ClassCastException。语法引用变量 instanceof 数据类型结果返回boolean值。判断引用指向的对象是否属于该类型或该类型的子类。示例javapublic static void checkAnimal(Animal a) { a.eat(); // 所有动物都有的行为 // 类型判断与安全转型 if (a instanceof Dog) { Dog dog (Dog) a; dog.lookHome(); } else if (a instanceof Cat) { Cat cat (Cat) a; cat.catchMouse(); } else { System.out.println(这是其他动物); } }五、总结与最佳实践多态的本质通过父类/接口引用调用方法执行时由JVM根据对象的实际类型决定调用哪个版本的方法动态绑定。使用场景当需要编写通用代码、处理一组相关对象、或设计可扩展的系统架构时。转型原则能向上转型就向上转型利用多态提高代码通用性。必须向下转型时才转需要使用子类特有功能时。向下转型前务必用instanceof判断确保类型安全。package polymorphism02; public class Animal { private int age; private String color; public Animal() { } public Animal(int age, String color) { this.age age; this.color color; } public int getAge() { return age; } public void setAge(int age) { this.age age; } public String getColor() { return color; } public void setColor(String color) { this.color color; } public void eat(String something){ System.out.println(动物在吃东西); } }package polymorphism02; public class Cat extends Animal{ public Cat() { } public Cat(int age, String color) { super(age, color); } Override public void eat(String something){ System.out.println(getAge()岁的getColor()颜色的猫在吃something); } public void catchMouse(){ System.out.println(猫抓老鼠); } }package polymorphism02; public class Dog extends Animal{ public Dog() { } public Dog(int age, String color) { super(age, color); } Override public void eat(String something){ System.out.println(getAge()岁的getColor()颜色的狗在吃something); } public void lookHome(){ System.out.println(狗在看家); } }package polymorphism02; public class Person { private String name; private int age; public Person() { } public Person(int age, String name) { this.age age; this.name name; } public int getAge() { return age; } public void setAge(int age) { this.age age; } public String getName() { return name; } public void setName(String name) { this.name name; } //饲养狗 /*public void keepPet(Dog dog,String something){ System.out.println(年龄为age岁的name养了一只dog.getColor()颜色的dog.getAge()岁的狗); dog.eat(something); } //饲养猫 public void keepPet(Cat cat,String something){ System.out.println(年龄为age岁的name养了一只cat.getColor()颜色的cat.getAge()岁的猫); cat.eat(something); }*/ //一个方法能接收使用动物信息 //方法的形参可以写这些类的父类 public void keepPet(Animal a ,String something){ if (a instanceof Dog d){ System.out.println(年龄为age岁的name养了一只d.getColor()颜色的d.getAge()岁的狗); d.eat(something); }else if (a instanceof Cat c){ System.out.println(年龄为age岁的name养了一只c.getColor()颜色的c.getAge()岁的猫); c.eat(something); }else { System.out.println(没有这种动物); } } }package polymorphism02; public class Test { public static void main(String[] args) { //创建对象并调用 /*Person p new Person(30, 老王); Dog d new Dog(2,黑); p.keepPet(d,骨头); Person p1 new Person(26, 老李); Cat d1 new Cat(3,黄); p1.keepPet(d1,); */ Person p new Person(30, 老王); Dog d new Dog(2,黑); Cat c new Cat(3,黄); p.keepPet(d,骨头); p.keepPet(c,); } }