2025-10-26 07:47:45 -

多态的认识与使用技巧

多态的认识

在面向对象编程(OOP)中,多态(Polymorphism) 是三大核心特性之一(另外两个是封装和继承),其本质是 “同一行为在不同对象上表现出不同的实现”—— 简单来说,就是 “同一件事,不同对象做起来有不同的方式”。

多态的核心价值在于降低代码耦合度、提高扩展性:调用者无需关心对象的具体类型,只需调用统一的接口,就能触发对应对象的具体实现,后续新增对象时无需修改原有调用逻辑。 一、多态的核心前提 多态并非孤立存在,它需要依赖两个基础条件才能实现,缺一不可:

继承(或实现接口):存在 “父类与子类” 的层级关系(或 “接口与实现类” 的实现关系),子类继承父类的属性和方法,或实现接口定义的抽象方法。 方法重写(Override):子类对父类的 “同名、同参数列表、同返回值(或兼容返回值)” 的方法进行重新实现,覆盖父类的原有逻辑。

多态的实现条件 1.必须在继承的体系下 2.子类必须要对父类中的方法进行重写 3.通过父类的引用调用进行重写 多态的体现:咋代码运行时,当传递不同类的对象时,会调用相应类的方法。

// 1. 继承体系 - 父类

class Shape {

// 父类中的方法,将被子类重写

public void draw() {

System.out.println("绘制图形");

}

}

// 子类1

class Circle extends Shape {

// 2. 子类重写父类方法

@Override

public void draw() {

System.out.println("绘制圆形");

}

}

// 子类2

class Rectangle extends Shape {

// 2. 子类重写父类方法

@Override

public void draw() {

System.out.println("绘制矩形");

}

}

// 子类3

class Triangle extends Shape {

// 2. 子类重写父类方法

@Override

public void draw() {

System.out.println("绘制三角形");

}

}

public class PolymorphismExample {

// 3. 通过父类引用调用重写方法

public static void drawShape(Shape shape) {

shape.draw(); // 调用的是实际对象的draw()方法

}

public static void main(String[] args) {

// 多态的体现:传递不同类的对象,调用相应类的方法

drawShape(new Circle()); // 输出:绘制圆形

drawShape(new Rectangle()); // 输出:绘制矩形

drawShape(new Triangle()); // 输出:绘制三角形

}

}

重写:

重写(Override)也称为覆盖,指的是在继承关系中,子类对父类中非静态、非 private 修饰、非 final 修饰、非构造方法的实现逻辑进行重新编写。其核心特点是 “外壳不变,核心重写”—— 方法的名称、参数列表等结构保持一致,但具体实现细节由子类根据自身需求重新定义。

重写的优势在于:子类可以基于父类的方法框架,定制符合自身特性的行为,既保留了父类的接口规范,又能实现子类的个性化逻辑。 【方法重写的规则】 方法原型一致性 1.子类重写父类方法时,必须保证返回值类型、方法名、参数列表完全一致(参数的类型、顺序、个数均需相同),这是构成重写的基础。 2.返回值类型的特殊情况,被重写的方法返回值类型可以不同,但必须满足 “父子关系”(即子类方法的返回值类型是父类方法返回值类型的子类)。 3.访问权限限制:子类重写的方法,访问权限不能低于父类中被重写方法的权限。若父类方法为public,子类重写时只能是public(不能是protected或private);若父类方法为protected,子类重写时可以是protected或public。 4.不可重写的方法:父类中以下类型的方法不能被重写: static修饰的静态方法(属于类级别的方法,不依赖对象实例); private修饰的私有方法(子类无法访问父类的私有方法); final修饰的最终方法(被final标记的方法禁止子类重写); 构造方法(构造方法是创建对象的特殊方法,子类有自己的构造方法,不存在重写概念)。 5.@Override 注解 重写方法时,建议显式添加@Override注解。该注解的作用是: 告诉编译器 “此方法是重写父类的方法”,便于编译器进行合法性校验(例如方法名拼写错误、参数列表不一致等问题会直接报错); 提高代码可读性,让其他开发者明确知道这是一个重写方法。

二、多态的两种常见形式 多态在代码中主要通过 “编译时多态” 和 “运行时多态” 体现,其中运行时多态是面向对象多态的核心。

编译时多态(方法重载) 指在同一个类中,允许存在多个 “方法名相同但参数列表不同” 的方法(参数个数、类型、顺序不同均可),编译器会根据调用时传入的参数自动匹配对应的方法。

