面向对象编程(OOP)

封装、继承和多态:Java 的三大面向对象编程(OOP)特性

Java 是一种面向对象编程语言(区别于面向对象or面向过程),面向对象编程(OOP)通过将数据和方法封装在对象中,旨在提高程序的可维护性、可扩展性和复用性。OOP 主要包括以下三大核心特性:封装继承多态

一、封装(Encapsulation)

1.1 封装的核心概念

/**
 * 封装:将数据和操作数据的方法绑定在一起,隐藏内部实现细节
 * 核心原则:高内聚、低耦合
 */
public class BankAccount {

    // ========== 1. 数据隐藏(私有字段) ==========
    private String accountNumber;
    private String ownerName;
    private double balance;
    private List<Transaction> transactions;

    // ========== 2. 构造器(初始化对象) ==========
    public BankAccount(String accountNumber, String ownerName) {
        this.accountNumber = accountNumber;
        this.ownerName = ownerName;
        this.balance = 0.0;
        this.transactions = new ArrayList<>();
    }

    // ========== 3. 公共接口(受控访问) ==========

    // Getter:只读访问
    public String getAccountNumber() {
        return accountNumber;
    }

    public String getOwnerName() {
        return ownerName;
    }

    // 只提供余额查询,不提供直接修改
    public double getBalance() {
        return balance;
    }

    // Setter:带验证的写入
    public void setOwnerName(String ownerName) {
        if (ownerName == null || ownerName.trim().isEmpty()) {
            throw new IllegalArgumentException("Owner name cannot be empty");
        }
        this.ownerName = ownerName;
    }

    // ========== 4. 业务方法(封装业务逻辑) ==========

    /**
     * 存款
     * ✅ 优点:
     * - 参数验证
     * - 业务规则集中管理
     * - 记录交易历史
     */
    public void deposit(double amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Deposit amount must be positive");
        }

        balance += amount;
        transactions.add(new Transaction("DEPOSIT", amount, balance));
        logTransaction("Deposited: " + amount);
    }

    /**
     * 取款
     * ✅ 封装了复杂的业务逻辑
     */
    public boolean withdraw(double amount) {
        // 验证 1:金额有效性
        if (amount <= 0) {
            throw new IllegalArgumentException("Withdrawal amount must be positive");
        }

        // 验证 2:余额充足性
        if (amount > balance) {
            System.out.println("Insufficient balance");
            return false;
        }

        // 验证 3:单次取款限额
        if (amount > 10000) {
            System.out.println("Single withdrawal limit exceeded");
            return false;
        }

        balance -= amount;
        transactions.add(new Transaction("WITHDRAW", amount, balance));
        logTransaction("Withdrew: " + amount);
        return true;
    }

    /**
     * 转账
     * ✅ 封装了跨账户操作的复杂性
     */
    public boolean transfer(BankAccount target, double amount) {
        if (target == null) {
            throw new IllegalArgumentException("Target account cannot be null");
        }

        if (this.withdraw(amount)) {
            target.deposit(amount);
            logTransaction("Transferred " + amount + " to " + target.getAccountNumber());
            return true;
        }
        return false;
    }

    // ========== 5. 内部辅助方法(私有) ==========
    private void logTransaction(String message) {
        System.out.println("[" + LocalDateTime.now() + "] " + message);
    }

    // ========== 6. 不可变视图(防御性拷贝) ==========
    public List<Transaction> getTransactions() {
        // ❌ 错误:直接返回内部集合
        // return transactions;

        // ✅ 正确:返回不可变副本
        return Collections.unmodifiableList(new ArrayList<>(transactions));
    }

    /**
     * 交易记录(不可变类)
     */
    public static class Transaction {
        private final String type;
        private final double amount;
        private final double balanceAfter;
        private final LocalDateTime timestamp;

        public Transaction(String type, double amount, double balanceAfter) {
            this.type = type;
            this.amount = amount;
            this.balanceAfter = balanceAfter;
            this.timestamp = LocalDateTime.now();
        }

        // 只提供 getter,无 setter(不可变)
        public String getType() { return type; }
        public double getAmount() { return amount; }
        public double getBalanceAfter() { return balanceAfter; }
        public LocalDateTime getTimestamp() { return timestamp; }
    }
}

1.2 访问控制修饰符

/**
 * Java 四种访问级别
 */
public class AccessControlDemo {

    // ========== 1. private(类内部) ==========
    private String privateField = "private";

    private void privateMethod() {
        System.out.println("Only accessible within this class");
    }

    // ========== 2. default(包级别) ==========
    String defaultField = "default";  // 无修饰符

    void defaultMethod() {
        System.out.println("Accessible within the same package");
    }

    // ========== 3. protected(包 + 子类) ==========
    protected String protectedField = "protected";

    protected void protectedMethod() {
        System.out.println("Accessible within package and subclasses");
    }

    // ========== 4. public(所有地方) ==========
    public String publicField = "public";

    public void publicMethod() {
        System.out.println("Accessible everywhere");
    }

    /**
     * 访问级别表格:
     *
     * ┌──────────┬────────┬──────┬────────┬──────────┐
     * │ 修饰符   │ 同类   │ 同包 │ 子类   │ 其他包   │
     * ├──────────┼────────┼──────┼────────┼──────────┤
     * │ private  │   ✅   │  ❌  │  ❌   │   ❌     │
     * │ default  │   ✅   │  ✅  │  ❌   │   ❌     │
     * │protected │   ✅   │  ✅  │  ✅   │   ❌     │
     * │ public   │   ✅   │  ✅  │  ✅   │   ✅     │
     * └──────────┴────────┴──────┴────────┴──────────┘
     */
}

// ========== 同包类测试 ==========
class SamePackageTest {
    public void test() {
        AccessControlDemo demo = new AccessControlDemo();

        // demo.privateField;    // ❌ 编译错误
        // demo.privateMethod(); // ❌ 编译错误

        String s1 = demo.defaultField;     // ✅
        demo.defaultMethod();              // ✅

        String s2 = demo.protectedField;   // ✅
        demo.protectedMethod();            // ✅

        String s3 = demo.publicField;      // ✅
        demo.publicMethod();               // ✅
    }
}

// ========== 不同包子类测试 ==========
package com.other;

