面向对象
三大特性
封装
将数据和行为包裹在类中,通过访问修饰符控制外部可见性,隐藏内部实现细节。
public class BankAccount {
private double balance; // 外部不可直接访问
public void deposit(double amount) {
if (amount > 0) balance += amount;
}
public double getBalance() {
return balance;
}
}访问修饰符作用范围:
| 修饰符 | 同类 | 同包 | 子类 | 其他包 |
|---|---|---|---|---|
private | ✓ | ✗ | ✗ | ✗ |
(default) | ✓ | ✓ | ✗ | ✗ |
protected | ✓ | ✓ | ✓ | ✗ |
public | ✓ | ✓ | ✓ | ✓ |
继承
子类复用父类的属性和方法,用 extends 关键字实现。Java 只支持单继承,但可多层继承。
public class Animal {
protected String name;
public void eat() {
System.out.println(name + " is eating");
}
}
public class Dog extends Animal {
public void bark() {
System.out.println(name + " is barking");
}
}super引用父类成员或调用父类构造器- 子类构造器默认调用父类无参构造器(
super()),若父类无无参构造器则必须显式调用 final类不可被继承,final方法不可被重写
多态
同一接口对不同实现的统一调用,分为编译时多态(重载)和运行时多态(重写 + 向上转型)。
Animal a = new Dog(); // 向上转型
a.eat(); // 运行时绑定到 Dog 的 eat()(若 Dog 重写了)
// 向下转型需先判断
if (a instanceof Dog d) { // Java 16+ 模式匹配
d.bark();
}重写 vs 重载
| 对比 | 重写(Override) | 重载(Overload) |
|---|---|---|
| 位置 | 子类与父类之间 | 同一个类中 |
| 方法名 | 相同 | 相同 |
| 参数列表 | 相同 | 不同 |
| 返回类型 | 相同或协变(子类) | 无要求 |
| 访问权限 | 不能更严格 | 无要求 |
| 异常 | 不能抛出更宽泛的受检异常 | 无要求 |
| 绑定时机 | 运行时(动态绑定) | 编译时(静态绑定) |
// 重写
@Override
public String toString() { return "Dog: " + name; }
// 重载
public void print(int x) {}
public void print(String s) {}
public void print(int x, int y) {}类的组成
public class Person {
// 静态变量(类变量)
private static int count = 0;
// 实例变量
private String name;
private int age;
// 静态初始化块(类加载时执行一次)
static {
System.out.println("类加载");
}
// 实例初始化块(每次创建对象时执行,早于构造器)
{
count++;
}
// 构造器
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 实例方法
public String getName() { return name; }
// 静态方法(不能访问实例变量)
public static int getCount() { return count; }
}Object 类核心方法
所有类都隐式继承 Object,常用方法:
| 方法 | 说明 |
|---|---|
equals(Object) | 默认比较引用,通常需重写为值比较 |
hashCode() | 重写 equals 时必须同步重写 |
toString() | 默认返回 类名@十六进制哈希值 |
clone() | 浅拷贝,需实现 Cloneable 接口 |
getClass() | 返回运行时类型 |
finalize() | 已废弃,不推荐使用 |
equals 与 hashCode 契约:若 a.equals(b) 为 true,则 a.hashCode() == b.hashCode() 必须成立。
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person p)) return false;
return age == p.age && Objects.equals(name, p.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}内部类
| 类型 | 声明位置 | 能否访问外部类成员 | 说明 |
|---|---|---|---|
| 成员内部类 | 类体内 | 可以(包括 private) | 需先创建外部类实例 |
| 静态内部类 | 类体内(static) | 只能访问静态成员 | 可独立实例化 |
| 局部内部类 | 方法内 | 可以 | 作用域限于方法 |
| 匿名内部类 | 表达式中 | 可以 | 无类名,常替代为 Lambda |
// 匿名内部类(常见于回调)
Runnable r = new Runnable() {
@Override
public void run() { System.out.println("run"); }
};
// 等价 Lambda
Runnable r2 = () -> System.out.println("run");关键字
this
- 指向当前对象的引用
- 构造器中
this(...)调用同类其他构造器,必须是第一条语句
static
- 静态成员属于类,而非实例
- 静态方法中不能使用
this、super或访问实例成员 - 静态变量在类加载时初始化,只有一份内存
final
- final 变量:只能赋值一次(基本类型值不可变;引用类型引用不可变,但对象内容可变)
- final 方法:不可被重写
- final 类:不可被继承(如
String、Integer)