002-面向对象基本概念

002-面向对象基本概念

🟢 难度: 初级 | ⏱️ 预计时间: 2.5小时 | 📋 前置: 001-面向对象概述

📚 导航

⬅️ 上一章: 001-面向对象概述
➡️ 下一章: 003-类与对象
🏠 返回目录: 面向对象教程

学习目标

完成本章节后,你将能够:

  • 深入理解面向对象的四大基本特征:抽象、封装、继承、多态
  • 掌握类与对象的关系和区别
  • 理解消息传递机制
  • 掌握面向对象的基本术语和概念
  • 能够识别和分析简单的面向对象设计

1. 面向对象四大基本特征

面向对象编程有四大基本特征,它们构成了面向对象技术的理论基础:

mindmap
  root((面向对象四大特征))
    抽象(Abstraction)
      数据抽象
      过程抽象
      忽略无关细节
      突出本质特征
    封装(Encapsulation)
      数据隐藏
      接口统一
      访问控制
      模块化
    继承(Inheritance)
      代码重用
      层次结构
      "is-a"关系
      特化与泛化
    多态(Polymorphism)
      同一接口
      不同实现
      动态绑定
      运行时决定

1.1 抽象(Abstraction)

定义:抽象是指忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。

抽象的类型

1. 数据抽象

  • 描述对象的属性和状态
  • 定义对象的数据结构
  • 隐藏数据的具体实现

2. 过程抽象

  • 描述对象的行为和操作
  • 定义对象的方法接口
  • 隐藏方法的具体实现
抽象的实现示例
// 抽象类:图形
public abstract class Shape {
    // 数据抽象:基本属性
    protected String color;
    protected double x, y; // 位置坐标
    
    // 构造方法
    public Shape(String color, double x, double y) {
        this.color = color;
        this.x = x;
        this.y = y;
    }
    
    // 过程抽象:抽象方法(子类必须实现)
    public abstract double calculateArea();     // 计算面积
    public abstract double calculatePerimeter(); // 计算周长
    public abstract void draw();                // 绘制图形
    
    // 具体方法:通用行为
    public void move(double deltaX, double deltaY) {
        this.x += deltaX;
        this.y += deltaY;
        System.out.println("图形移动到: (" + x + ", " + y + ")");
    }
    
    // 获取颜色
    public String getColor() {
        return color;
    }
}

// 具体实现:圆形
public class Circle extends Shape {
    private double radius;
    
    public Circle(String color, double x, double y, double radius) {
        super(color, x, y);
        this.radius = radius;
    }
    
    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
    
    @Override
    public double calculatePerimeter() {
        return 2 * Math.PI * radius;
    }
    
    @Override
    public void draw() {
        System.out.println("绘制" + color + "圆形,半径: " + radius);
    }
}
抽象的层次
现实世界
概念模型
逻辑模型
物理模型
具体的汽车
奔驰S500
汽车概念
交通工具
汽车类
属性和方法
代码实现
Car.java

1.2 封装(Encapsulation)

定义:封装是把对象的属性和方法结合成一个独立的系统单位,并尽可能隐藏对象的内部细节。

封装的目的
  1. 数据保护:防止外部直接访问和修改对象内部数据
  2. 接口统一:提供统一的访问接口
  3. 降低耦合:减少模块间的依赖关系
  4. 提高安全性:控制对数据的访问权限
访问控制修饰符
修饰符同一类同一包子类其他包说明
private私有,仅本类可访问
default包私有,同包可访问
protected受保护,子类可访问
public公有,所有类可访问
封装的实现示例
public class BankAccount {
    // 私有属性:外部无法直接访问
    private String accountNumber;
    private String accountHolder;
    private double balance;
    private String password;
    
    // 构造方法
    public BankAccount(String accountNumber, String accountHolder, String password) {
        this.accountNumber = accountNumber;
        this.accountHolder = accountHolder;
        this.password = password;
        this.balance = 0.0;
    }
    