class SubclassTest extends AccessControlDemo {
    public void test() {
        // privateField;    // ❌ 编译错误
        // defaultField;    // ❌ 编译错误(不同包)

        String s1 = protectedField;  // ✅
        protectedMethod();           // ✅

        String s2 = publicField;     // ✅
        publicMethod();              // ✅
    }
}

1.3 封装的最佳实践

/**
 * 封装的设计原则
 */
public class EncapsulationBestPractices {

    // ========== 1. 最小化可变性 ==========

    // ❌ 错误:可变字段
    public List<String> items = new ArrayList<>();

    // ✅ 正确:不可变字段
    private final List<String> items2 = new ArrayList<>();

    public List<String> getItems() {
        return Collections.unmodifiableList(items2);
    }

    public void addItem(String item) {
        items2.add(item);
    }

    // ========== 2. 防御性拷贝 ==========

    private Date birthDate;

    // ❌ 错误:返回内部可变对象的引用
    public Date getBirthDate() {
        return birthDate;
    }

    // ✅ 正确:返回副本
    public Date getBirthDateSafe() {
        return birthDate == null ? null : new Date(birthDate.getTime());
    }

    // ✅ 更好:使用不可变类型
    private final LocalDate birthDate2 = LocalDate.now();

    public LocalDate getBirthDate2() {
        return birthDate2;  // LocalDate 不可变,安全返回
    }

    // ========== 3. JavaBeans 规范 ==========

    private String name;

    // 标准 getter/setter 命名
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // boolean 类型特殊命名
    private boolean active;

    public boolean isActive() {  // 使用 is 前缀
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    // ========== 4. Lombok 简化(可选) ==========

    /**
     * 使用 Lombok 注解自动生成代码
     */
    @Data  // 生成 getter/setter/toString/equals/hashCode
    @Builder  // 生成建造者模式
    @AllArgsConstructor
    @NoArgsConstructor
    public static class User {
        private Long id;
        private String username;
        private String email;

        @Setter(AccessLevel.NONE)  // 不生成 setter
        private LocalDateTime createdAt;
    }

    // 使用示例
    User user = User.builder()
            .id(1L)
            .username("admin")
            .email("admin@example.com")
            .build();
}

二、继承(Inheritance)

2.1 继承的基础

/**
 * 继承:子类继承父类的属性和方法
 * 关键词:extends
 */

// ========== 父类(基类、超类) ==========
public class Animal {

    // 父类字段
    protected String name;
    protected int age;
    private String species;  // private 字段子类不可直接访问

    // 父类构造器
    public Animal(String name, int age, String species) {
        this.name = name;
        this.age = age;
        this.species = species;
    }

    // 父类方法
    public void eat() {
        System.out.println(name + " is eating");
    }

    public void sleep() {
        System.out.println(name + " is sleeping");
    }

    // final 方法:子类不能重写
    public final void breathe() {
        System.out.println(name + " is breathing");
    }

    // protected 方法:子类可访问
    protected void makeSound() {
        System.out.println("Some generic sound");
    }

    // Getter
    public String getSpecies() {
        return species;
    }
}

// ========== 子类(派生类) ==========
public class Dog extends Animal {

    // 子类独有字段
    private String breed;

    // 子类构造器:必须调用父类构造器
    public Dog(String name, int age, String breed) {
        super(name, age, "Canine");  // ✅ super() 调用父类构造器
        this.breed = breed;
    }

    // ========== 方法重写(Override) ==========

    /**
     * @Override 注解:
     * - 编译期检查是否正确重写
     * - 提高代码可读性
     */
    @Override
    public void eat() {
        System.out.println(name + " is eating dog food");
    }

    @Override
    protected void makeSound() {
        System.out.println(name + " barks: Woof! Woof!");
    }

    // ❌ 编译错误:不能重写 final 方法
    // @Override
    // public void breathe() {}

    // ========== 子类独有方法 ==========
    public void fetch() {
        System.out.println(name + " is fetching the ball");
    }

    public void wagTail() {
        System.out.println(name + " is wagging tail");
    }

    // ========== 访问父类成员 ==========
    public void showInfo() {
        // 访问 protected 字段
        System.out.println("Name: " + name);      // ✅
        System.out.println("Age: " + age);        // ✅

        // 访问 private 字段:需要通过 getter
        System.out.println("Species: " + getSpecies());  // ✅

        // 调用父类方法
        super.eat();  // 显式调用父类版本
        this.eat();   // 调用子类重写版本
    }
}

// ========== 使用示例 ==========
public class InheritanceDemo {
    public static void main(String[] args) {
        Dog dog = new Dog("Buddy", 3, "Golden Retriever");

        // 调用继承的方法
        dog.sleep();      // 来自 Animal
        dog.breathe();    // 来自 Animal(final)

        // 调用重写的方法
        dog.eat();        // 来自 Dog(重写)
        dog.makeSound();  // 来自 Dog(重写)

        // 调用子类独有方法
		dog.fetch();      // 来自 Dog
		dog.wagTail();    // 来自 Dog

		dog.showInfo();
	}
}

2.2 super 关键字详解

/**
 * super 关键字的三种用法
 */
public class SuperKeywordDemo {

    // ========== 父类 ==========
    static class Parent {
        protected String name = "Parent";

        public Parent() {
            System.out.println("Parent constructor");
        }

        public Parent(String name) {
            this.name = name;
            System.out.println("Parent constructor with name: " + name);
        }

        public void display() {
            System.out.println("Parent display");
        }

        public void print() {
            System.out.println("Parent print");
        }
    }

    // ========== 子类 ==========
    static class Child extends Parent {
        private String name = "Child";

        public Child() {
            // super() 必须是构造器的第一条语句
            super("ParentName");  // ✅ 用法 1:调用父类构造器
            System.out.println("Child constructor");
        }

        @Override
        public void display() {
            // ✅ 用法 2:访问父类字段
            System.out.println("Parent name: " + super.name);
            System.out.println("Child name: " + this.name);
        }

        @Override
        public void print() {
            // ✅ 用法 3:调用父类方法
            super.print();  // 调用父类版本
            System.out.println("Child print");
        }

        public void showAll() {
            super.display();  // 调用父类 display()
            this.display();   // 调用子类 display()
        }
    }

