Java 继承与多态

继承和多态是面向对象编程的核心特性,使代码更加灵活和可复用。

继承(Inheritance)

什么是继承

继承是面向对象的一个重要特性,允许一个类(子类)继承另一个类(父类)的属性和方法。

// 父类(基类、超类)
public class Animal {
    protected String name;
    protected int age;
    
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public void eat() {
        System.out.println(name + " 正在吃东西");
    }
    
    public void sleep() {
        System.out.println(name + " 正在睡觉");
    }
    
    public void display() {
        System.out.println("名称:" + name + ",年龄:" + age);
    }
}
 
// 子类(派生类)继承父类
public class Dog extends Animal {
    private String breed;  // 品种
    
    // 子类构造方法必须调用父类构造方法
    public Dog(String name, int age, String breed) {
        super(name, age);  // 调用父类构造方法
        this.breed = breed;
    }
    
    // 子类可以添加自己的方法
    public void bark() {
        System.out.println(name + " 正在汪汪叫");
    }
    
    // 子类可以重写父类方法
    @Override
    public void display() {
        super.display();  // 调用父类方法
        System.out.println("品种:" + breed);
    }
}
 
// 使用继承
public class InheritanceExample {
    public static void main(String[] args) {
        Dog dog = new Dog("旺财", 3, "金毛");
        dog.eat();      // 继承自父类
        dog.sleep();    // 继承自父类
        dog.bark();     // 子类自己的方法
        dog.display();  // 重写的父类方法
    }
}

继承的特点

// 1. 单继承:Java 只支持单继承,一个类只能继承一个父类
public class Cat extends Animal {
    // Cat 只能继承 Animal,不能同时继承其他类
}
 
// 2. 多层继承:可以形成继承链
public class Mammal extends Animal {
    public void giveBirth() {
        System.out.println("哺乳");
    }
}
 
public class Dog extends Mammal {
    // Dog 继承 Mammal,Mammal 继承 Animal
    // Dog 间接继承了 Animal 的所有属性和方法
}
 
// 3. 所有类都继承自 Object 类
public class MyClass {
    // 即使没有显式继承,也隐式继承 Object
    // 可以使用 Object 的方法,如 toString()、equals() 等
}

super 关键字

public class Parent {
    protected String name = "父类";
    
    public Parent() {
        System.out.println("父类构造方法");
    }
    
    public void method() {
        System.out.println("父类方法");
    }
}
 
public class Child extends Parent {
    private String name = "子类";
    
    public Child() {
        super();  // 调用父类构造方法(必须放在第一行)
        System.out.println("子类构造方法");
    }
    
    public void method() {
        super.method();  // 调用父类方法
        System.out.println("子类方法");
    }
    
    public void display() {
        System.out.println(super.name);  // 访问父类属性
        System.out.println(this.name);    // 访问子类属性
    }
}

方法重写(Override)

public class Animal {
    public void makeSound() {
        System.out.println("动物发出声音");
    }
    
    // 可以被重写的方法
    public void move() {
        System.out.println("动物在移动");
    }
}
 
public class Dog extends Animal {
    // 重写父类方法:方法签名必须相同
    @Override
    public void makeSound() {
        System.out.println("汪汪叫");
    }
    
    @Override
    public void move() {
        System.out.println("狗在跑");
    }
}
 
public class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("喵喵叫");
    }
    
    @Override
    public void move() {
        System.out.println("猫在走");
    }
}

重写规则

public class OverrideRules {
    // 1. 方法名和参数列表必须相同
    // 2. 返回类型必须相同或是子类(协变返回类型)
    // 3. 访问权限不能比父类更严格
    // 4. 不能重写 private、final、static 方法
}
 
class Parent {
    protected Object getObject() {
        return new Object();
    }
}
 
class Child extends Parent {
    // 协变返回类型:返回类型可以是子类
    @Override
    protected String getObject() {
        return "字符串";
    }
}

多态(Polymorphism)

什么是多态

多态是指同一个方法在不同对象上有不同的实现。

public class PolymorphismExample {
    public static void main(String[] args) {
        // 多态:父类引用指向子类对象
        Animal animal1 = new Dog("旺财", 3, "金毛");
        Animal animal2 = new Cat("咪咪", 2);
        
        // 调用重写的方法:实际执行的是子类的方法
        animal1.makeSound();  // 输出:汪汪叫
        animal2.makeSound();  // 输出:喵喵叫
        
        // 多态的优势:可以用统一的方式处理不同的对象
        Animal[] animals = {animal1, animal2};
        for (Animal animal : animals) {
            animal.makeSound();  // 每个对象调用自己的实现
        }
    }
}