    // 公有方法:提供受控的访问接口
    public boolean deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("存款成功,当前余额: " + balance);
            return true;
        }
        System.out.println("存款金额必须大于0");
        return false;
    }
    
    public boolean withdraw(double amount, String inputPassword) {
        // 密码验证
        if (!verifyPassword(inputPassword)) {
            System.out.println("密码错误");
            return false;
        }
        
        // 余额检查
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("取款成功,当前余额: " + balance);
            return true;
        }
        
        System.out.println("取款失败:金额无效或余额不足");
        return false;
    }
    
    // 私有方法:内部使用,外部无法访问
    private boolean verifyPassword(String inputPassword) {
        return this.password.equals(inputPassword);
    }
    
    // 受保护的方法:子类可以访问
    protected void updateBalance(double newBalance) {
        this.balance = newBalance;
    }
    
    // 公有访问器:只读访问
    public double getBalance(String inputPassword) {
        if (verifyPassword(inputPassword)) {
            return balance;
        }
        throw new SecurityException("密码错误,无法查询余额");
    }
    
    public String getAccountNumber() {
        return accountNumber;
    }
    
    public String getAccountHolder() {
        return accountHolder;
    }
}
封装的好处
封装的好处
数据安全
代码维护
接口稳定
模块独立
防止非法访问
数据一致性保证
内部修改不影响外部
降低维护成本
公共接口不变
向后兼容性
降低耦合度
提高重用性

1.3 继承(Inheritance)

定义:继承是一种机制,允许在已有类的基础上创建新类,新类可以继承已有类的属性和方法。

继承的基本概念
  • 父类(超类、基类):被继承的类
  • 子类(派生类):继承其他类的类
  • 单继承:一个子类只能有一个直接父类
  • 多继承:一个子类可以有多个直接父类(Java不支持,但支持接口多实现)
继承关系图
Vehicle
-String brand
-String model
-int year
+start()
+stop()
+getInfo()
Car
-int doors
-String fuelType
+openTrunk()
+lockDoors()
Motorcycle
-boolean hasSidecar
+wheelie()
+leanInTurn()
Truck
-double cargoCapacity
-int axles
+loadCargo()
+unloadCargo()
继承的实现示例
// 父类:交通工具
public class Vehicle {
    protected String brand;      // 品牌
    protected String model;      // 型号
    protected int year;          // 年份
    protected boolean isRunning; // 运行状态
    
    // 构造方法
    public Vehicle(String brand, String model, int year) {
        this.brand = brand;
        this.model = model;
        this.year = year;
        this.isRunning = false;
    }
    
    // 启动
    public void start() {
        if (!isRunning) {
            isRunning = true;
            System.out.println(brand + " " + model + " 启动了");
        }
    }
    
    // 停止
    public void stop() {
        if (isRunning) {
            isRunning = false;
            System.out.println(brand + " " + model + " 停止了");
        }
    }
    
    // 获取信息
    public String getInfo() {
        return year + "年 " + brand + " " + model;
    }
    
    // 获取运行状态
    public boolean isRunning() {
        return isRunning;
    }
}

// 子类:汽车
public class Car extends Vehicle {
    private int doors;           // 门数
    private String fuelType;     // 燃料类型
    private boolean trunkOpen;   // 后备箱状态
    
    // 构造方法
    public Car(String brand, String model, int year, int doors, String fuelType) {
        super(brand, model, year); // 调用父类构造方法
        this.doors = doors;
        this.fuelType = fuelType;
        this.trunkOpen = false;
    }
    
    // 重写父类方法
    @Override
    public void start() {
        System.out.println("检查燃料: " + fuelType);
        super.start(); // 调用父类方法
        System.out.println("汽车准备就绪");
    }
    
    // 新增方法:打开后备箱
    public void openTrunk() {
        if (!trunkOpen) {
            trunkOpen = true;
            System.out.println("后备箱已打开");
        }
    }
    
    // 新增方法:锁车门
    public void lockDoors() {
        if (!isRunning) {
            System.out.println("所有 " + doors + " 个车门已锁定");
        } else {
            System.out.println("车辆运行中,无法锁定车门");
        }
    }
    
    // 重写获取信息方法
    @Override
    public String getInfo() {
        return super.getInfo() + ", " + doors + "门, 燃料: " + fuelType;
    }
}

// 子类:摩托车
public class Motorcycle extends Vehicle {
    private boolean hasSidecar;  // 是否有边车
    
    public Motorcycle(String brand, String model, int year, boolean hasSidecar) {
        super(brand, model, year);
        this.hasSidecar = hasSidecar;
    }
    
    @Override
    public void start() {
        System.out.println("检查头盔和护具");
        super.start();
        System.out.println("摩托车准备就绪");
    }
    
    // 新增方法:翘头
    public void wheelie() {
        if (isRunning && !hasSidecar) {
            System.out.println("摩托车翘头表演!");
        } else {
            System.out.println("无法执行翘头:车辆未启动或有边车");
        }
    }
    
