多态的体现与多种实现
Note: This article has been written with the assistance of AI.
多态的体现
多态是面向对象编程的三大特性之一,允许不同类的对象对同一消息做出响应,提高了代码的灵活性和可扩展性。
方法重载
方法重载是指同一类中可以有多个同名方法,方法签名是方法的唯一标识符,由方法名称和参数列表(参数的类型、数量和顺序)组成,重载具有不同的参数列表(参数类型、数量或顺序不同)。虽然方法名相同,但根据传入的参数不同,编译器会在编译时确定调用哪个方法(方法重载的依据是编译器通过方法签名来区分重载的方法,编译时绑定编译器根据方法签名确定调用哪个方法)。
public class Calculator {
// 整数加法
public int add(int a, int b) {
System.out.println("调用整数加法");
return a + b;
}
// 浮点数加法 - 参数类型不同
public double add(double a, double b) {
System.out.println("调用浮点数加法");
return a + b;
}
// 三个数加法 - 参数数量不同
public int add(int a, int b, int c) {
System.out.println("调用三参数加法");
return a + b + c;
}
// 参数顺序不同
public void printInfo(String name, int age) {
System.out.println("姓名: " + name + ", 年龄: " + age);
}
public void printInfo(int age, String name) {
System.out.println("年龄: " + age + ", 姓名: " + name);
}
}
// 测试类
public class OverloadingDemo {
public static void main(String[] args) {
Calculator calc = new Calculator();
// 编译器在编译时确定调用哪个方法
System.out.println(calc.add(5, 10)); // 调用整数加法
System.out.println(calc.add(5.5, 10.5)); // 调用浮点数加法
System.out.println(calc.add(1, 2, 3)); // 调用三参数加法
calc.printInfo("张三", 25); // 姓名: 张三, 年龄: 25
calc.printInfo(25, "张三"); // 年龄: 25, 姓名: 张三
}
}
方法重写
方法重写是指子类重新定义父类中已有的方法,提供特定的实现。在运行时,JVM 会根据对象的实际类型来决定调用哪个版本的方法。
// 父类
class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
// 将被重写的方法
public void makeSound() {
System.out.println("动物发出声音");
}
public void eat() {
System.out.println(name + "正在吃东西");
}
}
// 子类 Dog
class Dog extends Animal {
public Dog(String name) {
super(name);
}
// 重写父类方法
@Override
public void makeSound() {
System.out.println(name + "汪汪叫");
}
// 子类特有的方法
public void fetch() {
System.out.println(name + "在接飞盘");
}
}
// 子类 Cat
class Cat extends Animal {
public Cat(String name) {
super(name);
}
// 重写父类方法
@Override
public void makeSound() {
System.out.println(name + "喵喵叫");
}
// 重写父类方法
@Override
public void eat() {
System.out.println(name + "优雅地吃鱼");
}
}
// 测试类
public class OverridingDemo {
public static void main(String[] args) {
// 向上转型 - 父类引用指向子类对象
Animal myDog = new Dog("旺财");
Animal myCat = new Cat("咪咪");
// 运行时多态 - JVM根据实际对象类型调用相应方法
myDog.makeSound(); // 输出: 旺财汪汪叫
myCat.makeSound(); // 输出: 咪咪喵喵叫
myDog.eat(); // 输出: 旺财正在吃东西 (继承父类实现)
myCat.eat(); // 输出: 咪咪优雅地吃鱼 (子类重写实现)
// 多态在集合中的应用
Animal[] animals = {new Dog("小黑"), new Cat("小白"), new Dog("大黄")};
for (Animal animal : animals) {
animal.makeSound(); // 运行时确定调用哪个方法
}
}
}
接口与实现
接口定义了一组方法规范,不同的类可以实现同一个接口并提供不同的实现,通过接口引用可以调用不同实现类的方法,使得程序在面对不同具体实现时保持一贯的调用方式。
// 定义接口
interface Shape {
double calculateArea();
double calculatePerimeter();
void displayInfo();
}
// 圆形实现
class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
@Override
public double calculatePerimeter() {
return 2 * Math.PI * radius;
}
@Override
public void displayInfo() {
System.out.printf("圆形 - 半径: %.2f, 面积: %.2f, 周长: %.2f%n",
radius, calculateArea(), calculatePerimeter());
}
}
// 矩形实现
class Rectangle implements Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double calculateArea() {
return width * height;
}
@Override
public double calculatePerimeter() {
return 2 * (width + height);
}
@Override
public void displayInfo() {
System.out.printf("矩形 - 宽: %.2f, 高: %.2f, 面积: %.2f, 周长: %.2f%n",
width, height, calculateArea(), calculatePerimeter());
}
}
// 测试类
public class InterfacePolymorphismDemo {
public static void main(String[] args) {
// 使用接口类型引用
Shape circle = new Circle(5.0);
Shape rectangle = new Rectangle(4.0, 6.0);
// 相同的接口方法调用,不同的实现
circle.displayInfo();
rectangle.displayInfo();
// 多态在集合中的应用
Shape[] shapes = {
new Circle(3.0),
new Rectangle(2.0, 4.0),
new Circle(7.0)
};
double totalArea = 0;
for (Shape shape : shapes) {
shape.displayInfo();
totalArea += shape.calculateArea();
}
System.out.printf("所有图形的总面积: %.2f%n", totalArea);
}
}
向上转型和向下转型:
- 向上转型是自动进行的,将子类对象赋值给父类引用(父类类型的引用指向子类对象),这种方式可以在运行时期采用不同的子类实现。
// 父类
class Animal {
public void eat() {
System.out.println("动物在吃东西");
}
public void sleep() {
System.out.println("动物在睡觉");
}
}
// 子类
class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗在吃狗粮");
}
public void bark() {
System.out.println("狗在汪汪叫");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫在吃鱼");
}
public void meow() {
System.out.println("猫在喵喵叫");
}
}
public class UpcastingExample {
public static void main(String[] args) {
// 向上转型 - 自动进行
Animal animal1 = new Dog(); // Dog对象转型为Animal类型
Animal animal2 = new Cat(); // Cat对象转型为Animal类型
animal1.eat(); // 输出: 狗在吃狗粮 (多态)
animal1.sleep(); // 输出: 动物在睡觉
animal2.eat(); // 输出: 猫在吃鱼 (多态)
animal2.sleep(); // 输出: 动物在睡觉
// animal1.bark(); // 编译错误! 父类引用无法调用子类特有方法
}
}
- 向下转型需要显式进行,并且有风险,需要使用
instanceof进行检查。向下转型将父类引用转回其子类类型(执行前需要确认引用实际指向的对象类型以避免ClassCastException)。
public class DowncastingExample {
public static void main(String[] args) {
// 向上转型
Animal animal1 = new Dog();
Animal animal2 = new Cat();
// 安全的向下转型 - 使用instanceof检查
if (animal1 instanceof Dog) {
Dog dog = (Dog) animal1; // 向下转型
dog.bark(); // 现在可以调用子类特有方法
dog.eat();
}
if (animal2 instanceof Cat) {
Cat cat = (Cat) animal2; // 向下转型
cat.meow(); // 现在可以调用子类特有方法
cat.eat();
}
// 不安全的向下转型 - 会导致ClassCastException
try {
Dog wrongDog = (Dog) animal2; // animal2实际上是Cat对象
wrongDog.bark();
} catch (ClassCastException e) {
System.out.println("类型转换异常: " + e.getMessage());
}
}
}
Java 多态的多种实现方法
继承与方法重写
// 父类
class Animal {
public void makeSound() {
System.out.println("动物发出声音");
}
public void move() {
System.out.println("动物在移动");
}
}
// 子类重写方法
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("汪汪汪");
}
@Override
public void move() {
System.out.println("狗在奔跑");
}
public void fetch() {
System.out.println("狗在接飞盘");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("喵喵喵");
}
@Override
public void move() {
System.out.println("猫在悄悄走动");
}
}
class Bird extends Animal {
@Override
public void makeSound() {
System.out.println("叽叽喳喳");
}
@Override
public void move() {
System.out.println("鸟在飞翔");
}
}
public class InheritancePolymorphism {
public static void main(String[] args) {
// 多态表现:同一个方法调用,不同对象有不同行为
Animal[] animals = {
new Dog(),
new Cat(),
new Bird(),
new Dog()
};
for (Animal animal : animals) {
animal.makeSound(); // 运行时多态
animal.move(); // 运行时多态
System.out.println("---");
}
// 方法参数多态
AnimalProcessor processor = new AnimalProcessor();
processor.processAnimal(new Dog());
processor.processAnimal(new Cat());
processor.processAnimal(new Bird());
}
}
class AnimalProcessor {
// 方法参数使用父类类型,可以接受任何子类对象
public void processAnimal(Animal animal) {
System.out.println("处理动物:");
animal.makeSound();
animal.move();
System.out.println("==========");
}
}
接口实现
// 接口定义
interface Drawable {
void draw();
double getArea();
}
interface Resizable {
void resize(double factor);
}
// 类实现接口
class Circle implements Drawable, Resizable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("绘制圆形,半径: " + radius);
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
@Override
public void resize(double factor) {
this.radius *= factor;
System.out.println("圆形调整大小,新半径: " + radius);
}
}
class Rectangle implements Drawable {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println("绘制矩形,宽度: " + width + ", 高度: " + height);
}
@Override
public double getArea() {
return width * height;
}
}
class Triangle implements Drawable, Resizable {
private double base;
private double height;
public Triangle(double base, double height) {
this.base = base;
this.height = height;
}
@Override
public void draw() {
System.out.println("绘制三角形,底边: " + base + ", 高: " + height);
}
@Override
public double getArea() {
return 0.5 * base * height;
}
@Override
public void resize(double factor) {
this.base *= factor;
this.height *= factor;
System.out.println("三角形调整大小,新底边: " + base + ", 新高: " + height);
}
}
public class InterfacePolymorphism {
public static void main(String[] args) {
// 接口引用指向实现类对象
Drawable[] drawables = {
new Circle(5.0),
new Rectangle(4.0, 6.0),
new Triangle(3.0, 4.0),
new Circle(2.0)
};
System.out.println("=== 绘制所有图形 ===");
for (Drawable drawable : drawables) {
drawable.draw();
System.out.println("面积: " + drawable.getArea());
System.out.println("---");
}
// 多接口多态
Resizable[] resizables = {
new Circle(3.0),
new Triangle(2.0, 3.0)
};
System.out.println("=== 调整图形大小 ===");
for (Resizable resizable : resizables) {
resizable.resize(1.5); // 放大1.5倍
}
// 方法返回值的多态
ShapeFactory factory = new ShapeFactory();
Drawable shape1 = factory.createShape("circle");
Drawable shape2 = factory.createShape("rectangle");
shape1.draw();
shape2.draw();
}
}
class ShapeFactory {
// 工厂方法返回接口类型,实现多态
public Drawable createShape(String type) {
switch (type.toLowerCase()) {
case "circle":
return new Circle(1.0);
case "rectangle":
return new Rectangle(2.0, 3.0);
case "triangle":
return new Triangle(2.0, 2.0);
default:
return new Circle(1.0);
}
}
}
抽象类
// 抽象类
abstract class Employee {
protected String name;
protected double baseSalary;
public Employee(String name, double baseSalary) {
this.name = name;
this.baseSalary = baseSalary;
}
// 抽象方法 - 子类必须实现
public abstract double calculateSalary();
// 具体方法 - 子类可以继承或重写
public void displayInfo() {
System.out.println("员工姓名: " + name);
System.out.println("基本工资: " + baseSalary);
System.out.println("实发工资: " + calculateSalary());
}
// 模板方法模式 - 定义算法骨架
public final void processSalary() {
System.out.println("=== 处理 " + name + " 的工资 ===");
calculateBase();
calculateBonus();
calculateDeduction();
displayInfo();
System.out.println();
}
protected void calculateBase() {
System.out.println("计算基本工资: " + baseSalary);
}
protected abstract void calculateBonus();
protected abstract void calculateDeduction();
}
// 具体子类
class FullTimeEmployee extends Employee {
private double bonus;
public FullTimeEmployee(String name, double baseSalary, double bonus) {
super(name, baseSalary);
this.bonus = bonus;
}
@Override
public double calculateSalary() {
return baseSalary + bonus;
}
@Override
protected void calculateBonus() {
System.out.println("全职员工奖金: " + bonus);
}
@Override
protected void calculateDeduction() {
double deduction = baseSalary * 0.1; // 10% 扣款
System.out.println("社保扣款: " + deduction);
}
}
class PartTimeEmployee extends Employee {
private int hours;
private double hourlyRate;
public PartTimeEmployee(String name, int hours, double hourlyRate) {
super(name, 0); // 基本工资为0,按小时计算
this.hours = hours;
this.hourlyRate = hourlyRate;
}
@Override
public double calculateSalary() {
return hours * hourlyRate;
}
@Override
protected void calculateBonus() {
System.out.println("兼职员工无奖金");
}
@Override
protected void calculateDeduction() {
System.out.println("兼职员工无扣款");
}
@Override
public void displayInfo() {
System.out.println("兼职员工姓名: " + name);
System.out.println("工作小时: " + hours);
System.out.println("时薪: " + hourlyRate);
System.out.println("实发工资: " + calculateSalary());
}
}
class Manager extends Employee {
private double bonus;
private double stockOptions;
public Manager(String name, double baseSalary, double bonus, double stockOptions) {
super(name, baseSalary);
this.bonus = bonus;
this.stockOptions = stockOptions;
}
@Override
public double calculateSalary() {
return baseSalary + bonus + stockOptions;
}
@Override
protected void calculateBonus() {
System.out.println("经理奖金: " + bonus);
}
@Override
protected void calculateDeduction() {
double deduction = baseSalary * 0.15; // 15% 扣款
System.out.println("高级社保扣款: " + deduction);
}
@Override
public void displayInfo() {
System.out.println("经理姓名: " + name);
System.out.println("基本工资: " + baseSalary);
System.out.println("奖金: " + bonus);
System.out.println("股票期权: " + stockOptions);
System.out.println("实发工资: " + calculateSalary());
}
}
public class AbstractClassPolymorphism {
public static void main(String[] args) {
Employee[] employees = {
new FullTimeEmployee("张三", 8000, 2000),
new PartTimeEmployee("李四", 40, 100),
new Manager("王五", 15000, 5000, 3000),
new FullTimeEmployee("赵六", 7000, 1500)
};
System.out.println("=== 员工工资处理 ===");
for (Employee employee : employees) {
employee.processSalary(); // 模板方法,多态表现
}
// 计算总工资支出
double totalSalary = 0;
for (Employee employee : employees) {
totalSalary += employee.calculateSalary();
}
System.out.println("总工资支出: " + totalSalary);
}
}
方法重载(编译时多态)
public class OverloadingPolymorphism {
// 方法重载 - 编译时多态
public void print(int num) {
System.out.println("整数: " + num);
}
public void print(double num) {
System.out.println("浮点数: " + num);
}
public void print(String text) {
System.out.println("字符串: " + text);
}
public void print(int[] array) {
System.out.print("数组: [");
for (int i = 0; i < array.length; i++) {
System.out.print(array[i]);
if (i < array.length - 1) System.out.print(", ");
}
System.out.println("]");
}
public void print(String format, Object... args) {
System.out.printf(format, args);
}
// 构造器重载
private String name;
private int age;
public OverloadingPolymorphism() {
this("未知", 0);
}
public OverloadingPolymorphism(String name) {
this(name, 0);
}
public OverloadingPolymorphism(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
OverloadingPolymorphism poly = new OverloadingPolymorphism();
// 方法重载多态
poly.print(10);
poly.print(3.14);
poly.print("Hello");
poly.print(new int[]{1, 2, 3, 4, 5});
poly.print("姓名: %s, 年龄: %d%n", "张三", 25);
// 构造器重载
OverloadingPolymorphism obj1 = new OverloadingPolymorphism();
OverloadingPolymorphism obj2 = new OverloadingPolymorphism("李四");
OverloadingPolymorphism obj3 = new OverloadingPolymorphism("王五", 30);
}
}
多态实现方法总结
| 实现方式 | 类型 | 特点 |
|---|---|---|
| 继承与方法重写 | 运行时多态 | 基于继承关系,子类重写父类方法 |
| 接口实现 | 运行时多态 | 基于接口契约,类实现接口方法 |
| 抽象类 | 运行时多态 | 包含抽象方法和具体方法 |
| 方法重载 | 编译时多态 | 同一类中方法名相同,参数不同 |

浙公网安备 33010602011771号