    public static void main(String[] args) {
        Child child = new Child();
        /**
         * 输出:
         * Parent constructor with name: ParentName
         * Child constructor
         */

        child.display();
        /**
         * 输出:
         * Parent name: Parent
         * Child name: Child
         */

        child.print();
        /**
         * 输出:
         * Parent print
         * Child print
         */
    }

    /**
     * super vs this:
     *
     * super:
     * - 访问父类成员
     * - 调用父类构造器
     * - 必须是构造器第一条语句
     *
     * this:
     * - 访问当前类成员
     * - 调用当前类其他构造器
     * - 必须是构造器第一条语句
     *
     * ⚠️ super() 和 this() 不能同时出现!
     */
}

2.3 构造器链

/**
 * 构造器链:子类构造器自动调用父类构造器
 */
public class ConstructorChainDemo {

    // ========== 三层继承关系 ==========

    static class GrandParent {
        public GrandParent() {
            System.out.println("1. GrandParent()");
        }
    }

    static class Parent extends GrandParent {
        public Parent() {
            super();  // 隐式调用(可省略)
            System.out.println("2. Parent()");
        }
    }

    static class Child extends Parent {
        public Child() {
            super();  // 隐式调用(可省略)
            System.out.println("3. Child()");
        }
    }

    public static void main(String[] args) {
        new Child();
        /**
         * 输出:
         * 1. GrandParent()
         * 2. Parent()
         * 3. Child()
         *
         * 执行顺序:从顶层到底层
         */
    }

    // ========== 构造器重载 + 链式调用 ==========

    static class Person {
        private String name;
        private int age;
        private String address;

        // 主构造器
        public Person(String name, int age, String address) {
            this.name = name;
            this.age = age;
            this.address = address;
            System.out.println("Full constructor");
        }

        // 委托构造器
        public Person(String name, int age) {
            this(name, age, "Unknown");  // 调用主构造器
            System.out.println("Two-arg constructor");
        }

        public Person(String name) {
            this(name, 0);  // 调用两参数构造器
            System.out.println("One-arg constructor");
        }

        public Person() {
            this("Unknown");  // 调用单参数构造器
            System.out.println("No-arg constructor");
        }
    }

    static class Employee extends Person {
        private String company;

        public Employee(String name, int age, String address, String company) {
            super(name, age, address);  // 必须先调用父类构造器
            this.company = company;
            System.out.println("Employee constructor");
        }
    }

    public static void test() {
        new Employee("Alice", 30, "NYC", "Google");
        /**
         * 输出:
         * Full constructor
         * Employee constructor
         */
    }

    /**
     * 构造器调用规则:
     *
     * 1️⃣ 如果子类构造器没有显式调用 super(),编译器自动插入 super()
     * 2️⃣ 如果父类没有无参构造器,子类必须显式调用父类有参构造器
     * 3️⃣ super() 或 this() 必须是构造器的第一条语句
     * 4️⃣ super() 和 this() 不能同时出现
     */
}

2.4 继承与初始化顺序

/**
 * 完整的初始化顺序
 */
public class InitializationOrderDemo {

    static class Parent {
        // 1. 父类静态字段
        private static String staticField = initStaticField();

        // 2. 父类静态块
        static {
            System.out.println("2. Parent static block");
        }

        // 3. 父类实例字段
        private String instanceField = initInstanceField();

        // 4. 父类实例块
        {
            System.out.println("4. Parent instance block");
        }

        // 5. 父类构造器
        public Parent() {
            System.out.println("5. Parent constructor");
        }

        private static String initStaticField() {
            System.out.println("1. Parent static field");
            return "parent static";
        }

        private String initInstanceField() {
            System.out.println("3. Parent instance field");
            return "parent instance";
        }
    }

    static class Child extends Parent {
        // 6. 子类静态字段
        private static String staticField = initStaticField();

        // 7. 子类静态块
        static {
            System.out.println("7. Child static block");
        }

        // 8. 子类实例字段
        private String instanceField = initInstanceField();

        // 9. 子类实例块
        {
            System.out.println("9. Child instance block");
        }

        // 10. 子类构造器
        public Child() {
            super();
            System.out.println("10. Child constructor");
        }

        private static String initStaticField() {
            System.out.println("6. Child static field");
            return "child static";
        }

        private String initInstanceField() {
            System.out.println("8. Child instance field");
            return "child instance";
        }
    }

    public static void main(String[] args) {
        System.out.println("=== First instantiation ===");
        new Child();

        System.out.println("\n=== Second instantiation ===");
        new Child();

        /**
         * 输出:
         * === First instantiation ===
         * 1. Parent static field
         * 2. Parent static block
         * 6. Child static field
         * 7. Child static block
         * 3. Parent instance field
         * 4. Parent instance block
         * 5. Parent constructor
         * 8. Child instance field
         * 9. Child instance block
         * 10. Child constructor
         *
         * === Second instantiation ===
         * 3. Parent instance field
         * 4. Parent instance block
         * 5. Parent constructor
         * 8. Child instance field
         * 9. Child instance block
         * 10. Child constructor
         *
         * ⚠️ 静态内容只初始化一次!
         */
    }

    /**
     * 初始化顺序总结:
     *
     * 1️⃣ 父类静态成员(字段 + 块)
     * 2️⃣ 子类静态成员(字段 + 块)
     * 3️⃣ 父类实例成员(字段 + 块)
     * 4️⃣ 父类构造器
     * 5️⃣ 子类实例成员(字段 + 块)
     * 6️⃣ 子类构造器
     */
}

2.5 方法重写(Override)详解

/**
 * 方法重写的规则和最佳实践
 */
public class OverrideDemo {

    static class Parent {
        // 返回类型:Object
        public Object getValue() {
            return "Parent";
        }

        // 访问修饰符:protected
        protected void display() {
            System.out.println("Parent display");
        }

        // 抛出异常:IOException
        public void process() throws IOException {
            System.out.println("Parent process");
        }

        // final 方法:不能重写
        public final void finalMethod() {
            System.out.println("Final method");
        }

        // static 方法:不能重写(可以隐藏)
        public static void staticMethod() {
            System.out.println("Parent static");
        }
    }

    static class Child extends Parent {

        // ========== 规则 1:协变返回类型 ==========
        @Override
        public String getValue() {  // String 是 Object 的子类 ✅
            return "Child";
        }