    @Override
    public String getInfo() {
        return super.getInfo() + (hasSidecar ? ", 带边车" : ", 无边车");
    }
}
继承的类型
继承类型
实现继承
接口继承
继承具体实现
代码重用
is-a关系
继承接口规范
多重继承
can-do关系

1.4 多态(Polymorphism)

定义:多态是指同一个接口可以有多种不同的实现方式,在运行时根据对象的实际类型来决定调用哪个具体的实现。

多态的类型

1. 编译时多态(静态多态)

  • 方法重载(Overloading)
  • 运算符重载

2. 运行时多态(动态多态)

  • 方法重写(Overriding)
  • 虚方法调用
多态的实现条件
  1. 继承关系:子类继承父类
  2. 方法重写:子类重写父类方法
  3. 向上转型:父类引用指向子类对象
多态的实现示例
// 抽象父类:动物
public abstract class Animal {
    protected String name;
    protected int age;
    
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // 抽象方法:发出声音(多态的基础)
    public abstract void makeSound();
    
    // 抽象方法:移动方式
    public abstract void move();
    
    // 具体方法:睡觉
    public void sleep() {
        System.out.println(name + " 正在睡觉...");
    }
    
    // 获取信息
    public String getInfo() {
        return name + ",年龄: " + age;
    }
}

// 子类:狗
public class Dog extends Animal {
    private String breed; // 品种
    
    public Dog(String name, int age, String breed) {
        super(name, age);
        this.breed = breed;
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + " 汪汪叫!");
    }
    
    @Override
    public void move() {
        System.out.println(name + " 在地上跑来跑去");
    }
    
    // 特有方法
    public void wagTail() {
        System.out.println(name + " 摇尾巴表示友好");
    }
    
    @Override
    public String getInfo() {
        return super.getInfo() + ",品种: " + breed;
    }
}

// 子类:猫
public class Cat extends Animal {
    private boolean isIndoor; // 是否室内猫
    
    public Cat(String name, int age, boolean isIndoor) {
        super(name, age);
        this.isIndoor = isIndoor;
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + " 喵喵叫!");
    }
    
    @Override
    public void move() {
        System.out.println(name + " 优雅地踱步");
    }
    
    // 特有方法
    public void purr() {
        System.out.println(name + " 发出呼噜声");
    }
    
    @Override
    public String getInfo() {
        return super.getInfo() + (isIndoor ? ",室内猫" : ",户外猫");
    }
}

// 子类:鸟
public class Bird extends Animal {
    private boolean canFly; // 是否会飞
    
    public Bird(String name, int age, boolean canFly) {
        super(name, age);
        this.canFly = canFly;
    }
    
    @Override
    public void makeSound() {
        System.out.println(name + " 啾啾叫!");
    }
    
    @Override
    public void move() {
        if (canFly) {
            System.out.println(name + " 在天空中飞翔");
        } else {
            System.out.println(name + " 在地上蹦跳");
        }
    }
    
    // 特有方法
    public void buildNest() {
        System.out.println(name + " 正在筑巢");
    }
}

// 多态的使用示例
public class AnimalDemo {
    public static void main(String[] args) {
        // 创建不同类型的动物对象
        Animal[] animals = {
            new Dog("旺财", 3, "金毛"),
            new Cat("咪咪", 2, true),
            new Bird("小黄", 1, true)
        };
        
        // 多态的体现:同一个方法调用,不同的实现
        System.out.println("=== 动物园表演开始 ===");
        for (Animal animal : animals) {
            System.out.println("\n" + animal.getInfo());
            animal.makeSound(); // 多态:运行时决定调用哪个实现
            animal.move();      // 多态:运行时决定调用哪个实现
            animal.sleep();     // 调用父类方法
        }
        
        // 演示向下转型
        System.out.println("\n=== 特殊表演 ===");
        for (Animal animal : animals) {
            if (animal instanceof Dog) {
                Dog dog = (Dog) animal; // 向下转型
                dog.wagTail();          // 调用子类特有方法
            } else if (animal instanceof Cat) {
                Cat cat = (Cat) animal;
                cat.purr();
            } else if (animal instanceof Bird) {
                Bird bird = (Bird) animal;
                bird.buildNest();
            }
        }
    }
    
    // 多态的另一个例子:动物管理员
    public static void feedAnimal(Animal animal) {
        System.out.println("准备喂食: " + animal.getInfo());
        animal.makeSound(); // 多态:不同动物不同叫声
        System.out.println("喂食完成\n");
    }
}
多态的优势
多态的优势
代码灵活性
可扩展性
维护性
重用性
统一接口
动态绑定
新增类型无需修改现有代码
开闭原则
修改实现不影响调用代码
降低耦合
通用算法
框架设计

