Java面向对象编程的基本语法规则

Java面向对象编程关键在理解封装、协作与语义规则:类名须与public类文件名严格一致;this用于解决变量冲突和构造器调用,不可用于静态上下文;extends建立类型关系但受private/final限制;implements要求实现接口所有抽象方法且必须为public。

Java面向对象编程不是靠背语法规则写出来的,而是靠理解「类如何封装行为与状态」「对象怎么协作」来落地的。死记classpublicthis这些关键字没用,关键在什么时候必须用、不用会出什么错。

类定义必须用 class,且文件名要和 public 类名严格一致

Java 编译器强制要求:如果一个源文件里有 public 类,文件名必须和该类名完全相同(包括大小写),否则报错 error: class XXX is public, should be declared in a file named XXX.java

常见错误场景:

  • 新建了 Student.java,但里面写了 public class student { ... }(小写 s)→ 编译失败
  • 一个文件里定义了两个 public 类 → 编译失败(只能有一个,且必须匹配文件名)
  • 想把多个辅助类(如 AddressGrade)全塞进 Main.java → 只能有一个 public class Main,其余类必须不加 public

this 不是可选修饰符,而是解决变量名冲突和构造器调用的关键工具

this 在方法或构造器里出现,通常就两类用途:一

是区分形参和成员变量,二是调用本类其他构造器(必须是第一行)。漏掉或乱用会导致逻辑错或编译报错。

典型误用:

  • 在 setter 里写 name = name; → 实际赋值的是参数自己,成员变量没变;正确写法是 this.name = name;
  • 想用 this(...) 调用另一个构造器,但没放在第一行 → 编译错误 call to this must be first statement in constructor
  • 在静态方法(如 static void print())里用 this → 编译错误 non-static variable this cannot be referenced from a static context

继承用 extends,但子类不能访问父类 private 成员,也不能重写 final 方法

Java 的继承不是“复制代码”,而是建立类型关系 + 成员可见性控制。很多初学者以为 extends 后就能直接用父类所有东西,结果发现 private 字段/方法根本看不到,或者 final void close() 死活重写不了。

要点说明:

  • private 成员对子类不可见,哪怕同包也不行;要用 protected 或包级(默认)访问控制才可能被继承使用
  • final 方法禁止重写,强行写同签名方法 → 编译错误 cannot override final method
  • 构造器不会被继承,子类必须显式调用 super(...)(或隐式调用无参 super()),否则编译器自动插一句,但如果父类没无参构造器就会报错 constructor Parent() is not defined

接口实现用 implements,所有方法默认 public abstract,实现类必须全部覆写(除非是 defaultstatic

接口不是“模板类”,它只定义契约。Java 8+ 允许 defaultstatic 方法,但普通抽象方法仍强制实现——这点常被忽略,导致编译通不过。

常见陷阱:

  • 实现接口时漏写某个方法 → 编译错误 class XXX must either be declared abstract or implement abstract method YYY
  • 在实现类里把接口方法写成 private void doWork() → 编译错误,接口方法默认 public,实现也必须是 public
  • 误以为 default 方法可以被子类“继承并覆盖”就完事了,结果发现父类也实现了同一接口,而 JVM 选择的是最具体实现类里的版本,不是按继承链找的

真正卡住人的从来不是语法能不能写出来,而是「为什么这里必须加 public」「为什么 this 不能出现在静态上下文」「为什么明明写了 extends 却访问不到父类字段」——这些问题的答案不在语法手册里,在字节码加载规则、访问控制语义和 JVM 类型检查机制中。