        // ========== 规则 2:访问权限不能更严格 ==========
        @Override
        public void display() {  // protected -> public ✅
            System.out.println("Child display");
        }

        // ❌ 编译错误:不能从 protected 降为 private
        // @Override
        // private void display() {}

        // ========== 规则 3:异常限制 ==========
        @Override
        public void process() throws FileNotFoundException {  // IOException 的子类 ✅
            System.out.println("Child process");
        }

        // ❌ 编译错误:不能抛出更宽泛的异常
        // @Override
        // public void process() throws Exception {}

        // ========== 规则 4:不能重写 final 方法 ==========
        // ❌ 编译错误
        // @Override
        // public void finalMethod() {}

        // ========== 规则 5:static 方法不是重写,是隐藏 ==========
        public static void staticMethod() {  // 不是 @Override
            System.out.println("Child static");
        }
    }

    public static void main(String[] args) {
        // ========== 多态调用 ==========
        Parent p = new Child();

        Object obj = p.getValue();  // 运行时调用 Child.getValue()
        System.out.println(obj);    // 输出:Child

        p.display();                // 运行时调用 Child.display()

        // ========== 静态方法调用(编译时绑定) ==========
        p.staticMethod();           // 输出:Parent static(不是多态!)
        Child.staticMethod();       // 输出:Child static

        /**
         * 重写 vs 隐藏:
         *
         * 重写(Override):
         * - 实例方法
         * - 运行时多态(动态绑定)
         * - 使用 @Override 注解
         *
         * 隐藏(Hiding):
         * - 静态方法、静态字段
         * - 编译时绑定
         * - 无 @Override 注解
         */
    }
}

三、多态(Polymorphism)

3.1 多态的基本概念

/**
 * 多态:同一个引用类型,指向不同的对象时,调用同一个方法表现出不同的行为
 *
 * 多态的三个必要条件:
 * 1️⃣ 继承(或实现接口)
 * 2️⃣ 重写(子类重写父类方法)
 * 3️⃣ 向上转型(父类引用指向子类对象)
 */
public class PolymorphismBasics {

    // ========== 父类 ==========
    static class Animal {
        public void makeSound() {
            System.out.println("Some generic sound");
        }

        public void eat() {
            System.out.println("Animal is eating");
        }
    }

    // ========== 子类 1 ==========
    static class Dog extends Animal {
        @Override
        public void makeSound() {
            System.out.println("Woof! Woof!");
        }

        @Override
        public void eat() {
            System.out.println("Dog is eating bones");
        }

        // 子类独有方法
        public void fetch() {
            System.out.println("Dog is fetching");
        }
    }

    // ========== 子类 2 ==========
    static class Cat extends Animal {
        @Override
        public void makeSound() {
            System.out.println("Meow! Meow!");
        }

        @Override
        public void eat() {
            System.out.println("Cat is eating fish");
        }

        // 子类独有方法
        public void climb() {
            System.out.println("Cat is climbing");
        }
    }

    // ========== 子类 3 ==========
    static class Bird extends Animal {
        @Override
        public void makeSound() {
            System.out.println("Chirp! Chirp!");
        }

        @Override
        public void eat() {
            System.out.println("Bird is eating seeds");
		}

		// 子类独有方法
		public void fly() {
			System.out.println("Bird is flying");
		}
	}

	// ========== 多态演示 ==========
	public static void main(String[] args) {

		// ========== 1. 向上转型(Upcasting) ==========
		Animal animal1 = new Dog();     // ✅ 自动转型
		Animal animal2 = new Cat();     // ✅ 自动转型
		Animal animal3 = new Bird();    // ✅ 自动转型

		// 多态调用:运行时根据实际对象类型调用对应方法
		animal1.makeSound();  // 输出:Woof! Woof!
		animal2.makeSound();  // 输出:Meow! Meow!
		animal3.makeSound();  // 输出:Chirp! Chirp!

		animal1.eat();        // 输出:Dog is eating bones
		animal2.eat();        // 输出:Cat is eating fish
		animal3.eat();        // 输出:Bird is eating seeds

		// ❌ 不能调用子类独有方法
		// animal1.fetch();   // 编译错误
		// animal2.climb();   // 编译错误
		// animal3.fly();     // 编译错误

		// ========== 2. 向下转型(Downcasting) ==========

		// ✅ 正确的向下转型
		if (animal1 instanceof Dog) {
			Dog dog = (Dog) animal1;
			dog.fetch();  // 现在可以调用子类方法
		}

		// ❌ 错误的向下转型:运行时异常
		try {
			Dog dog = (Dog) animal2;  // animal2 实际是 Cat
			dog.fetch();
		} catch (ClassCastException e) {
			System.out.println("ClassCastException: Cannot cast Cat to Dog");
		}

		// ========== 3. 数组多态 ==========
		Animal[] animals = {
			new Dog(),
			new Cat(),
			new Bird(),
			new Dog(),
			new Cat()
		};

		// 统一处理不同类型的对象
		for (Animal animal : animals) {
			animal.makeSound();  // 多态调用
			animal.eat();
			System.out.println("---");
		}

		// ========== 4. 集合多态 ==========
		List<Animal> animalList = new ArrayList<>();
		animalList.add(new Dog());
		animalList.add(new Cat());
		animalList.add(new Bird());

		for (Animal animal : animalList) {
			animal.makeSound();
		}

		// ========== 5. 方法参数多态 ==========
		feedAnimal(new Dog());
		feedAnimal(new Cat());
		feedAnimal(new Bird());
	}

	/**
	方法参数多态:接受父类类型参数,可以传入任意子类对象
	*/
	public static void feedAnimal(Animal animal) {
		 System.out.println("Feeding the animal...");
		 animal.eat(); // 多态调用
	}
}

3.2 编译时多态(方法重载)

/**
 * 编译时多态(静态多态):方法重载(Overloading)
 * 特点:编译期确定调用哪个方法
 */
public class CompileTimePolymorphism {

    // ========== 方法重载的四种方式 ==========

    // 1️⃣ 参数个数不同
    public void print(String message) {
        System.out.println("String: " + message);
    }

    public void print(String message, int count) {
        for (int i = 0; i < count; i++) {
            System.out.println(message);
        }
    }

