Java 5——final 抽象 接口

final

final修饰变量

基本用法

被final修饰的变量不可以被改变,又被称为常量

java 复制代码
final double PI = 3.14159;
PI = 3.14;   // 编译错误:不能再次赋值
空白 final(Blank final)

声明时不赋初值,但必须在构造方法或初始化块中完成赋值,且只能赋值一次

java 复制代码
class Circle {
    final double PI;           // 空白 final
    Circle() {
        PI = 3.14159;          // 构造方法中赋值
    }
}
final 修饰引用类型变量

引用变量本身不能再指向其他对象

但对象的内容(成员变量)仍可改变(除非对象的类做了不可变设计)

java 复制代码
final StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");      // ✅ 允许,对象内容改变
sb = new StringBuilder(); // ❌ 错误:引用不能改变
final 修饰成员变量

实例变量:必须显式赋值或在构造方法中赋值

静态变量:必须显式赋值或在静态代码块中赋值

java 复制代码
class Example {
    final int a = 10;           // 直接赋值
    final int b;                // 空白 final,需在构造器中赋值
    static final int C = 100;   // 静态常量
    static final int D;         // 空白 static final,需在静态块中赋值

    Example() { b = 20; }
    static { D = 200; }
}
局部变量

局部变量被 final 修饰后,值不能改变

java 复制代码
public void method() {
    final int x = 5;
    x = 6;   // 错误
}
方法参数

方法参数被 final 修饰后,在方法体内不能改变参数引用

java 复制代码
public void print(final int value) {
    // value = 10;   // 错误
    System.out.println(value);
}

final修饰方法

被final修饰的方法不可以被重写

主要目的:防止子类修改该方法的行为

注意:final 方法仍可以被继承,只是子类不能重写

java 复制代码
class Parent {
    public final void show() {
        System.out.println("Parent show");
    }
}

class Child extends Parent {
    // public void show() { }   // 编译错误:不能重写 final 方法
}

private 方法隐式是 final 的(因为子类不可见),但通常不写 final构造方法不能是 final(构造方法不能被继承)。

final修饰类

被final修饰的类不可以被继承

典型例子:StringIntegerSystem

java 复制代码
final class FinalClass {
    // 类体
}

// class SubClass extends FinalClass { }   // 编译错误:不能继承 final 类

final 类的所有方法隐式也是 final 的(因为无法被重写),但成员变量可以是普通的

finalstatic 的区别

特性 final static
作用 不可改变(值、方法、类) 属于类,不依赖对象
修饰变量 只能赋值一次(常量) 类变量,所有对象共享一份
修饰方法 不能被子类重写 类方法,不能被子类重写(隐藏)
修饰类 不能被继承 不能修饰外部类(可修饰内部类)
常见组合 static final 表示全局常量 -

全局变量通常写成 public static final,例如 Math.PI

java 复制代码
public static final double PI = 3.141592653589793;

总结就是不可变

final 与不可变性(Immutability)

final 只是保证引用不可变,并不保证对象内容不可变

真正的不可变类要求:

1.类声明为 final(防止子类修改行为)

2.所有成员变量为 private final

3.不提供任何修改成员变量的方法(setter)

4.如果有可变成员(如 Date、集合),应返回其副本或不可变视图

java 复制代码
public final class ImmutablePerson {
    private final String name;
    private final int age;
    public ImmutablePerson(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() { return name; }
    public int getAge() { return age; }
}

抽象

抽象:现实中不存在的东西

在Java中的抽象表示只声明,不实现

抽象方法

抽象方法:使用abstract来修饰,不可以有方法体,直接用分号结束

抽象类:如果一个类中有抽象方法,那么这个类必须是一个抽象类

特点:

1.抽象类不可以创建对象

2.抽象类的子类,必须重写父类中的抽象方法,否则子类必须也是抽象类

3.抽象方法不能被 privatefinalstatic 修饰

抽象类

通过抽象类可以强制要求子类中必须有哪些方法

抽象类不能被实例化 (不能 new

抽象类的构造方法用于被子类调用(super

抽象类可以没有抽象方法(但通常至少有一个抽象方法)

抽象类可以包含成员变量、常量、构造方法、具体方法、静态方法等

抽象类中可以有正常的方法

java 复制代码
public abstract class Animal {
    protected String name;
    
    public Animal(String name) {
        this.name = name;
    }
    
    // 抽象方法
    public abstract void sound();
    
    // 具体方法
    public void sleep() {
        System.out.println(name + "在睡觉");
    }
}
继承抽象类

子类继承抽象类后,必须:

实现所有抽象方法(除非子类也是抽象类)

可以使用 super 调用父类构造方法

java 复制代码
class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }
    @Override
    public void sound() {
        System.out.println(name + "汪汪叫");
    }
}

class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }
    @Override
    public void sound() {
        System.out.println(name + "喵喵喵");
    }
}
常见误区

