Skip to content

面向对象编程

Java 是一门纯粹的面向对象编程语言,面向对象编程(OOP)是 Java 的核心特性。

面向对象概念

三大特性

  • 封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式
  • 继承:子类继承父类的属性和方法,实现代码复用
  • 多态:同一操作作用于不同对象,产生不同的执行结果

类与对象

类的定义

java
public class Person {
    // 属性(成员变量)
    private String name;
    private int age;

    // 静态变量(类变量)
    public static int count = 0;

    // 构造方法
    public Person() {
        this("未知", 0);
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        count++;
    }

    // 实例方法
    public void introduce() {
        System.out.println("我叫" + name + ",今年" + age + "岁");
    }

    // 静态方法(类方法)
    public static int getCount() {
        return count;
    }

    // Getter 和 Setter
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age > 0 && age < 150) {
            this.age = age;
        }
    }
}

对象的创建与使用

java
public class Main {
    public static void main(String[] args) {
        // 创建对象
        Person person1 = new Person();
        Person person2 = new Person("张三", 25);

        // 调用方法
        person1.introduce();  // 我叫未知,今年0岁
        person2.introduce();  // 我叫张三,今年25岁

        // 使用 setter 修改属性
        person1.setName("李四");
        person1.setAge(30);

        // 使用 getter 获取属性
        System.out.println(person1.getName());  // 李四

        // 调用静态方法
        System.out.println("总人数: " + Person.getCount());  // 2
    }
}

构造方法

构造方法特点

  • 方法名与类名相同
  • 没有返回值类型(连 void 都没有)
  • 在创建对象时自动调用
  • 可以重载
java
public class Student {
    private String name;
    private int age;
    private String major;

    // 无参构造
    public Student() {
        this.name = "未知";
    }

    // 带参构造
    public Student(String name) {
        this.name = name;
    }

    // 全参构造
    public Student(String name, int age, String major) {
        this.name = name;
        this.age = age;
        this.major = major;
    }
}

构造代码块

java
public class Example {
    private int value;

    // 构造代码块,在每次创建对象时都会执行
    // 优先于构造方法执行
    {
        System.out.println("构造代码块执行");
        value = 100;
    }

    public Example() {
        System.out.println("构造方法执行");
    }
}

封装

访问修饰符

修饰符同一类同一包子类其他
public
protected
默认
private

封装示例

java
public class BankAccount {
    // 私有属性,外部无法直接访问
    private String accountNumber;
    private double balance;

    public BankAccount(String accountNumber, double balance) {
        this.accountNumber = accountNumber;
        this.balance = balance;
    }

    // 公共方法,提供受控的访问
    public double getBalance() {
        return balance;
    }

    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("存款成功: " + amount);
        }
    }

    public void withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("取款成功: " + amount);
        } else {
            System.out.println("取款失败: 余额不足");
        }
    }
}

继承

基本语法

java
// 父类
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 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 eat() {
        System.out.println(name + "正在吃狗粮");
    }
}

// 使用
Dog dog = new Dog("旺财", 3, "金毛");
dog.eat();    // 旺财正在吃狗粮
dog.sleep();  // 旺财正在睡觉
dog.bark();   // 旺财正在汪汪叫

方法重写

java
public class Bird extends Animal {
    public Bird(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(name + "正在吃虫子");
    }

    // 子类特有方法
    public void fly() {
        System.out.println(name + "正在飞翔");
    }
}

super 关键字

java
public class Child extends Parent {
    private String name;

    public Child(String parentName, String childName) {
        super(parentName);  // 调用父类构造方法
        this.name = childName;
    }

    public void showNames() {
        System.out.println("父类名称: " + super.name);  // 访问父类属性
        super.showName();  // 调用父类方法
    }
}

final 关键字

java
// final 类不能被继承
public final class Constants {
    // final 变量不能被修改
    public static final double PI = 3.14159;

    // final 方法不能被重写
    public final void show() {
        System.out.println("这是一个 final 方法");
    }
}