    // 2️⃣ 参数类型不同
    public void display(int value) {
        System.out.println("int: " + value);
    }

    public void display(double value) {
        System.out.println("double: " + value);
    }

    public void display(String value) {
        System.out.println("String: " + value);
    }

    // 3️⃣ 参数顺序不同
    public void process(String name, int age) {
        System.out.println(name + " is " + age + " years old");
    }

    public void process(int age, String name) {
        System.out.println(name + " is " + age + " years old");
    }

    // 4️⃣ 可变参数重载
    public void sum(int... numbers) {
        int total = 0;
        for (int num : numbers) {
            total += num;
        }
        System.out.println("Sum: " + total);
    }

    public void sum(int a, int b) {
        System.out.println("Sum of two: " + (a + b));
    }

    // ========== 重载解析优先级 ==========
    public static void main(String[] args) {
        CompileTimePolymorphism demo = new CompileTimePolymorphism();

        // 测试 1:精确匹配
        demo.display(10);      // 调用 display(int)
        demo.display(10.5);    // 调用 display(double)
        demo.display("Hello"); // 调用 display(String)

        // 测试 2:自动类型提升
        byte b = 5;
        demo.display(b);       // byte -> int,调用 display(int)

        short s = 10;
        demo.display(s);       // short -> int,调用 display(int)

        float f = 3.14f;
        demo.display(f);       // float -> double,调用 display(double)

        // 测试 3:装箱
        Integer integer = 100;
        demo.display(integer); // Integer -> int(自动拆箱),调用 display(int)

        // 测试 4:可变参数
        demo.sum(1, 2);        // 优先调用 sum(int, int)
        demo.sum(1, 2, 3);     // 调用 sum(int...)
        demo.sum();            // 调用 sum(int...)
    }

    /**
     * 重载解析优先级(从高到低):
     *
     * 1️⃣ 精确匹配
     * 2️⃣ 自动类型提升(byte->short->int->long->float->double)
     * 3️⃣ 自动装箱/拆箱
     * 4️⃣ 可变参数
     */

    // ========== 不能重载的情况 ==========

    // ❌ 返回类型不同不构成重载
    // public int getValue() { return 1; }
    // public double getValue() { return 1.0; }  // 编译错误

    // ❌ 仅访问修饰符不同不构成重载
    // public void method() {}
    // private void method() {}  // 编译错误

    // ❌ 仅抛出异常不同不构成重载
    // public void doSomething() {}
    // public void doSomething() throws Exception {}  // 编译错误
}

3.3 运行时多态(方法重写)

/**
 * 运行时多态(动态多态):方法重写(Overriding)
 * 特点:运行时根据实际对象类型确定调用哪个方法
 */
public class RuntimePolymorphism {

    // ========== 父类 ==========
    static class Shape {
        protected String color;

        public Shape(String color) {
            this.color = color;
        }

        // 可重写方法
        public double getArea() {
            return 0;
        }

        public void draw() {
            System.out.println("Drawing a shape");
        }

        public void displayInfo() {
            System.out.println("Color: " + color + ", Area: " + getArea());
        }
    }

    // ========== 子类 1:Circle ==========
    static 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 void draw() {
            System.out.println("Drawing a circle with radius " + radius);
        }
    }

    // ========== 子类 2:Rectangle ==========
    static 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 void draw() {
            System.out.println("Drawing a rectangle " + width + "x" + height);
        }
    }

    // ========== 子类 3:Triangle ==========
    static class Triangle extends Shape {
        private double base;
        private double height;

        public Triangle(String color, double base, double height) {
            super(color);
            this.base = base;
            this.height = height;
        }

        @Override
        public double getArea() {
            return 0.5 * base * height;
        }

        @Override
        public void draw() {
            System.out.println("Drawing a triangle");
        }
    }

    // ========== 运行时多态演示 ==========
    public static void main(String[] args) {

        // ========== 1. 基本多态调用 ==========
        Shape shape1 = new Circle("Red", 5.0);
        Shape shape2 = new Rectangle("Blue", 4.0, 6.0);
        Shape shape3 = new Triangle("Green", 3.0, 4.0);

        // 运行时确定调用哪个 getArea()
        System.out.println("Circle area: " + shape1.getArea());
        System.out.println("Rectangle area: " + shape2.getArea());
        System.out.println("Triangle area: " + shape3.getArea());

        // ========== 2. 方法链中的多态 ==========
        shape1.displayInfo();  // displayInfo() 中调用 getArea(),多态!
        shape2.displayInfo();
        shape3.displayInfo();

        /**
         * displayInfo() 在父类中定义,但调用的 getArea()
         * 是运行时根据实际对象类型确定的!
         */

        // ========== 3. 集合中的多态 ==========
        List<Shape> shapes = Arrays.asList(
            new Circle("Red", 5.0),
            new Rectangle("Blue", 4.0, 6.0),
            new Triangle("Green", 3.0, 4.0),
            new Circle("Yellow", 3.0)
        );

        // 统一处理不同形状
        double totalArea = 0;
        for (Shape shape : shapes) {
            shape.draw();               // 多态调用
            totalArea += shape.getArea();  // 多态调用
        }
        System.out.println("Total area: " + totalArea);

        // ========== 4. instanceof 类型检查 ==========
        for (Shape shape : shapes) {
            if (shape instanceof Circle) {
                System.out.println("Found a circle");
            } else if (shape instanceof Rectangle) {
                System.out.println("Found a rectangle");
            } else if (shape instanceof Triangle) {
                System.out.println("Found a triangle");
            }
        }

        // ========== 5. 模式匹配(JDK 16+) ==========
        for (Shape shape : shapes) {
            if (shape instanceof Circle circle) {  // 模式匹配 + 自动转型
                System.out.println("Circle radius: " + circle.radius);
            } else if (shape instanceof Rectangle rect) {
                System.out.println("Rectangle: " + rect.width + "x" + rect.height);
            }
        }
    }

    /**
     * 多态的底层实现:虚方法表(Virtual Method Table, VMT)
     *
     * 每个类都有一个虚方法表,存储该类的所有虚方法的地址。
     *
     * Shape VMT:
     * ┌─────────────┬──────────────┐
     * │ getArea()   │ Shape.getArea│
     * │ draw()      │ Shape.draw   │
     * └─────────────┴──────────────┘
     *
     * Circle VMT:
     * ┌─────────────┬──────────────┐
     * │ getArea()   │ Circle.getArea│  ⬅️ 重写
     * │ draw()      │ Circle.draw   │  ⬅️ 重写
     * └─────────────┴──────────────┘
     *
     * 调用流程:
     * 1. 根据对象找到其类的虚方法表
     * 2. 在虚方法表中查找方法地址
     * 3. 调用对应地址的方法
     */
}