2. 类与对象的深入理解

2.1 类的定义和组成

**类(Class)**是对象的模板或蓝图,定义了对象的属性和行为。

类的组成要素
类的组成
属性(Fields)
方法(Methods)
构造器(Constructors)
内部类(Inner Classes)
静态成员(Static Members)
实例变量
类变量
实例方法
类方法
抽象方法
默认构造器
参数化构造器
重载构造器
完整的类定义示例
public class Student {
    // 静态变量:类变量,所有实例共享
    private static int totalStudents = 0;
    private static final String SCHOOL_NAME = "清华大学";
    
    // 实例变量:每个对象独有
    private String studentId;      // 学号
    private String name;           // 姓名
    private int age;               // 年龄
    private String major;          // 专业
    private double[] scores;       // 成绩数组
    
    // 静态初始化块
    static {
        System.out.println("Student类被加载");
    }
    
    // 实例初始化块
    {
        scores = new double[5]; // 默认5门课程
        System.out.println("创建新的学生对象");
    }
    
    // 默认构造器
    public Student() {
        this("未知", "S000000", 18, "未定");
    }
    
    // 参数化构造器
    public Student(String name, String studentId, int age, String major) {
        this.name = name;
        this.studentId = studentId;
        this.age = age;
        this.major = major;
        totalStudents++; // 学生总数增加
    }
    
    // 实例方法:添加成绩
    public void addScore(int courseIndex, double score) {
        if (courseIndex >= 0 && courseIndex < scores.length) {
            scores[courseIndex] = score;
        } else {
            throw new IndexOutOfBoundsException("课程索引超出范围");
        }
    }
    
    // 实例方法:计算平均分
    public double calculateAverage() {
        double sum = 0;
        int count = 0;
        for (double score : scores) {
            if (score > 0) { // 只计算已录入的成绩
                sum += score;
                count++;
            }
        }
        return count > 0 ? sum / count : 0;
    }
    
    // 实例方法:获取学生信息
    public String getStudentInfo() {
        return String.format("学号: %s, 姓名: %s, 年龄: %d, 专业: %s, 平均分: %.2f",
                studentId, name, age, major, calculateAverage());
    }
    
    // 静态方法:获取学生总数
    public static int getTotalStudents() {
        return totalStudents;
    }
    
    // 静态方法:获取学校名称
    public static String getSchoolName() {
        return SCHOOL_NAME;
    }
    
    // 静态方法:比较两个学生的平均分
    public static int compareByAverage(Student s1, Student s2) {
        return Double.compare(s1.calculateAverage(), s2.calculateAverage());
    }
    
    // Getter和Setter方法
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    
    public String getStudentId() { return studentId; }
    
    public int getAge() { return age; }
    public void setAge(int age) {
        if (age > 0 && age < 150) {
            this.age = age;
        } else {
            throw new IllegalArgumentException("年龄必须在1-149之间");
        }
    }
    
    public String getMajor() { return major; }
    public void setMajor(String major) { this.major = major; }
    
    // 重写Object类的方法
    @Override
    public String toString() {
        return getStudentInfo();
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Student student = (Student) obj;
        return studentId.equals(student.studentId);
    }
    
    @Override
    public int hashCode() {
        return studentId.hashCode();
    }
}

2.2 对象的创建和生命周期