向上转型和向下转型

public class TypeCasting {
    public static void main(String[] args) {
        // 向上转型:子类对象转为父类引用(自动转换)
        Animal animal = new Dog("旺财", 3, "金毛");
        // 可以调用父类的方法
        animal.eat();
        animal.sleep();
        // 不能直接调用子类特有的方法
        // animal.bark();  // 编译错误
        
        // 向下转型:父类引用转为子类引用(需要强制转换)
        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;  // 强制转换
            dog.bark();  // 现在可以调用子类方法
        }
        
        // 错误的向下转型会导致 ClassCastException
        Animal cat = new Cat("咪咪", 2);
        // Dog dog2 = (Dog) cat;  // 运行时错误:ClassCastException
    }
}

instanceof 运算符

public class InstanceofExample {
    public static void main(String[] args) {
        Animal animal = new Dog("旺财", 3, "金毛");
        
        // instanceof 用于检查对象是否是某个类的实例
        System.out.println(animal instanceof Animal);  // true
        System.out.println(animal instanceof Dog);    // true
        System.out.println(animal instanceof Cat);   // false
        
        // 安全的向下转型
        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;
            dog.bark();
        }
    }
}

实际应用示例

示例1:图形类层次结构

// 抽象图形类
public abstract class Shape {
    protected String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    // 抽象方法:子类必须实现
    public abstract double getArea();
    public abstract double getPerimeter();
    
    public void display() {
        System.out.println("颜色:" + color);
        System.out.println("面积:" + getArea());
        System.out.println("周长:" + getPerimeter());
    }
}
 
// 圆形
public class Circle extends Shape {
    private double radius;
    
    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
    
    @Override
    public double getPerimeter() {
        return 2 * Math.PI * radius;
    }
}
 
// 矩形
public class Rectangle extends Shape {
    private double width;
    private double height;
    
    public Rectangle(String color, double width, double height) {
        super(color);
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double getArea() {
        return width * height;
    }
    
    @Override
    public double getPerimeter() {
        return 2 * (width + height);
    }
}
 
// 使用多态
public class ShapeTest {
    public static void main(String[] args) {
        Shape[] shapes = {
            new Circle("红色", 5.0),
            new Rectangle("蓝色", 4.0, 6.0)
        };
        
        for (Shape shape : shapes) {
            shape.display();  // 多态:每个图形调用自己的实现
        }
    }
}

示例2:员工管理系统

public class Employee {
    protected String name;
    protected double salary;
    
    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }
    
    public double calculateSalary() {
        return salary;
    }
    
    public void display() {
        System.out.println("姓名:" + name);
        System.out.println("基本工资:" + salary);
    }
}
 
public class Manager extends Employee {
    private double bonus;
    
    public Manager(String name, double salary, double bonus) {
        super(name, salary);
        this.bonus = bonus;
    }
    
    @Override
    public double calculateSalary() {
        return salary + bonus;  // 经理工资 = 基本工资 + 奖金
    }
    
    @Override
    public void display() {
        super.display();
        System.out.println("奖金:" + bonus);
        System.out.println("总工资:" + calculateSalary());
    }
}
 
public class Developer extends Employee {
    private int overtimeHours;
    private double hourlyRate;
    
    public Developer(String name, double salary, int overtimeHours, double hourlyRate) {
        super(name, salary);
        this.overtimeHours = overtimeHours;
        this.hourlyRate = hourlyRate;
    }
    
    @Override
    public double calculateSalary() {
        return salary + (overtimeHours * hourlyRate);  // 开发员工资 = 基本工资 + 加班费
    }
    
    @Override
    public void display() {
        super.display();
        System.out.println("加班小时:" + overtimeHours);
        System.out.println("总工资:" + calculateSalary());
    }
}

总结

继承和多态是面向对象编程的核心:

  • 继承:子类继承父类的属性和方法,实现代码复用
  • 方法重写:子类可以重写父类方法,实现不同的行为
  • 多态:同一方法在不同对象上有不同实现
  • 向上转型:子类对象转为父类引用(自动)
  • 向下转型:父类引用转为子类引用(需要强制转换和检查)

掌握继承和多态可以编写更加灵活和可扩展的代码。


相关链接


java 面向对象 继承 多态 方法重写