3.4 多态的实际应用

/**
 * 多态的实际应用场景
 */
public class PolymorphismApplications {

    // ========== 场景 1:支付系统 ==========

    interface PaymentMethod {
        boolean pay(double amount);
        String getPaymentType();
    }

    static class CreditCardPayment implements PaymentMethod {
        private String cardNumber;

        public CreditCardPayment(String cardNumber) {
            this.cardNumber = cardNumber;
        }

        @Override
        public boolean pay(double amount) {
            System.out.println("Paying $" + amount + " with Credit Card " + cardNumber);
            return true;
        }

        @Override
        public String getPaymentType() {
            return "Credit Card";
        }
    }

    static class PayPalPayment implements PaymentMethod {
        private String email;

        public PayPalPayment(String email) {
            this.email = email;
        }

        @Override
        public boolean pay(double amount) {
            System.out.println("Paying $" + amount + " with PayPal " + email);
            return true;
        }

        @Override
        public String getPaymentType() {
            return "PayPal";
        }
    }

    static class WeChatPayment implements PaymentMethod {
        private String phoneNumber;

        public WeChatPayment(String phoneNumber) {
            this.phoneNumber = phoneNumber;
        }

        @Override
        public boolean pay(double amount) {
            System.out.println("Paying $" + amount + " with WeChat " + phoneNumber);
            return true;
        }

        @Override
        public String getPaymentType() {
            return "WeChat Pay";
        }
    }

    /**
     * 订单类:使用多态处理不同支付方式
     */
    static class Order {
        private double totalAmount;
        private PaymentMethod paymentMethod;  // 多态字段

        public Order(double totalAmount) {
            this.totalAmount = totalAmount;
        }

        public void setPaymentMethod(PaymentMethod paymentMethod) {
            this.paymentMethod = paymentMethod;
        }

        public void checkout() {
            if (paymentMethod == null) {
                System.out.println("Please select a payment method");
                return;
            }

            System.out.println("Processing order...");
            // 多态调用:运行时确定具体支付方式
            if (paymentMethod.pay(totalAmount)) {
                System.out.println("Payment successful via " + paymentMethod.getPaymentType());
            } else {
                System.out.println("Payment failed");
            }
        }
    }

    // ========== 场景 2:日志系统 ==========

    interface Logger {
        void log(String message);
        void error(String message);
    }

    static class ConsoleLogger implements Logger {
        @Override
        public void log(String message) {
            System.out.println("[CONSOLE LOG] " + message);
        }

        @Override
        public void error(String message) {
            System.err.println("[CONSOLE ERROR] " + message);
        }
    }

    static class FileLogger implements Logger {
        private String filename;

        public FileLogger(String filename) {
            this.filename = filename;
        }

        @Override
        public void log(String message) {
            System.out.println("[FILE LOG to " + filename + "] " + message);
        }

        @Override
        public void error(String message) {
            System.out.println("[FILE ERROR to " + filename + "] " + message);
        }
    }

    static class DatabaseLogger implements Logger {
        private String connectionString;

        public DatabaseLogger(String connectionString) {
            this.connectionString = connectionString;
        }

        @Override
        public void log(String message) {
            System.out.println("[DB LOG to " + connectionString + "] " + message);
        }

        @Override
        public void error(String message) {
            System.out.println("[DB ERROR to " + connectionString + "] " + message);
        }
    }

    /**
     * 应用服务:使用多态的日志记录器
     */
    static class Application {
        private Logger logger;  // 多态字段

        public Application(Logger logger) {
            this.logger = logger;
        }

        public void start() {
            logger.log("Application started");
        }

        public void processData() {
            try {
                logger.log("Processing data...");
                int result = 100 / 0;  // 异常
            } catch (Exception e) {
                logger.error("Error: " + e.getMessage());
            }
        }
    }

    // ========== 场景 3:策略模式 ==========

    interface SortStrategy {
        void sort(int[] array);
    }

    static class BubbleSort implements SortStrategy {
        @Override
        public void sort(int[] array) {
            System.out.println("Using Bubble Sort");
            for (int i = 0; i < array.length - 1; i++) {
                for (int j = 0; j < array.length - 1 - i; j++) {
                    if (array[j] > array[j + 1]) {
                        int temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                    }
                }
            }
        }
    }

    static class QuickSort implements SortStrategy {
        @Override
        public void sort(int[] array) {
            System.out.println("Using Quick Sort");
            quickSort(array, 0, array.length - 1);
        }

        private void quickSort(int[] array, int low, int high) {
            if (low < high) {
                int pi = partition(array, low, high);
                quickSort(array, low, pi - 1);
                quickSort(array, pi + 1, high);
            }
        }

        private int partition(int[] array, int low, int high) {
            int pivot = array[high];
            int i = low - 1;
            for (int j = low; j < high; j++) {
                if (array[j] < pivot) {
                    i++;
                    int temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }
            }
            int temp = array[i + 1];
            array[i + 1] = array[high];
            array[high] = temp;
            return i + 1;
        }
    }

    static class MergeSort implements SortStrategy {
        @Override
        public void sort(int[] array) {
            System.out.println("Using Merge Sort");
            mergeSort(array, 0, array.length - 1);
        }

        private void mergeSort(int[] array, int left, int right) {
            if (left < right) {
                int mid = (left + right) / 2;
                mergeSort(array, left, mid);
                mergeSort(array, mid + 1, right);
                merge(array, left, mid, right);
            }
        }

        private void merge(int[] array, int left, int mid, int right) {
            // 归并逻辑
        }
    }

    /**
     * 排序器:运行时切换排序策略
     */
    static class Sorter {
        private SortStrategy strategy;

        public void setStrategy(SortStrategy strategy) {
            this.strategy = strategy;
        }