多态

多态的实现

java
// 父类引用指向子类对象
Animal animal1 = new Dog("旺财", 3);
Animal animal2 = new Bird("小鸟", 1);

// 调用重写的方法
animal1.eat();  // 旺财正在吃狗粮
animal2.eat();  // 小鸟正在吃虫子

// 编译时类型是 Animal,无法调用子类特有方法
// animal1.bark();  // 编译错误

// 需要向下转型
if (animal1 instanceof Dog) {
    Dog dog = (Dog) animal1;
    dog.bark();  // 旺财正在汪汪叫
}

多态示例

java
public class ShapeDemo {
    public static void main(String[] args) {
        Shape[] shapes = {
            new Circle(5),
            new Rectangle(4, 6),
            new Triangle(3, 4, 5)
        };

        for (Shape shape : shapes) {
            System.out.println("面积: " + shape.getArea());
            System.out.println("周长: " + shape.getPerimeter());
        }
    }
}

abstract class Shape {
    public abstract double getArea();
    public abstract double getPerimeter();
}

class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }

    @Override
    public double getPerimeter() {
        return 2 * Math.PI * radius;
    }
}

class Rectangle extends Shape {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

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

    @Override
    public double getPerimeter() {
        return 2 * (width + height);
    }
}

抽象类

抽象类定义

java
// 抽象类不能实例化
public 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 showInfo() {
        System.out.println("姓名: " + name);
        System.out.println("工资: " + calculateSalary());
    }
}

// 子类实现抽象方法
public class Manager extends Employee {
    private double bonus;

    public Manager(String name, double baseSalary, double bonus) {
        super(name, baseSalary);
        this.bonus = bonus;
    }

    @Override
    public double calculateSalary() {
        return baseSalary + bonus;
    }
}

public class Developer extends Employee {
    private int overtimeHours;

    public Developer(String name, double baseSalary, int overtimeHours) {
        super(name, baseSalary);
        this.overtimeHours = overtimeHours;
    }

    @Override
    public double calculateSalary() {
        return baseSalary + overtimeHours * 100;
    }
}

接口

接口定义

java
// 定义接口
public interface Flyable {
    int MAX_HEIGHT = 10000;  // 默认 public static final

    void fly();  // 默认 public abstract

    // 默认方法(Java 8+)
    default void showMaxHeight() {
        System.out.println("最大飞行高度: " + MAX_HEIGHT);
    }

    // 静态方法(Java 8+)
    static void info() {
        System.out.println("这是一个飞行接口");
    }
}

// 实现接口
public class Airplane implements Flyable {
    @Override
    public void fly() {
        System.out.println("飞机在天空飞行");
    }
}

// 实现多个接口
public class Superman implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("超人在飞行");
    }

    @Override
    public void swim() {
        System.out.println("超人在游泳");
    }
}

接口继承

java
public interface A {
    void methodA();
}

public interface B {
    void methodB();
}

// 接口多继承
public interface C extends A, B {
    void methodC();
}

// 实现类需要实现所有方法
public class Impl implements C {
    @Override
    public void methodA() {}

    @Override
    public void methodB() {}

    @Override
    public void methodC() {}
}

内部类

成员内部类

java
public class Outer {
    private int outerField = 10;

    // 成员内部类
    public class Inner {
        private int innerField = 20;

        public void show() {
            System.out.println("外部类字段: " + outerField);
            System.out.println("内部类字段: " + innerField);
        }
    }

    public void createInner() {
        Inner inner = new Inner();
        inner.show();
    }
}

// 使用
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.show();

静态内部类

java
public class Outer {
    private static int staticField = 10;

    // 静态内部类
    public static class StaticInner {
        public void show() {
            System.out.println("静态字段: " + staticField);
            // 不能访问外部类的非静态成员
        }
    }
}

// 使用
Outer.StaticInner inner = new Outer.StaticInner();
inner.show();

局部内部类