对象创建过程
客户端代码 Java虚拟机 堆内存 类加载器 new Student("张三", "S001", 20, "计算机") 加载Student类(如果未加载) 类加载完成 分配内存空间 返回内存地址 执行实例初始化块 调用构造器 返回对象引用 客户端代码 Java虚拟机 堆内存 类加载器
对象的使用示例
public class StudentDemo {
    public static void main(String[] args) {
        // 1. 创建对象
        System.out.println("=== 创建学生对象 ===");
        Student student1 = new Student("张三", "S001", 20, "计算机科学");
        Student student2 = new Student("李四", "S002", 19, "软件工程");
        Student student3 = new Student(); // 使用默认构造器
        
        System.out.println("当前学生总数: " + Student.getTotalStudents());
        System.out.println("学校名称: " + Student.getSchoolName());
        
        // 2. 设置对象状态
        System.out.println("\n=== 录入成绩 ===");
        student1.addScore(0, 85.5); // 数学
        student1.addScore(1, 92.0); // 英语
        student1.addScore(2, 78.5); // 物理
        student1.addScore(3, 88.0); // 化学
        student1.addScore(4, 95.5); // 计算机
        
        student2.addScore(0, 90.0);
        student2.addScore(1, 87.5);
        student2.addScore(2, 82.0);
        student2.addScore(3, 91.5);
        student2.addScore(4, 89.0);
        
        // 3. 调用对象方法
        System.out.println("\n=== 学生信息 ===");
        System.out.println(student1.getStudentInfo());
        System.out.println(student2.getStudentInfo());
        System.out.println(student3.getStudentInfo());
        
        // 4. 使用静态方法比较
        System.out.println("\n=== 成绩比较 ===");
        int comparison = Student.compareByAverage(student1, student2);
        if (comparison > 0) {
            System.out.println(student1.getName() + " 的平均分更高");
        } else if (comparison < 0) {
            System.out.println(student2.getName() + " 的平均分更高");
        } else {
            System.out.println("两人平均分相同");
        }
        
        // 5. 对象比较
        System.out.println("\n=== 对象比较 ===");
        Student student4 = new Student("王五", "S001", 21, "数学"); // 相同学号
        System.out.println("student1.equals(student4): " + student1.equals(student4));
        System.out.println("student1 == student4: " + (student1 == student4));
    }
}

2.3 对象的内存模型

栈内存 (Stack)
方法区 (Method Area)
堆内存 (Heap)
student1 引用
student2 引用
Student类信息
totalStudents: 3
SCHOOL_NAME: 清华大学
方法代码
Student对象1
name: 张三
studentId: S001
age: 20
major: 计算机科学
scores: [85.5, 92.0, ...]
Student对象2
name: 李四
studentId: S002
age: 19
major: 软件工程
scores: [90.0, 87.5, ...]
double数组对象
[85.5, 92.0, 78.5, 88.0, 95.5]
double数组对象
[90.0, 87.5, 82.0, 91.5, 89.0]

3. 消息传递机制

3.1 消息传递的概念

在面向对象编程中,消息传递是对象之间通信的方式。当一个对象需要另一个对象执行某个操作时,它会向目标对象发送一个消息。

消息的组成
消息
接收者
(Receiver)
消息名
(Message Name)
参数
(Parameters)
目标对象
方法名
方法参数

3.2 消息传递的实现

// 消息发送者:银行客户
public class BankCustomer {
    private String name;
    private String customerId;
    
    public BankCustomer(String name, String customerId) {
        this.name = name;
        this.customerId = customerId;
    }
    
    // 发送消息:存款
    public void makeDeposit(BankAccount account, double amount) {
        System.out.println(name + " 向账户发送存款消息");
        // 消息:account.deposit(amount)
        // 接收者:account对象
        // 消息名:deposit
        // 参数:amount
        boolean result = account.deposit(amount);
        
        if (result) {
            System.out.println(name + " 存款成功");
        } else {
            System.out.println(name + " 存款失败");
        }
    }
    
    // 发送消息:取款
    public void makeWithdrawal(BankAccount account, double amount, String password) {
        System.out.println(name + " 向账户发送取款消息");
        // 消息:account.withdraw(amount, password)
        boolean result = account.withdraw(amount, password);
        
        if (result) {
            System.out.println(name + " 取款成功");
        } else {
            System.out.println(name + " 取款失败");
        }
    }
    
    // 发送消息:查询余额
    public void checkBalance(BankAccount account, String password) {
        System.out.println(name + " 向账户发送查询余额消息");
        try {
            // 消息:account.getBalance(password)
            double balance = account.getBalance(password);
            System.out.println(name + " 当前余额: " + balance);
        } catch (SecurityException e) {
            System.out.println(name + " 查询失败: " + e.getMessage());
        }
    }
}

// 消息传递示例
public class MessagePassingDemo {
    public static void main(String[] args) {
        // 创建对象
        BankAccount account = new BankAccount("ACC001", "张三", "123456");
        BankCustomer customer = new BankCustomer("张三", "CUST001");
        
        System.out.println("=== 消息传递演示 ===");
        
        // 客户向账户发送各种消息
        customer.makeDeposit(account, 1000.0);           // 存款消息
        customer.checkBalance(account, "123456");        // 查询消息
        customer.makeWithdrawal(account, 500.0, "123456"); // 取款消息
        customer.checkBalance(account, "123456");        // 再次查询
        customer.makeWithdrawal(account, 600.0, "wrong"); // 错误密码
    }
}

