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)

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

相关推荐
吴声子夜歌4 小时前
Java面试——算法
java·算法·面试
东风破_4 小时前
Vibe Coding 上头之后,我开始用 SDD 给 AI 编程加一张“施工图”
人工智能·程序员
evans在进步4 小时前
LeetCode 64:最小路径和——Java 原地动态规划详解
java·leetcode·动态规划
凤山老林6 小时前
Spring Boot 3.x AOT 编译实战:从原理、踩坑到生产落地
java·spring boot·后端
博傅6 小时前
Spring 核心原理
java·后端·spring
yurenpai(27届找实习中)6 小时前
从零读懂 AI 智能客服(一):模块职责与 SSE 聊天链路(后端架构)
java·人工智能·架构·langchain4j
用户938515635076 小时前
掘金风格后端数据库设计实战:从用户表到分布式架构,一文搞定
后端·sql
陈皮波比茶7 小时前
Swagger
java
拾光师7 小时前
Hadoop 三种运行模式:从单机调试到生产集群,一路搭过来
后端
小闫BI设源码7 小时前
Elasticsearch面试必看:如何让客户端精准选择节点高效执行请求?
java·elasticsearch·面试宝典·深入解析