java
public class Outer {
    public void method() {
        final int localVar = 10;

        // 局部内部类
        class LocalInner {
            public void show() {
                System.out.println("局部变量: " + localVar);
            }
        }

        LocalInner inner = new LocalInner();
        inner.show();
    }
}

匿名内部类

java
public interface Greeting {
    void greet();
}

public class Main {
    public static void main(String[] args) {
        // 匿名内部类
        Greeting greeting = new Greeting() {
            @Override
            public void greet() {
                System.out.println("Hello!");
            }
        };

        greeting.greet();

        // 使用 Lambda 表达式(Java 8+)
        Greeting greeting2 = () -> System.out.println("Hello Lambda!");
        greeting2.greet();
    }
}

枚举

枚举定义

java
public enum Weekday {
    MONDAY("星期一"),
    TUESDAY("星期二"),
    WEDNESDAY("星期三"),
    THURSDAY("星期四"),
    FRIDAY("星期五"),
    SATURDAY("星期六"),
    SUNDAY("星期日");

    private String name;

    Weekday(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

// 使用
Weekday day = Weekday.MONDAY;
System.out.println(day.getName());  // 星期一

// 遍历
for (Weekday w : Weekday.values()) {
    System.out.println(w.ordinal() + ": " + w.getName());
}

// switch
switch (day) {
    case MONDAY:
        System.out.println("工作日");
        break;
    case SATURDAY:
    case SUNDAY:
        System.out.println("周末");
        break;
}

带方法的枚举

java
public enum Operation {
    ADD {
        @Override
        public double apply(double x, double y) {
            return x + y;
        }
    },
    SUBTRACT {
        @Override
        public double apply(double x, double y) {
            return x - y;
        }
    },
    MULTIPLY {
        @Override
        public double apply(double x, double y) {
            return x * y;
        }
    },
    DIVIDE {
        @Override
        public double apply(double x, double y) {
            return x / y;
        }
    };

    public abstract double apply(double x, double y);
}

// 使用
double result = Operation.ADD.apply(5, 3);  // 8.0

实践示例

java
import java.util.ArrayList;
import java.util.List;

// 定义接口
interface Payable {
    double calculatePay();
}

// 抽象类
abstract class Worker implements Payable {
    protected String name;
    protected int id;

    public Worker(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public abstract void work();

    public void showInfo() {
        System.out.println("ID: " + id + ", 姓名: " + name);
    }
}

// 具体类
class FullTimeEmployee extends Worker {
    private double monthlySalary;
    private double bonus;

    public FullTimeEmployee(String name, int id, double monthlySalary, double bonus) {
        super(name, id);
        this.monthlySalary = monthlySalary;
        this.bonus = bonus;
    }

    @Override
    public void work() {
        System.out.println(name + "正在全职工作");
    }

    @Override
    public double calculatePay() {
        return monthlySalary + bonus;
    }
}

class PartTimeEmployee extends Worker {
    private double hourlyRate;
    private int hoursWorked;

    public PartTimeEmployee(String name, int id, double hourlyRate, int hoursWorked) {
        super(name, id);
        this.hourlyRate = hourlyRate;
        this.hoursWorked = hoursWorked;
    }

    @Override
    public void work() {
        System.out.println(name + "正在兼职工作");
    }

    @Override
    public double calculatePay() {
        return hourlyRate * hoursWorked;
    }
}

// 使用
public class Company {
    public static void main(String[] args) {
        List<Worker> workers = new ArrayList<>();
        workers.add(new FullTimeEmployee("张三", 1, 10000, 2000));
        workers.add(new PartTimeEmployee("李四", 2, 50, 80));
        workers.add(new FullTimeEmployee("王五", 3, 15000, 3000));

        double totalPay = 0;

        for (Worker worker : workers) {
            worker.showInfo();
            worker.work();
            double pay = worker.calculatePay();
            System.out.println("工资: " + pay);
            System.out.println("--------------------");
            totalPay += pay;
        }

        System.out.println("总工资支出: " + totalPay);
    }
}