OOP/OOD练习建议与相关模板(基础类封装模板,必须掌握) 【from 黄老师】
针对Java OOP题目中高频核心场景的通用代码模板(Starter Code),覆盖基础封装、对象排序、继承多态、接口实现、综合系统建模五大核心场景,可根据具体题目需求微调,所有模板均符合Java OOP最佳实践(封装、高内聚低耦合)。
📌 Core OOP Java 知识点覆盖
这些题目重点练习以下 Java OOP 核心概念:
- 封装 Encapsulation:类设计、隐藏内部细节
- 继承 Inheritance:父类与子类关系、
extends - 多态 Polymorphism:父类/接口引用指向子类对象
- 接口 Interface:自定义接口 +
implements - 抽象 Abstract:抽象类 + 抽象方法设计
- Comparable/Comparator:排序与比较机制实现
1. 基础类封装模板(适配入门级题目:P5740/P5741/P5742/P1001等)
适用场景
定义实体类(如学生、苹果、金币等),封装属性和行为,实现基础的对象创建、属性访问、业务逻辑计算。
import java.util.Scanner;
// 以P5740【最厉害的学生】为例:封装Student类
public class Main {
// 1. 实体类:私有属性 + 构造方法 + getter/setter + 业务方法
static class Student {
// 私有属性(封装核心:隐藏内部状态)
private String name;
private int chinese;
private int math;
private int english;
// 构造方法:初始化对象
public Student(String name, int chinese, int math, int english) {
this.name = name;
this.chinese = chinese;
this.math = math;
this.english = english;
}
// 业务方法:封装计算逻辑(高内聚)
public int getTotalScore() {
return chinese + math + english;
}
// Getter方法:对外提供属性访问(可控)
public String getName() {
return name;
}
// 可选:重写toString,方便调试输出
@Override
public String toString() {
return name + " " + chinese + " " + math + " " + english + " 总分:" + getTotalScore();
}
}
// 主方法:程序入口,处理输入输出 + 调用对象方法
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.nextLine(); // 吸收换行符
Student topStudent = null;
int maxScore = 0;
// 创建多个对象并遍历
for (int i = 0; i < n; i++) {
String[] info = sc.nextLine().split(" ");
String name = info[0];
int chinese = Integer.parseInt(info[1]);
int math = Integer.parseInt(info[2]);
int english = Integer.parseInt(info[3]);
Student s = new Student(name, chinese, math, english);
int total = s.getTotalScore();
// 对象比较逻辑
if (total > maxScore) {
maxScore = total;
topStudent = s;
}
}
// 输出结果
System.out.println(topStudent);
sc.close();
}
}
2. Comparable/Comparator 排序模板(适配普及级题目:P1068/P1093/P1104/P1567等)
适用场景
需要对自定义对象进行排序(单/多关键字排序),如奖学金排名、考生分数线划定、生日排序等。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
// 以P1093【奖学金】为例:多关键字排序
public class Main {
// 1. 定义实体类(实现Comparable接口:自然排序)
static class Student implements Comparable<Student> {
private int id; // 学号
private int chinese;
private int math;
private int english;
private int total;
public Student(int id, int chinese, int math, int english) {
this.id = id;
this.chinese = chinese;
this.math = math;
this.english = english;
this.total = chinese + math + english;
}
// 核心:重写compareTo,定义排序规则
// 规则:总分降序 → 语文降序 → 学号升序
@Override
public int compareTo(Student o) {
if (this.total != o.total) {
return o.total - this.total; // 降序:用o - this
}
if (this.chinese != o.chinese) {
return o.chinese - this.chinese;
}
return this.id - o.id; // 升序:this - o
}
// Getter + toString
public int getId() {
return id;
}
@Override
public String toString() {
return id + " " + total;
}
}
// 2. 可选:Comparator接口(自定义排序,灵活度更高)
static class StudentComparator implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
// 可定义与自然排序不同的规则
return s1.getId() - s2.getId();
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
ArrayList<Student> list = new ArrayList<>();
// 初始化对象列表
for (int i = 0; i < n; i++) {
int id = i + 1; // 假设学号从1开始
int chinese = sc.nextInt();
int math = sc.nextInt();
int english = sc.nextInt();
list.add(new Student(id, chinese, math, english));
}
// 排序方式1:使用Comparable自然排序
Collections.sort(list);
// 排序方式2:使用Comparator自定义排序(按需选择)
// Collections.sort(list, new StudentComparator());
// 输出结果
for (Student s : list) {
System.out.println(s);
}
sc.close();
}
}
3. 继承与多态模板(适配提高级题目:P1551/P1957/P2482等)
适用场景
需要抽象公共属性/行为,通过继承复用代码,通过多态实现不同子类的差异化行为(如猪国杀的角色、口算练习题的运算类型)。
import java.util.Scanner;
// 以P2482【猪国杀】简化版为例:角色继承 + 多态
public class Main {
// 1. 父类:抽象公共属性和行为
static abstract class Role {
protected String name; // 角色名
protected int hp; // 血量
public Role(String name, int hp) {
this.name = name;
this.hp = hp;
}
// 抽象方法:子类必须实现(多态核心)
public abstract void skill(Role target);
// 通用方法:所有子类复用
public void hurt(int damage) {
this.hp -= damage;
System.out.println(name + "受到" + damage + "点伤害,剩余血量:" + hp);
}
// Getter
public String getName() {
return name;
}
public int getHp() {
return hp;
}
}
// 2. 子类1:主公(重写抽象方法)
static class Lord extends Role {
public Lord() {
super("主公", 10); // 调用父类构造
}
@Override
public void skill(Role target) {
System.out.println(name + "对" + target.getName() + "使用主公技能,造成2点伤害");
target.hurt(2);
}
}
// 3. 子类2:反贼(重写抽象方法)
static class Rebel extends Role {
public Rebel() {
super("反贼", 8);
}
@Override
public void skill(Role target) {
System.out.println(name + "对" + target.getName() + "使用反贼技能,造成1点伤害");
target.hurt(1);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 多态:父类引用指向子类对象
Role lord = new Lord();
Role rebel = new Rebel();
// 调用子类的skill方法(运行时多态)
lord.skill(rebel);
rebel.skill(lord);
sc.close();
}
}
4. 接口实现模板(适配提高级题目:P2089/P3367/P3370等)
适用场景
需要定义行为规范,让不同类实现同一接口(如烤鸡的配方计算、并查集的操作、字符串哈希策略)。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
// 以P2089【烤鸡】为例:接口定义配方计算规则
public class Main {
// 1. 定义接口:规范行为
interface RecipeCalculator {
// 计算n克调料的所有配方组合
List<List<Integer>> calculate(int n);
}
// 2. 实现接口:具体的配方计算逻辑
static class ChickenRecipe implements RecipeCalculator {
private static final int MAX_PER_SPOON = 3; // 每勺最多3克
private List<List<Integer>> result;
@Override
public List<List<Integer>> calculate(int n) {
result = new ArrayList<>();
backtrack(n, new ArrayList<>(), 0);
return result;
}
// 回溯算法(封装在实现类内部,对外隐藏细节)
private void backtrack(int remain, List<Integer> path, int count) {
if (count == 10) { // 固定10勺
if (remain == 0) {
result.add(new ArrayList<>(path));
}
return;
}
for (int i = 1; i <= MAX_PER_SPOON; i++) {
if (i > remain) break;
path.add(i);
backtrack(remain - i, path, count + 1);
path.remove(path.size() - 1);
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 总克数
// 面向接口编程:依赖接口而非具体实现
RecipeCalculator calculator = new ChickenRecipe();
List<List<Integer>> recipes = calculator.calculate(n);
// 输出结果
System.out.println(recipes.size());
for (List<Integer> recipe : recipes) {
for (int num : recipe) {
System.out.print(num + " ");
}
System.out.println();
}
sc.close();
}
}
5. 综合系统建模模板(适配省选级题目:P1563/P2482/P2586等)
适用场景
复杂系统模拟(如玩具谜题、杀蚂蚁、猪国杀),需拆分多个类协作,封装状态和行为,降低耦合。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
// 以P1563【玩具谜题】为例:多类协作建模
public class Main {
// 1. 玩具人类:封装状态和行为
static class Toy {
private String job; // 职业
private int direction; // 朝向:0=内,1=外
public Toy(String job, int direction) {
this.job = job;
this.direction = direction;
}
// 根据朝向和步数计算下一个位置
public int getNextIndex(int currentIdx, int step, int total) {
if (direction == 0) { // 朝内:左数(索引减)
return (currentIdx - step + total) % total;
} else { // 朝外:右数(索引加)
return (currentIdx + step) % total;
}
}
public String getJob() {
return job;
}
}
// 2. 游戏类:封装游戏逻辑(高内聚)
static class ToyPuzzleGame {
private List<Toy> toys;
private int currentIdx; // 当前选中的玩具索引
public ToyPuzzleGame(List<Toy> toys) {
this.toys = toys;
this.currentIdx = 0; // 初始位置
}
// 执行一次操作
public void executeOperation(int step) {
Toy currentToy = toys.get(currentIdx);
currentIdx = currentToy.getNextIndex(currentIdx, step, toys.size());
}
// 获取当前结果
public String getCurrentJob() {
return toys.get(currentIdx).getJob();
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 玩具数量
int m = sc.nextInt(); // 操作次数
// 初始化玩具列表
List<Toy> toys = new ArrayList<>();
for (int i = 0; i < n; i++) {
int dir = sc.nextInt();
String job = sc.next();
toys.add(new Toy(job, dir));
}
// 创建游戏对象,执行操作
ToyPuzzleGame game = new ToyPuzzleGame(toys);
for (int i = 0; i < m; i++) {
int dir = sc.nextInt();
int step = sc.nextInt();
game.executeOperation(step);
}
// 输出结果
System.out.println(game.getCurrentJob());
sc.close();
}
}
总结
- 模板核心原则:所有模板均遵循「封装(私有属性+公共方法)、高内聚(业务逻辑封装在类内部)、低耦合(类间通过接口/方法调用交互)」,符合Java OOP最佳实践。
- 使用技巧:
- 入门题优先用「基础类封装模板」,聚焦属性和方法封装;
- 排序题优先用「Comparable/Comparator模板」,注意多关键字排序的规则定义;
- 提高/省选题根据场景选择「继承多态」或「接口实现」模板,复杂系统用「综合建模模板」拆分类。
- 通用调整点:根据具体题目修改实体类的属性、业务方法的逻辑、排序规则或接口实现细节,主方法的输入输出逻辑可复用模板结构。

浙公网安备 33010602011771号