        public void executeSort(int[] array) {
            if (strategy == null) {
                System.out.println("No sorting strategy set");
                return;
            }
            strategy.sort(array);  // 多态调用
        }
    }

    // ========== 场景 4:工厂模式 + 多态 ==========

    interface Database {
        void connect();
        void query(String sql);
        void disconnect();
    }

    static class MySQLDatabase implements Database {
        @Override
        public void connect() {
            System.out.println("Connecting to MySQL...");
        }

        @Override
        public void query(String sql) {
            System.out.println("MySQL Query: " + sql);
        }

        @Override
        public void disconnect() {
            System.out.println("Disconnecting from MySQL");
        }
    }

    static class PostgreSQLDatabase implements Database {
        @Override
        public void connect() {
            System.out.println("Connecting to PostgreSQL...");
        }

        @Override
        public void query(String sql) {
            System.out.println("PostgreSQL Query: " + sql);
        }

        @Override
        public void disconnect() {
            System.out.println("Disconnecting from PostgreSQL");
        }
    }

    static class MongoDBDatabase implements Database {
        @Override
        public void connect() {
            System.out.println("Connecting to MongoDB...");
        }

        @Override
        public void query(String sql) {
            System.out.println("MongoDB Query: " + sql);
        }

        @Override
        public void disconnect() {
            System.out.println("Disconnecting from MongoDB");
        }
    }

    /**
     * 数据库工厂
     */
    static class DatabaseFactory {
        public static Database createDatabase(String type) {
            switch (type.toLowerCase()) {
                case "mysql":
                    return new MySQLDatabase();
                case "postgresql":
                    return new PostgreSQLDatabase();
                case "mongodb":
                    return new MongoDBDatabase();
                default:
                    throw new IllegalArgumentException("Unknown database type: " + type);
            }
        }
    }

    /**
     * 数据访问层:使用多态处理不同数据库
     */
    static class DataAccessLayer {
        private Database database;

        public DataAccessLayer(String dbType) {
            this.database = DatabaseFactory.createDatabase(dbType);
        }

        public void executeQuery(String sql) {
            database.connect();    // 多态调用
            database.query(sql);   // 多态调用
            database.disconnect(); // 多态调用
        }
    }

    // ========== 测试所有场景 ==========
    public static void main(String[] args) {
        System.out.println("========== 场景 1:支付系统 ==========");
        Order order = new Order(99.99);

        // 使用信用卡支付
        order.setPaymentMethod(new CreditCardPayment("1234-5678-9012-3456"));
        order.checkout();

        // 切换为 PayPal
        order.setPaymentMethod(new PayPalPayment("user@example.com"));
        order.checkout();

        // 切换为微信支付
        order.setPaymentMethod(new WeChatPayment("13800138000"));
        order.checkout();

        System.out.println("\n========== 场景 2:日志系统 ==========");

        // 使用控制台日志
        Application app1 = new Application(new ConsoleLogger());
        app1.start();
        app1.processData();

        // 切换为文件日志
        Application app2 = new Application(new FileLogger("app.log"));
        app2.start();
        app2.processData();

        // 切换为数据库日志
        Application app3 = new Application(new DatabaseLogger("jdbc:mysql://localhost/logs"));
        app3.start();
        app3.processData();

        System.out.println("\n========== 场景 3:策略模式 ==========");
        int[] data = {64, 34, 25, 12, 22, 11, 90};

        Sorter sorter = new Sorter();

        // 使用冒泡排序
        sorter.setStrategy(new BubbleSort());
        sorter.executeSort(data.clone());

        // 切换为快速排序
        sorter.setStrategy(new QuickSort());
        sorter.executeSort(data.clone());

        // 切换为归并排序
        sorter.setStrategy(new MergeSort());
        sorter.executeSort(data.clone());

        System.out.println("\n========== 场景 4:工厂模式 ==========");

        // 使用 MySQL
        DataAccessLayer dal1 = new DataAccessLayer("mysql");
        dal1.executeQuery("SELECT * FROM users");

        // 切换为 PostgreSQL
        DataAccessLayer dal2 = new DataAccessLayer("postgresql");
        dal2.executeQuery("SELECT * FROM products");

        // 切换为 MongoDB
        DataAccessLayer dal3 = new DataAccessLayer("mongodb");
        dal3.executeQuery("db.orders.find()");
    }
}

说明:

  1. 支付系统(场景 1):通过设置 PaymentMethod,动态切换支付方式(信用卡、PayPal、微信支付),展示了如何通过多态来处理不同支付方式。
  2. 日志系统(场景 2):通过日志记录器接口 Logger,切换控制台日志、文件日志和数据库日志,展示多态如何适配不同日志输出方式。
  3. 策略模式(场景 3):通过 SortStrategy 接口,运行时切换排序算法(冒泡排序、快速排序、归并排序),展示如何使用策略模式。
  4. 工厂模式 + 多态(场景 4):通过 Database 接口,动态选择数据库(MySQL、PostgreSQL、MongoDB),展示了工厂模式与多态结合的使用。

四、Java OOP 的高级特性

4.1 单继承机制

/**
 * Java 为什么不支持多重继承?
 * 
 * 问题:菱形继承问题(Diamond Problem)
 */
public class SingleInheritanceDemo {
    
    // ========== 菱形继承问题示例(假设 Java 支持多继承) ==========
    
    /**
     * 假设的场景:
     * 
     *        A
     *       / \
     *      B   C
     *       \ /
     *        D
     * 
     * 如果 B 和 C 都重写了 A 的方法,D 继承 B 和 C,
     * 那么 D 调用该方法时应该用哪个版本?
     */
    
    static class A {
        public void display() {
            System.out.println("A");
        }
    }
    
    // ❌ Java 不支持
    // class D extends B, C { }  // 编译错误
    
    /**
     * Java 的解决方案:单继承 + 接口多实现
     */
    
    static class B extends A {
        @Override
        public void display() {
            System.out.println("B");
        }
    }
    
    static class C extends A {
        @Override
        public void display() {
            System.out.println("C");
        }
    }
    
    // ✅ D 只能选择继承一个类
    static class D extends B {
        // 只继承 B 的实现
    }
    
    /**
     * 单继承的优势:
     * 
     * ✅ 1. 避免菱形继承问题
     * ✅ 2. 简化继承关系
     * ✅ 3. 降低复杂度
     * ✅ 4. 提高代码可读性
     */
}

