Java类是按需提取特征与行为的契约设计,类名应为名词性现实概念,属性须为业务所需状态,方法体现职责归属,继承表达“是一种”、接口表达“能做什么”,抽象需经需求迭代验证。

Java 中的类不是对现实事物的“拍照式”复刻,而是按需提取特征与行为的契约设计——它只保留当前业务场景里真正要操作、要区分、要约束的部分。
类名和属性如何对应现实概念
类名应是名词性、可数、有明确边界的现实角色或事物,比如 Order、PaymentMethod、DeliveryTruck;而属性必须是该角色在当前系统中“需要被记住”的状态,且能用基础类型或已有类表达。例如 Order 类里放 orderDate、status、customerName 合理,但放“客户早餐吃了什么”就不合理——除非你在做营养追踪系统。
常见错误是把数据库字段直接拖成属性,比如加一个 createdAt 和 updatedAt 进业务类,结果发现它们只用于审计、不参与任何业务逻辑,反而干扰了领域表达。
- 属性命名优先用业务语言,如
isPaid比paymentStatusFlag更直白 - 避免冗余属性:不要同时存
totalAmount和itemList再加一个calculateTotal(),三者语义冲突 - 敏感信息(如身份证号、银行卡号)不该以明文
String形式作为公开属性,应封装或脱敏
方法设计体现的是“谁该做什么”
方法不是功能清单,而是职责归属声明。现实里“订单可以取消”“支付可以退款”“卡车可以调度”,这些动词落到类上,就是 Order.cancel()、Payment.refund()、DeliveryTruck.assignDriver()。关键在主语——动作的发起者和承担者是否自然。
立即学习“Java免费学习笔记(深入)”;
容易踩的坑是把方法写成工具函数风格:OrderUtils.calculateDiscount(order),这等于把本该属于 Order 的定价逻辑外移,破坏了封装,也让折扣规则散落在各处。
- 方法名用动词开头,且主语隐含在调用对象中,如
user.activate()而非activateUser(user) - 返回值应反映行为结果:状态变更类方法通常返回
boolean或this(支持流式调用),计算类方法返回具体值 - 避免长参数列表,尤其是多个原始类型堆砌,如
createOrder(String, String, BigDecimal, int, boolean)—— 应封装为OrderRequest对象
继承与接口:抽象的是“是什么”还是“能做什么”
用 extends 表达“是一种”,必须满足里氏替换原则:所有子类对象能无缝替代父类出现的位置。比如 ElectricCar extends Vehicle 成立,但 Rectangle extends Square 不成立——因为正方形不能随意修改宽高而不破坏约束。
而 implements 表达“能做什么”,关注能力契约。现实中“能扫码”“能打印”“能投递”都是独立能力,对应 Scannable、Printable、Deliverable 接口,一个 SelfServiceKiosk 可以同时实现三者,无需强行塞进某个继承链。
- 优先用接口组合而非继承扩展行为,更灵活也更贴近现实中的多重角色
- 抽象类适合提供共用状态+部分默认实现,比如
AbstractPayment含通用transactionId和基础validate(),但不强制子类必须用某种加密方式 - 别为了“看起来像现实”而建继承树,比如为“猫”“狗”“鸟”建
Animal父类,结果发现系统里根本不用“动物”这个泛化概念做任何判断或处理
抽象最难的部分,往往不是语法怎么写,而是反复问自己:“这个字段/方法/关系,在接下来三个月的需求迭代里,会被哪个角色基于什么理由去读、去改、去依赖?”——答案模糊的地方,就是抽象还没落到位的地方。









