Java 面向对象 · 交互课程

OOP 概述与抽象

OOP 概述与抽象

目标:理解面向机器 → 面向过程 → 面向对象三种范式的演进;掌握类、对象、属性、方法、封装、继承、多态七个基本概念;会用「抽象」把现实实体映射为类(属性 + 方法);理解 new 之后堆与栈上各存什么。

一、三种编程范式

程序的本质是「用机器处理数据」。不同范式回答「数据放哪、怎么算」的方式不同:

范式组织方式数据保护生活类比
面向机器直接管地址与指令,门槛高、易错无——谁都能改内存大通铺:十几人挤一间,丢东西常见
面向过程拆成函数/模块,顺序执行;模块间共享全局数据弱——数据对其他模块完全开放,被误改难排查4 人间:比通铺好,但室友互取物品难免
面向对象拆成对象,数据与操作封装在一起,事件触发、可多线程协作强——对外只暴露受控接口每人单间:生活学习互不干扰

面向对象不只是语法,更是一种「以对象协作响应事件」的组织方式,天然适配 GUI、网络、并发等现代场景。

二、七个基本概念

概念含义
对象 Object现实事物的抽象映射:具体属性 + 行为
类 Class同类事物共同特性(属性、行为)的抽象;对象的模板
属性 Field对象的状态/数据(成员变量)
方法 Method对象的行为/操作
封装 Encapsulation数据与方法捆绑在对象内部,隐藏实现细节、只暴露受控接口
继承 Inheritance子类复用父类的属性与方法(extends)
多态 Polymorphism同一接口、不同实现,运行时按实际对象分派

现实世界 ↔ 程序世界:

现实世界程序世界
具体事物的属性及行为对象
同类事物共同特性(属性、行为)的抽象类

三、抽象:从具体到类

「抽象」不是术语,是日常思维的延伸——说「这是一把凳子」本身就是在分类。

贯穿示例(ERASE):游戏里棋盘是一个对象(属性:行×列的格子矩阵;行为:放置/消除方块),每个落下的方块也是对象(属性:形状、颜色、位置;行为:下落、旋转)。整个游戏就是「对象协作响应事件」——键盘事件触发方块移动,碰撞事件触发行消除。

交互实验:抽象建模器(AbstractionModeler)

从真实世界「抽象」出类:给每个候选项判定它是属性(名词)、行为(动词)还是与对象无关, 右侧类骨架代码实时生成。判错的项会标红提醒。

候选项(点选判定)

  • 姓名
  • 学号
  • 选课(selectCourse)
  • 交学费(payTuition)
  • 查成绩(getGrade)
  • 教室的座位号
  • 今天星期几

抽象结果(实时生成)

public class Student {
}

还没有判定任何候选项——先点左边的按钮试试。

关系判断:is-a(继承)还是 has-a(组合)?

「A 是一种 B」→ is-a → extends;「A 有一个 B」→ has-a → 字段引用。点选你的判断,对照参考答案。

Student(学生) ? Person(人)class Student extends Person {}
Car(汽车) ? Engine(发动机)class Car { Engine engine; }
Order(订单) ? Item(商品项)class Order { Item[] items; }
Dog(狗) ? Animal(动物)class Dog extends Animal {}

四、案例:模拟服务大厅

把现实实体抽象为类(每类的属性与方法):

现实实体类主要属性主要方法
顾客Customer姓名、排队号取号、叫到就办理
客服Clerk工号、窗口号叫号、办理业务
取号机TicketMachine当前号码出票(号码 +1)
号票Ticket号码、时间显示号码
坐椅Chair位置可坐/空着
服务大厅ServiceHall顾客列表、客服列表开号、叫下一位

五、类的定义与对象的创建

package com.zmofun.erase.protogame;   // 包:组织类、避免命名冲突、控制访问

class Dog {
    String name;      // 属性
    int age;          // 属性

    Dog(String name, int age) {        // 构造方法:与类同名、无返回类型,初始化对象
        this.name = name;
        this.age = age;
    }

    void bark() {                      // 方法
        System.out.println(name + " says: woof!");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog d = new Dog("Fido", 3);   // new:堆上建对象,d 存的是引用
        d.bark();
    }
}

交互实验:对象内存地图(ObjectMemoryMap)

逐步执行 Dog d = new Dog("Fido", 3);:对象在堆上,局部变量在栈上存的是引用(地址)。

栈(Stack)

(空)

堆(Heap)

(空)
0 / 3

点「▶ 下一步」开始执行 new。

关键区别:d 里存的不是对象本身,而是堆上对象的地址——所以「两个引用指向同一对象」是可能的。

思考题

  1. 用「抽象」的眼光观察你的宿舍或教室:各举 1 个「现实实体 → 类(属性 + 方法)」的例子,写出类名、2 个以上属性和 1 个以上方法。
  2. 仿照「模拟服务大厅」,为图书馆借书场景列出至少 4 个类(如 Book、Reader、Librarian、LoanRecord),各写主要属性与方法。
  3. 结合「大通铺 / 4 人间 / 单间」类比,说明面向对象的「封装」解决了面向过程的什么问题?

学习小测验

学习小测验

Q1

下列不属于面向对象核心概念的是( )

Q2

Dog d = new Dog(); 中,变量 d 里存的是( )

Q3

「模拟服务大厅」案例中,Customer 类的主要属性可能是( )

Q4

构造方法的特征是( )

Q5

package 声明的主要作用不包括( )

Q6

类与对象的关系最准确的描述是( )