public class Calculator {

// 方法1:两个int相加

public int add(int a, int b) {

return a + b;

}

// 方法2:三个int相加(参数个数不同)

public int add(int a, int b, int c) {

return a + b + c;

}

// 方法3:两个double相加(参数类型不同)

public double add(double a, double b) {

return a + b;

}

public static void main(String[] args) {

Calculator calc = new Calculator();

System.out.println(calc.add(1, 2)); // 调用方法1,输出3

System.out.println(calc.add(1, 2, 3)); // 调用方法2,输出6

System.out.println(calc.add(1.5, 2.5)); // 调用方法3,输出4.0

}

}

关键:编译时已确定调用哪个方法,本质是 “同名方法的差异化匹配”。

运行时多态(方法重写)

这是面向对象多态的核心形式:父类引用可以指向子类对象,调用方法时,程序会根据 “对象的实际类型”(而非引用类型)执行子类重写后的方法。

// 1. 父类:定义统一接口

class Animal {

// 父类的方法(可被重写)

public void makeSound() {

System.out.println("动物发出声音");

}

}

// 2. 子类1:重写父类方法

class Dog extends Animal {

@Override

public void makeSound() {

System.out.println("小狗汪汪叫");

}

}

// 3. 子类2:重写父类方法

class Cat extends Animal {

@Override

public void makeSound() {

System.out.println("小猫喵喵叫");

}

}

public class PolymorphismDemo {

public static void main(String[] args) {

// 父类引用指向子类对象(多态的关键语法)

Animal animal1 = new Dog(); // 引用类型是Animal,实际对象是Dog

Animal animal2 = new Cat(); // 引用类型是Animal,实际对象是Cat

// 调用方法:运行时根据实际对象类型执行对应重写方法

animal1.makeSound(); // 输出“小狗汪汪叫”(执行Dog的方法)

animal2.makeSound(); // 输出“小猫喵喵叫”(执行Cat的方法)

}

}

关键:编译时无法确定调用哪个方法(animal1的引用类型是Animal,编译时只知道它有makeSound方法),运行时才根据 “实际对象是Dog还是Cat” 执行对应逻辑 —— 这就是 “晚绑定”。

向上转型

定义 向上转型指的是将子类对象的引用赋值给父类类型的变量,即 “子类对象→父类引用”。这是一种自动转换,不需要显式声明。核心特点 语法:父类类型 变量名 = new 子类类型(); 本质:父类引用指向了子类对象(引用类型变了,但实际对象还是子类) 访问限制:通过父类引用只能访问父类中定义的属性和方法,无法直接访问子类特有的属性和方法 多态基础:向上转型后,调用方法时会执行子类重写的实现(动态绑定)

class Animal {

public void eat() {

System.out.println("动物吃东西");

}

}

class Dog extends Animal {

@Override

public void eat() {

System.out.println("狗吃骨头");

}

// 子类特有方法

public void bark() {

System.out.println("狗汪汪叫");

}

}

public class CastDemo {

public static void main(String[] args) {

// 向上转型:Dog对象→Animal引用(自动转换)

Animal animal = new Dog();

// 正确:调用的是子类重写的方法(动态绑定)

animal.eat(); // 输出:狗吃骨头

// 错误:父类引用无法访问子类特有方法

// animal.bark(); // 编译报错

}

}

向下转型

定义 向下转型指的是将父类类型的引用转换为子类类型的变量,即 “父类引用→子类引用”。这是一种强制转换,必须显式声明(使用(子类类型))。核心前提 向下转型必须在向上转型的基础上进行(即父类引用原本指向的就是该子类对象),否则会抛出ClassCastException(类型转换异常)。核心特点 语法:子类类型 变量名 = (子类类型) 父类引用; 作用:将父类引用 “还原” 为子类引用,从而可以访问子类特有的属性和方法 风险:若转型的目标类型与实际对象类型不匹配,运行时会报错

public class CastDemo {

public static void main(String[] args) {

// 1. 先向上转型:Dog对象→Animal引用

Animal animal = new Dog();

// 2. 向下转型:Animal引用→Dog引用(强制转换)

Dog dog = (Dog) animal;

// 正确:可以访问子类特有方法

dog.bark(); // 输出:狗汪汪叫

// 错误示例:父类引用指向的是Dog对象,却转为Cat类型

Animal animal2 = new Dog();

// Cat cat = (Cat) animal2; // 运行时抛出ClassCastException

}

}


「手游寻仙哪里熔炼」寻仙熔炼值哪里获取
杭州到济南火车票查询