4.2 接口多实现

/**
 * Java 通过接口实现"多重继承"的效果
 */
public class MultipleInterfaceDemo {

    // ========== 多个接口 ==========

    // Flyable 接口:定义了飞行和起飞行为
    interface Flyable {
        void fly();

        default void takeOff() {
            System.out.println("Taking off...");
        }
    }

    // Swimmable 接口:定义了游泳和潜水行为
    interface Swimmable {
        void swim();

        default void dive() {
            System.out.println("Diving...");
        }
    }

    // Runnable 接口:定义了奔跑和冲刺行为
    interface Runnable {
        void run();
        
        default void sprint() {
            System.out.println("Sprinting...");
        }
    }

    // ========== 实现多个接口 ==========

    /**
     * Duck 类实现了 Flyable, Swimmable 和 Runnable 接口
     * 拥有飞行、游泳、奔跑的能力
     */
    static class Duck implements Flyable, Swimmable, Runnable {
        @Override
        public void fly() {
            System.out.println("Duck is flying");
        }

        @Override
        public void swim() {
            System.out.println("Duck is swimming");
        }

        @Override
        public void run() {
            System.out.println("Duck is running");
        }
    }

    /**
     * Fish 类只实现了 Swimmable 接口
     */
    static class Fish implements Swimmable {
        @Override
        public void swim() {
            System.out.println("Fish is swimming");
        }
    }

    /**
     * Bird 类实现了 Flyable 和 Runnable 接口
     */
    static class Bird implements Flyable, Runnable {
        @Override
        public void fly() {
            System.out.println("Bird is flying");
        }

        @Override
        public void run() {
            System.out.println("Bird is running");
        }
    }

    // ========== 接口冲突问题 ==========

    // 定义两个接口,它们有相同的默认方法 display
    interface Interface1 {
        default void display() {
            System.out.println("Interface1");
        }
    }

    interface Interface2 {
        default void display() {
            System.out.println("Interface2");
        }
    }

    /**
     * 如果两个接口有相同的默认方法,必须在实现类中显式重写
     */
    static class MyClass implements Interface1, Interface2 {
        @Override
        public void display() {
            // 必须重写以解决冲突

            // 方式 1:提供自己的实现
            System.out.println("MyClass");

            // 方式 2:调用某个接口的默认实现
            // Interface1.super.display();
            // 或
            // Interface2.super.display();
        }
    }

    // ========== 接口继承接口 ==========

    interface Animal {
        void eat();
    }

    interface Pet extends Animal {
        void play();
    }

    interface WildAnimal extends Animal {
        void hunt();
    }

    /**
     * 接口可以继承多个接口
     */
    interface Creature extends Flyable, Swimmable {
        void breathe();
    }

    static class Dragon implements Creature {
        @Override
        public void fly() {
            System.out.println("Dragon is flying");
        }

        @Override
        public void swim() {
            System.out.println("Dragon is swimming");
        }

        @Override
        public void breathe() {
            System.out.println("Dragon is breathing fire");
        }
    }

    // ========== 测试 ==========

    public static void main(String[] args) {
        System.out.println("========== Duck(多接口实现) ==========");
        Duck duck = new Duck();
        duck.fly();
        duck.swim();
        duck.run();
        duck.takeOff();  // 默认方法
        duck.dive();     // 默认方法
        duck.sprint();   // 默认方法

        System.out.println("\n========== 多态 ==========");
        // Duck 可以被视为多种类型
        Flyable flyable = duck;
        flyable.fly();

        Swimmable swimmable = duck;
        swimmable.swim();

        Runnable runnable = duck;
        runnable.run();

        System.out.println("\n========== 接口冲突解决 ==========");
        MyClass obj = new MyClass();
        obj.display();

        System.out.println("\n========== Dragon(接口继承) ==========");
        Dragon dragon = new Dragon();
        dragon.fly();
        dragon.swim();
        dragon.breathe();
        dragon.takeOff();  // 继承自 Flyable
        dragon.dive();     // 继承自 Swimmable
    }
}

  1. 多个接口:
    • 定义了三个接口 FlyableSwimmableRunnable,它们包含了飞行、游泳、奔跑的行为,且每个接口有一个默认方法。
  2. 实现多个接口:
    • Duck 类实现了所有三个接口(FlyableSwimmableRunnable),具备飞行、游泳、奔跑的功能。
    • Fish 类只实现了 Swimmable 接口,具备游泳功能。
    • Bird 类实现了 FlyableRunnable 接口,具备飞行和奔跑的功能。
  3. 接口冲突:
    • Interface1Interface2 都有 display 方法,如果实现这两个接口,需要在 MyClass 中重写 display 方法来解决冲突,可以选择自定义实现或调用某个接口的默认实现。
  4. 接口继承:
    • Creature 接口继承了 FlyableSwimmable,并定义了 breathe 方法,Dragon 类实现了 Creature 接口,具备飞行、游泳和呼吸的能力。
  5. 多态:
    • Duck 类对象可以被作为 FlyableSwimmableRunnable 类型使用,展示了接口的多态特性。
  6. 测试:
    • main 方法测试了各个场景,展示了如何使用多个接口、如何解决接口冲突以及如何利用接口继承创建多功能类。

核心概念:

  • 多接口实现: 类可以实现多个接口,从而实现多重功能。
  • 默认方法: 接口可以提供默认方法,在实现类中不必实现。
  • 接口冲突: 如果多个接口定义了相同的默认方法,必须在实现类中显式重写该方法。
  • 接口继承: 接口可以继承多个接口,创建更复杂的接口层次结构。

4.3 接口 vs 抽象类:

接口(Interface):

  • ✅ 支持多实现
  • ✅ 所有方法默认是 public abstract(JDK 8 前)
  • ✅ 只能有常量(public static final)
  • ✅ 支持默认方法和静态方法(JDK 8+)
  • ✅ 表示"能做什么"(能力)

抽象类(Abstract Class):

  • ✅ 只支持单继承
  • ✅ 可以有任意访问修饰符
  • ✅ 可以有实例变量
  • ✅ 可以有构造器
  • ✅ 表示"是什么"(本质)

⬅️ 面向对象or面向过程 🏠 00-Java ➡️ 面向对象设计的SOLID原则