承接第一课的基础语法,本节课正式进入 Java 的核心------面向对象编程(OOP)。掌握这些,你就拿到了 Java 世界的入场券。
- 什么是面向对象(OOP)?
面向对象 是一种编程思想,它将现实世界中的事物抽象为对象,通过对象之间的交互来设计程序。Java 正是纯面向对象的语言。
· 类(Class):对象的蓝图/模板,定义了对象拥有的属性(变量)和行为(方法)。 · 对象(Object):根据类创建出来的具体实例,占用内存。
java
// 定义一个类
public class Student {
// 属性(成员变量)
String name;
int age;
// 行为(方法)
public void study() {
System.out.println(name + " 正在学习...");
}
}
// 使用类创建对象
public class Main {
public static void main(String[] args) {
Student s1 = new Student(); // 创建对象
s1.name = "小明";
s1.age = 18;
s1.study(); // 输出:小明 正在学习...
}
}
三大特性:封装、继承、多态 ------ 这是 OOP 的灵魂。
- 封装(Encapsulation)
定义:将类的某些信息(属性)隐藏在内部,不允许外部直接访问,而是通过提供公共的方法(getter/setter)来访问。核心关键词:private、public、protected。
2.1 访问权限修饰符
修饰符 本类 同包 子类 任何地方 private ✅ ❌ ❌ ❌ default(不写) ✅ ✅ ❌ ❌ protected ✅ ✅ ✅ ❌ public ✅ ✅ ✅ ✅
2.2 封装实践(核心写法)
java
public class Person {
// 属性私有化(private)
private String name;
private int age;
// 公共的 getter/setter
public String getName() {
return name;
}
public void setName(String name) {
this.name = name; // this 代表当前对象
}
public int getAge() {
return age;
}
public void setAge(int age) {
// 可以在 setter 中加入业务逻辑(如合法性校验)
if (age >= 0 && age <= 150) {
this.age = age;
} else {
System.out.println("年龄不合法!");
}
}
}
封装的优点:提高安全性、增加代码的可维护性、隐藏内部实现细节。
- 继承(Inheritance)
定义:子类(派生类)可以继承父类(超类/基类)的非私有属性和方法,实现代码复用。关键词:extends。
Java 是单继承(一个子类只能有一个直接父类),但支持多重继承(爷爷→爸爸→儿子)。
java
// 父类
public class Animal {
public String name;
public void eat() {
System.out.println(name + " 正在吃东西");
}
}
// 子类(继承 Animal)
public class Dog extends Animal {
// 子类可以添加自己的特有属性
public String breed;
// 子类可以添加自己的特有方法
public void bark() {
System.out.println(name + " 汪汪叫");
}
}
// 测试
public class Test {
public static void main(String[] args) {
Dog dog = new Dog();
dog.name = "旺财"; // 来自父类
dog.eat(); // 来自父类
dog.bark(); // 自己的
}
}
3.1 super 关键字
用于访问父类的属性、方法或构造器。
java
public class Dog extends Animal {
public Dog(String name) {
super(name); // 调用父类有参构造(必须放在第一行)
}
@Override
public void eat() {
super.eat(); // 调用父类方法
System.out.println("狗子吃得真香");
}
}
注意:子类构造器默认会隐式调用 super()(父类无参构造)。如果父类没有无参构造,子类必须显式调用 super(参数)。
- 多态(Polymorphism)
定义:同一个行为具有多个不同表现形式的能力。即父类引用指向子类对象。核心:父类类型 变量名 = new 子类对象();
4.1 多态的前提
- 必须存在继承关系。
- 子类必须重写父类的方法(若没有重写,调用的是父类的)。
- 父类引用调用重写的方法时,实际执行的是子类的方法。
4.2 重载(Overload) vs 重写(Override)
对比 重载(Overload) 重写(Override) 位置 同一个类中 子父类中 方法名 相同 相同 参数列表 必须不同 必须相同 返回值 无关 必须兼容 修饰符 无关 权限不能缩小 本质 编译时多态(静态) 运行时多态(动态)
4.3 多态示例
java
class Animal {
public void sound() {
System.out.println("动物叫");
}
}
class Cat extends Animal {
@Override
public void sound() {
System.out.println("喵喵喵");
}
}
class Duck extends Animal {
@Override
public void sound() {
System.out.println("嘎嘎嘎");
}
}
// 测试
public class Test {
public static void main(String[] args) {
Animal a1 = new Cat(); // 向上转型(自动)
Animal a2 = new Duck();
a1.sound(); // 输出:喵喵喵(实际执行子类)
a2.sound(); // 输出:嘎嘎嘎
}
}
4.4 类型转换
· 向上转型(自动):Animal a = new Cat();(安全) · 向下转型(强制):Cat c = (Cat) a;(需要先用 instanceof 判断)
java
if (a1 instanceof Cat) {
Cat cat = (Cat) a1; // 安全转换
cat.sound();
}
- 接口(Interface)
定义:接口是一种完全抽象的规范(契约),只定义方法的签名(JDK 7),不包含实现。关键词:interface、implements。
Java 类只能单继承,但可以实现多个接口。
5.1 接口的基本语法
java
// 定义接口
public interface Flyable {
// 成员变量默认是 public static final(全局常量)
int MAX_SPEED = 1000;
// 方法默认是 public abstract(抽象方法)
void fly();
}
public interface Swimmable {
void swim();
}
5.2 实现接口
java
// 使用 implements 实现接口,必须重写所有抽象方法
public class Duck implements Flyable, Swimmable {
@Override
public void fly() {
System.out.println("鸭子扑腾着飞");
}
@Override
public void swim() {
System.out.println("鸭子嘎嘎游泳");
}
}
5.3 Java 8+ 接口新特性
· 默认方法(default):接口可以包含实现体,子类可继承或重写。 · 静态方法(static):通过接口名直接调用。
java
public interface NewInterface {
// 抽象方法(子类必须实现)
void test();
// 默认方法(子类可重写,也可不重写)
default void print() {
System.out.println("接口默认方法");
}
// 静态方法
static void show() {
System.out.println("接口静态方法");
}
}
抽象类 vs 接口:抽象类可以有构造器和普通成员变量(部分抽象),而接口完全抽象(Java 8 前)。现代开发中,接口更常用于定义行为规范,抽象类用于抽取共性属性。
- 异常处理(Exception)
Java 程序在运行时可能出现各种错误(如数组越界、空指针),异常处理机制可以让程序在出错后继续执行或优雅终止。
6.1 异常体系结构
· Throwable(顶级父类) · Error(错误):JVM 内部错误(如内存溢出),程序无法处理,只能终止。 · Exception(异常):程序可以捕获处理的。 · RuntimeException(运行时异常):不检查异常(如 NullPointerException、ArithmeticException),编译时不强制处理。 · 非运行时异常(受检异常):如 IOException、SQLException,编译时必须处理(try-catch 或 throws)。
6.2 异常处理关键字:try-catch-finally
java
public class ExceptionDemo {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
try {
// 可能出现异常的代码
System.out.println(arr[5]); // 数组越界
int a = 10 / 0; // 算术异常
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("捕获到数组越界异常:" + e.getMessage());
} catch (ArithmeticException e) {
System.out.println("捕获到算术异常:" + e.getMessage());
} catch (Exception e) { // 父类异常必须放在子类之后
System.out.println("捕获到其他异常");
} finally {
// 无论是否发生异常,都会执行(常用于释放资源,如关闭文件流)
System.out.println("finally 块执行,释放资源");
}
System.out.println("程序继续运行...");
}
}
6.3 抛出异常:throws 与 throw
· throws:声明方法可能抛出的异常,交给上层调用者处理。 · throw:手动抛出一个异常对象。
java
// 定义方法:声明可能抛出异常
public static int divide(int a, int b) throws ArithmeticException {
if (b == 0) {
throw new ArithmeticException("除数不能为0!"); // 手动抛出
}
return a / b;
}
// 调用时处理
public static void main(String[] args) {
try {
divide(10, 0);
} catch (ArithmeticException e) {
System.out.println("捕获:" + e.getMessage());
}
}
6.4 自定义异常
继承 Exception(受检)或 RuntimeException(非受检)。
java
// 自定义异常(通常继承 Exception 或 RuntimeException)
public class AgeException extends Exception {
public AgeException() {}
public AgeException(String message) {
super(message); // 将信息传给父类
}
}
// 使用自定义异常
public void setAge(int age) throws AgeException {
if (age < 0 || age > 150) {
throw new AgeException("年龄必须在 0~150 之间!");
}
this.age = age;
}
- 本课总结
知识点 核心要点 面向对象概述 类与对象的关系,三大特性(封装、继承、多态) 封装 private 属性 + public getter/setter,隐藏内部细节 继承 extends 单继承,super 调用父类,方法重写(@Override) 多态 父类引用指向子类对象,重载(编译时)和重写(运行时) 接口 interface / implements,多实现,default/static 方法(Java 8+) 异常 try-catch-finally,throws/throw,自定义异常(继承 Exception)
编码实践是掌握面向对象的唯一捷径,动手敲起来吧! 🚀