1.误区:抽象类必须包含抽象方法。

正解:抽象类可以没有抽象方法(例如作为工具类禁止实例化)。

2.误区:抽象类不能有构造方法。

正解:有构造方法,用于子类初始化。

3.误区:abstractfinal 可以同时修饰方法。

正解:不能,final 方法不能被重写,而抽象方法必须被重写,矛盾。

4.误区:抽象类可以实例化匿名内部类。

正解:这是创建了匿名子类的对象,不是抽象类本身的实例。

接口

接口实际上是一种特殊的抽象类

接口中所有的方法都是抽象方法

接口使用interface来声明,接口中的方法默认是 public abstract(可省略),成员变量默认是 public static final(常量)

java 复制代码
public interface Animal {
    // 常量(默认 public static final)
    String TYPE = "动物";

    // 抽象方法(默认 public abstract)
    void eat();
    void sleep();
}

类只能单继承,接口支持多实现

使用 implements 关键字,一个类可以实现多个接口(多实现)。必须实现所有抽象方法(除非该类是抽象类)

java 复制代码
public class Dog implements Animal {
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    @Override
    public void sleep() {
        System.out.println("狗睡觉");
    }
}

接口同样具有多态性

接口可以把很多不相关的内容进行整合

特点:

1.接口中所有的方法都是抽象方法,都是公开的

2.接口中所有的变量都是全局静态变量

特性 说明
接口不能实例化 不能 new 接口名(),但可以用实现类对象赋值给接口引用(多态)
接口没有构造方法 不能被 new,也不需要有构造方法
接口中的方法默认修饰符 public abstract(可省略)
接口中的成员变量默认修饰符 public static final(可省略),必须显式赋值
一个类可以实现多个接口 解决 Java 单继承的局限
接口可以继承多个接口 使用 extends,接口之间可以多继承
接口可以包含默认方法 Java 8 引入,使用 default 关键字,提供默认实现,不强制实现类重写
接口可以包含静态方法 Java 8 引入,使用 static 关键字,通过接口名调用
接口可以包含私有方法 Java 9 引入,用于默认方法或静态方法内部复用代码
接口的多实现

1.一个类可以实现多个接口。

2.如果多个接口有相同签名的默认方法,实现类必须重写该方法(或指定调用哪个父接口的默认方法)。

3.如果多个接口有相同签名的抽象方法,实现类只需实现一次

java 复制代码
interface Flyable {
    void fly();
}
interface Swimmable {
    void swim();
}
class Duck implements Flyable, Swimmable {
    @Override
    public void fly() { System.out.println("鸭子飞"); }
    @Override
    public void swim() { System.out.println("鸭子游泳"); }
}
接口与抽象类的区别
特性 接口(interface) 抽象类(abstract class)
关键字 interface abstract class
实例化 不能 不能
成员变量 默认 public static final(常量) 可以是普通变量、常量
构造方法 有,供子类调用
抽象方法 默认 public abstract 可以是 protectedpublic
具体方法 Java 8+ 可以有 default/static 方法 可以有任意具体方法
私有方法 Java 9+ 允许 允许
继承/实现 一个类可以实现多个接口 一个类只能继承一个抽象类(单继承)
设计意图 定义"能做什么"(can-do)能力契约 定义"是什么"(is-a),复用代码
常见误区
误区 正确理解
接口中不能有方法体 Java 8+ 可以有 defaultstatic 方法体
接口中的方法必须是 public 默认就是 public,不能是 protected / private(除非 Java 9+ 的私有方法)
接口可以实例化 不能,但可以用匿名内部类创建接口的匿名实现类
接口中的变量可以修改 接口中的变量默认是 final,不能修改
实现接口必须重写所有方法 如果实现类是抽象类,可以不重写
相关推荐
BlackTurn16 小时前
技术经理投标
java
曾阿伦16 小时前
Python 搭建简易HTTP服务
开发语言·python·http
YG亲测源码屋16 小时前
java配置环境变量、jdk环境变量配置、java环境变量设置方法
java·开发语言
MIUMIUKK16 小时前
从语法层面,看懂 Python 的特殊处
java·开发语言·python
FlyWIHTSKY16 小时前
TS、TSX、JS、JSX 文件扩展名详解
开发语言·javascript·ecmascript
着迷不白16 小时前
第一部分:认识python
开发语言·python
hujinyuan2016016 小时前
2026年3月 中国电子学会青少年软件编程(Python)三级考试试卷 真题及答案
java·python·算法
basketball61617 小时前
C++ 高级编程:2. 基本线程池实现
java·开发语言·c++
chao18984417 小时前
SGM(Semi-Global Matching)立体匹配算法 — C++ 实现
开发语言·c++·算法