Java 学习笔记 · 第二课:面向对象核心(封装、继承、多态)及接口与异常

承接第一课的基础语法,本节课正式进入 Java 的核心------面向对象编程(OOP)。掌握这些,你就拿到了 Java 世界的入场券。


  1. 什么是面向对象(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 的灵魂。


  1. 封装(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("年龄不合法!");
        }
    }
}

封装的优点:提高安全性、增加代码的可维护性、隐藏内部实现细节。


  1. 继承(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(参数)。


  1. 多态(Polymorphism)

定义:同一个行为具有多个不同表现形式的能力。即父类引用指向子类对象。核心:父类类型 变量名 = new 子类对象();

4.1 多态的前提

  1. 必须存在继承关系。
  2. 子类必须重写父类的方法(若没有重写,调用的是父类的)。
  3. 父类引用调用重写的方法时,实际执行的是子类的方法。

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();
}

  1. 接口(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 前)。现代开发中,接口更常用于定义行为规范,抽象类用于抽取共性属性。


  1. 异常处理(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;
}

  1. 本课总结

知识点 核心要点 面向对象概述 类与对象的关系,三大特性(封装、继承、多态) 封装 private 属性 + public getter/setter,隐藏内部细节 继承 extends 单继承,super 调用父类,方法重写(@Override) 多态 父类引用指向子类对象,重载(编译时)和重写(运行时) 接口 interface / implements,多实现,default/static 方法(Java 8+) 异常 try-catch-finally,throws/throw,自定义异常(继承 Exception)

编码实践是掌握面向对象的唯一捷径,动手敲起来吧! 🚀

相关推荐
颜进强1 小时前
Calude Code - 23 用 MCP 把 Jenkins 变成 AI 队友:一次对话完成自动化发布
前端·后端
wangjialelele1 小时前
Selenium4 + Java Web自动化测试入门指南:从环境搭建到常用操作详解
java·开发语言·前端·测试工具·自动化
Awna1 小时前
Golang 大小写可见性规范
开发语言·后端·golang
神奇小汤圆1 小时前
分布式事务没有银弹:从CAP定理到AT与TCC模式的选择指南
后端
YuePeng2 小时前
不写一行接口,让 DBeaver 直连你的指标层——背后只用了一个端口
后端·架构·github
孙启超2 小时前
【AI应用开发】LangChain 中 Chain 和 Agent 核心区别?
java·人工智能·langchain·llm·rag·ai应用开发·agent loop
leoZ2312 小时前
实战复盘:用 Claude Code 从零搭一个 GitHub PR 统计工具
java·人工智能·python·深度学习·自然语言处理·github·llama
William Dawson2 小时前
【踩坑实录|Hive1\.2\.1数据服务接口5大疑难问题调试与全方位优化方案】
java·hive·spring boot
2601_955759882 小时前
如何识别 Claude API 低价值调用并优化
java