3.3 消息传递的特点

消息传递特点
封装性
异步性
多态性
松耦合
隐藏内部实现
只暴露接口
发送者不等待
支持并发
同一消息不同响应
运行时绑定
发送者不依赖接收者实现
易于维护和扩展

4. 面向对象基本术语

4.1 核心术语表

术语英文定义示例
Class对象的模板或蓝图class Car { ... }
对象Object类的实例Car myCar = new Car();
实例Instance对象的另一种称呼myCar是Car类的一个实例
属性Attribute/Field对象的数据成员private String color;
方法Method对象的行为public void start() { ... }
构造器Constructor创建对象的特殊方法public Car() { ... }
继承Inheritance子类获得父类特性class SportsCar extends Car
重写Override子类重新定义父类方法@Override public void start()
重载Overload同名方法不同参数start()start(boolean)
多态Polymorphism同一接口多种实现Animal a = new Dog();
抽象Abstraction隐藏复杂性,突出本质abstract class Shape
接口Interface行为规范的定义interface Drawable
Package类的命名空间package com.example;

4.2 关系术语

对象关系
继承关系
(is-a)
组合关系
(has-a)
聚合关系
(part-of)
依赖关系
(uses-a)
关联关系
(knows-a)
狗是动物
Dog is-a Animal
汽车有引擎
Car has-a Engine
部门有员工
Department part-of Employee
学生使用图书
Student uses-a Book
老师知道学生
Teacher knows-a Student

4.3 访问控制术语

术语含义作用范围
public公有的所有类都可访问
private私有的仅本类可访问
protected受保护的本类、子类、同包类可访问
default包私有的同包类可访问
static静态的属于类而非实例
final最终的不可修改或继承
abstract抽象的不能实例化,需要子类实现

实践练习

练习1:设计一个图书管理系统

设计并实现一个简单的图书管理系统,要求:

  • 创建Book类,包含书名、作者、ISBN、价格等属性
  • 创建Library类,管理图书集合
  • 实现添加图书、删除图书、查找图书等功能
  • 使用封装原则保护数据
  • 提供合适的构造器和方法
// 请在此处实现你的代码
public class Book {
    // TODO: 实现Book类
}

public class Library {
    // TODO: 实现Library类
}

练习2:继承关系设计

设计一个员工管理系统的继承体系:

  • 创建Employee基类
  • 创建Manager、Developer、Designer子类
  • 每个子类有特有的属性和方法
  • 实现多态的工资计算方法
  • 演示向上转型和向下转型

练习3:多态应用

实现一个绘图系统:

  • 创建Shape抽象类
  • 创建Circle、Rectangle、Triangle子类
  • 实现多态的面积计算和绘制方法
  • 创建一个绘图管理器,统一处理不同形状

常见问题

Q: 什么时候使用继承,什么时候使用组合?
A:

  • 使用继承:当存在明确的"is-a"关系时,如Dog is-a Animal
  • 使用组合:当存在"has-a"关系时,如Car has-a Engine
  • 一般建议优先考虑组合,因为它提供更好的灵活性

Q: 抽象类和接口有什么区别?
A:

  • 抽象类可以有具体方法实现,接口只能有抽象方法(Java 8+支持默认方法)
  • 类只能继承一个抽象类,但可以实现多个接口
  • 抽象类可以有构造器,接口不能
  • 抽象类表示"is-a"关系,接口表示"can-do"关系

Q: 如何理解多态的动态绑定?
A: 动态绑定是指在运行时根据对象的实际类型来决定调用哪个方法,而不是在编译时决定。这使得同一段代码可以处理不同类型的对象,提高了代码的灵活性。

总结

本章节深入讲解了面向对象的四大基本特征:

  • 抽象:忽略无关细节,突出本质特征,是面向对象思维的基础
  • 封装:数据和方法的结合,隐藏内部实现,提供统一接口
  • 继承:代码重用和层次结构的建立,体现"is-a"关系
  • 多态:同一接口的多种实现,提供运行时的灵活性

这四个特征相互关联,共同构成了面向对象编程的理论基础。理解和掌握这些概念对于后续学习面向对象分析设计、UML建模和设计模式都至关重要。

下一步

继续学习:003-类与对象

在下一章节中,我们将更深入地学习类与对象的高级特性,包括静态成员、内部类、对象的生命周期管理等内容。


更新时间: 2024-12-19 | 版本: v1.0.0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值