封装 · 继承 · 多态¶
面向对象三件套。前端人写过 JS class/extends,这里主要理解 Java 的访问控制和强类型多态。
封装:private + getter/setter¶
class Account {
private int balance; // private:外部不能直接 balance = -50
public int getBalance() { return balance; } // getter
public void deposit(int amount) { // setter 里做校验
if (amount <= 0) return;
this.balance += amount;
}
}
封装的价值:把"如何修改 balance"的规则收进类内部,外部只能通过受控的方法访问。JS 没有真正的 private(# 私有字段是新特性),Java 的 private 是编译期强制的。
继承:extends + super¶
- Java 只能单继承(不像 Python 多继承)。要"多继承"的能力用接口(第 09 章)。
super调用父类的构造器/方法,对标 JS 的super。
多态:父类引用指向子类对象¶
Animal[] zoo = {new Dog(), new Cat()};
for (Animal a : zoo) {
a.speak(); // Dog 打印"汪汪",Cat 打印"喵喵"——运行时决定
}
这是后端最常用的模式:方法参数声明为父类型,能接收任何子类。Spring 里你会大量看到这种"面向接口/父类编程"。
@Override 是干什么的¶
加了 @Override,如果你拼错了方法名(比如写成 speek),编译器立刻报错——它发现父类没有这个方法可重写。不加的话,你以为是重写,其实是新方法,bug 很难查。重写一律加 @Override。
instanceof 与强转¶
Animal a = new Dog();
if (a instanceof Dog) {
Dog d = (Dog) a; // 向下转型(强转)后才能调用 Dog 专属方法
d.bark();
}
完整可运行示例¶
package com.javaglm.language.ch08;
/**
* 第 08 章 · 封装、继承、多态。
* 封装:private 字段 + getter/setter,外部不能乱改。
* 继承:extends 单继承,super 调父类。
* 多态:父类引用指向子类对象,调用的是子类重写后的方法。
*/
public class PolyDemo {
public static void main(String[] args) {
// === 封装 ===
Account acc = new Account("Tom");
acc.deposit(100);
// acc.balance = -50; // ✗ 编译报错!balance 是 private,外部不能直接改
acc.deposit(-30); // 被 setter 里的校验拦下,余额不变
System.out.println(acc.getName() + " 余额 = " + acc.getBalance()); // 100
// === 多态:父类引用指向子类对象 ===
Animal[] zoo = {new Dog(), new Cat()};
for (Animal a : zoo) {
a.speak(); // 运行时根据实际类型,调用各自重写的方法
}
// === instanceof:判断真实类型(对标 JS 的 instanceof)===
Animal a = new Dog();
if (a instanceof Dog) {
Dog d = (Dog) a; // 向下转型(强转)
d.bark();
}
}
}
// ===================== 封装 =====================
class Account {
private String name;
private int balance; // private:外部不可直接访问
Account(String name) {
this.name = name;
}
// getter:只读访问
public String getName() { return name; }
public int getBalance() { return balance; }
// setter 里做校验,这是"封装"的核心价值
public void deposit(int amount) {
if (amount <= 0) {
System.out.println("金额必须为正,忽略:" + amount);
return;
}
this.balance += amount;
}
}
// ===================== 继承 + 多态 =====================
class Animal {
public void speak() {
System.out.println("...");
}
}
class Dog extends Animal { // extends 单继承
@Override // 重写标记(编译器帮你检查签名是否真的覆盖了父类方法)
public void speak() {
System.out.println("汪汪!");
}
public void bark() {
System.out.println("Dog 专属方法");
}
}
class Cat extends Animal {
@Override
public void speak() {
System.out.println("喵喵!");
}
}
前端人对照¶
| JS | Java | 备注 |
|---|---|---|
class Dog extends Animal |
同 | Java 单继承 |
super.speak() |
同 | 调父类 |
无真正私有(# 除外) |
private 编译强制 |
封装更强 |
obj instanceof Cls |
同 | 判断类型 |
| 无重写标记 | @Override |
防拼错,必加 |
:octicons-arrow-left-16: 上一章:面向对象基础 | 下一章:接口与抽象类