1. 项目概述:day16这道坎到底在练什么
说实话,很多自学编程的人都会在某个学习阶段遇到一个转折点——语法书翻了好几遍,视频也看了不少,小练习都会做,但一碰到稍微综合一点的需求就卡壳。如果你正处在这样的阶段,那么day16-面向对象综合练习(上)这一课就是为你准备的。
这一天的内容,本质上是把之前零零散散学过的类与对象、构造方法、封装、继承、多态、抽象类与接口等面向对象核心概念,放进一个相对完整的场景里去做串联和落地。它不是单纯地让你再敲一遍某个知识点的示例代码,而是要你像一个真正的开发者那样,从需求分析、类结构设计、代码实现到测试验证,完整地走一遍面向对象的开发流程。
先说清楚一个容易让人迷惑的地方:为什么叫“综合练习(上)”?这意味着练习内容和配套的知识点在一个系列里被拆成了两段,前半段重点搞定类设计、封装、继承这三个基础基石,后半段才上多态、抽象类和接口这些偏“进阶”的特性。也就是说,如果你练完今天的内容,至少应该能独立设计出一个多类协作的小型程序结构,并清楚每个类该放什么字段、什么方法,以及类与类之间的继承关系怎么组织。
这篇文章适合谁?适合那种已经学完Java/C++/Python基础语法、正在面向对象门口徘徊的初学者,也适合那些上过一遍课但缺乏综合训练、想通过实际案例巩固OOP思想的同学。我会用真实的练习案例、三语言对比的写法思路,以及我自己当年踩过的坑,把这节课的内容拆透了讲。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 练习背后的设计思路:为什么面向对象必须靠“做题”才能学会
2.1 从“能看懂”到“会设计”的鸿沟
先问一个问题:你读代码的能力和写代码的能力是一回事吗?绝大多数初学者都会发现,读别人写的面向对象代码,好像每个关键字、每个语法都认识,合上书让自己从零开始设计一个系统,大脑就一片空白。这不是你笨,而是“理解”和“设计”之间本来就有巨大的鸿沟。
举个例子,你在书上看到public class Cat extends Animal,你觉得懂了——Cat是Animal的子类。但是当需求变成“有猫有狗有鸟,它们都会叫,但叫声不同,有的还会飞、会游泳”时,你的第一反应是什么呢?很多人的第一反应是:给每个动物都写一个类,然后每个类里都写一个makeSound()方法。运行起来没问题,但代码大量重复,想要新增一种动物就要复制粘贴一整套方法,改一个逻辑就要到处改。
面向对象的综合练习,本质上就是强迫你面对这类问题。它不会直接告诉你“请用继承和多态来实现”,而是抛出一个带着业务气息的需求,让你自己去判断:哪些东西是公共的,应该抽成父类?哪些行为是变化的,应该被子类重写?哪些能力是某些对象独有的,应该用接口来约束?这种设计判断力,就是靠一道道综合练习练出来的。
2.2 综合练习的经典套路:从需求中提炼类
我做这类型项目有一个经验:碰到综合练习,永远不要上来就写代码。哪怕脑子里已经有了大概的方案,也要先走一遍“需求分析 → 找名词 → 定类 → 画关系”的流程。学校里的练习题目通常不会太复杂,但核心逻辑和大厂面试的手写题、实际工作中的模块设计,基本是一个套路。
以常见的学生管理系统、图书管理系统、游戏角色系统为例,我们可以把一套标准方法的步骤拆成四步:
- 找名词。把题目里出现的所有“人”“物”“概念”圈出来。比如“学生”“老师”“课程”“成绩”“班级”,这些名词大概率就是你要设计的类。
- 找动词。名词旁边跟着的动作,就是方法。例如“学生选课”“老师录入成绩”“课程显示信息”,这些动作决定了类中要定义什么行为。
- 找形容词/归属关系。比如“研究生是一种学生”“讲师是一种老师”“课程有学分、有编号”,这些关系和属性决定了类与类之间的继承关系、字段类型。
- 区分“是什么”和“有什么”。A是B的一种,用继承;A拥有B,用组合。也就是
is-a关系用继承,has-a关系用字段引用,这个判断往往就是面向对象设计里最难的一步。
为什么很多人练习做不对?大多数情况不是语法问题,而是一上来就写public class Student,写着写着发现“研究生”和“本科生”很多代码重复,才回来补继承,最后整个类的关系变得一团糟。面向对象是设计先行的事情,动手之前花十分钟画图整理,省下来的可能是几小时的重构时间。
2.3 练习案例的选择逻辑:大学管理系统可能是最合适的第一道题
day16的练习题很多教材会选“学生/教师/课程”这类主题,原因只有两个字:熟悉。你天天在校园里生活,不需要额外的行业背景知识就能理解需求,能把全部注意力放在OOP的设计和实现上。这也顺便说明了一个道理:练习难度应该体现在设计思考上,而不是业务背景上。
我后面展开的案例也遵循这个原则。做一个带继承关系的校园角色信息管理系统,包含普通学生、研究生、教师三种角色,每个角色都有基本信息展示和各自的独有操作,同时提供一个统一的测试入口。这个系统麻雀虽小,但足够覆盖day16上半段练习的核心知识点:类与对象、构造方法重载、封装(private字段 + getter/setter)、静态成员、继承(父类子类、super调用)、方法重写。更重要的是,你能在一道题里同时看到这些知识是怎么协同工作的,而不是像之前学语法那样,一个知识点配一道独立的小题。
3. 核心案例实操:构建校园角色管理系统的完整过程
3.1 需求明细与类结构设计
这里我们先把具体需求定下来。假设题目要求实现一个校园角色信息管理系统,需要支持三种角色:普通学生、研究生、教师。所有角色都有姓名、年龄和自我介绍的功能;学生需要显示学号和所在班级;研究生的显示除了学号、班级之外,还需要导师姓名和研究方向;教师需要显示工号和所授课程。
这样一个需求你拿到的第一眼可能觉得毫无头绪。没关系,按照老规矩走一遍。找出所有名词:学生、研究生、教师、姓名、年龄、学号、班级、导师、研究方向、工号、课程。再找动词:自我介绍、显示信息。最后梳理一下关系:研究生是一种特殊的学生,所以研究生继承学生类;学生和教师都是校园成员,抽一个公共父类Person最合理。关系图和类职责就这样确定下来了。
这里我给出一个类结构设计的经典模板,字段名和方法名用英文,方便你对照代码:
| 类名 | 类型 | 关键字段 | 核心方法 |
|---|---|---|---|
| Person | 父类 | name, age | introduce() |
| Student | 子类(继承Person) | studentId, className | introduce(), study() |
| GraduateStudent | 子类(继承Student) | supervisor, researchField | introduce(), research() |
| Teacher | 子类(继承Person) | teacherId, course | introduce(), teach() |
注意一个细节:GraduateStudent首先是一个Student,它继承了学号和班级,同时加了导师和研究方向两
