
前言在Java的世界里接口和修饰符是面向对象编程的基石。接口定义了“做什么”而修饰符则决定了“怎么做”以及“能做什么”。老师要求我们深入理解这两个部分于是我结合课堂讲义梳理了这份博客。如果你也正在为这些概念苦恼不妨跟着我一起从零开始逐步击破。---第一部分接口Interface接口是Java中非常重要的概念它代表一种标准和规范。打个比方就像USB接口所有符合USB规范的设备U盘、鼠标都可以插到电脑上使用而电脑制造商和设备制造商都遵循同一套USB标准。在Java中接口就是这样的“USB规范”。1. 接口的基本概念与语法什么是接口接口是一种引用数据类型它只定义了方法的名字、参数列表和返回值类型但不提供方法的具体实现在Java 8之前。接口是“实现者”和“使用者”之间的契约。接口的语法要点· 使用关键字 interface 定义编译后生成独立的 .class 文件。· 不能创建对象不能 new 接口但可以声明引用变量即接口类型的变量。· 接口中的属性默认是 public static final 的即公开、静态、常量。一旦赋值就不能改变。· 接口中的方法默认是 public abstract 的即公开、抽象方法没有方法体。· 接口没有构造方法因为它不是类不能被实例化。java// 定义一个接口interface MyInterface {int MAX_VALUE 100; // 等价于 public static final int MAX_VALUE 100;void doWork(); // 等价于 public abstract void doWork();}2. 接口的实现类 implements 接口定义好后需要由类来实现它。实现类使用 implements 关键字。实现规则· 如果实现类不想成为抽象类就必须重写实现接口中所有的抽象方法。· 重写时方法的访问修饰符必须是 public因为接口中的方法默认是public子类重写时权限不能更小。· 接口类型的引用可以指向实现类的对象这就是多态的典型用法。强制使用多态是开发中的最佳实践。javainterface MyInter {int NUM 3;void m1();int m2();}class MyClass implements MyInter {Overridepublic void m1() {System.out.println(m1的方法...);}Overridepublic int m2() {System.out.println(m2的方法...);return 0;}}public class TestInter {public static void main(String[] args) {MyInter mi new MyClass(); // 多态接口引用指向实现类对象mi.m1();int result mi.m2();System.out.println(result result);}}3. 接口的继承性多继承 vs 多实现Java中类之间是单继承但接口之间支持多继承一个接口可以继承多个父接口。接口多继承语法javainterface A { void a(); }interface B { void b(); }interface C extends A, B { // 多继承void c();}类与接口之间是多实现一个类可以同时实现多个接口。javaclass MyClass implements A, B {Overridepublic void a() { }Overridepublic void b() { }}类继承父类的同时实现接口先继承后实现javaclass Parent { }class Child extends Parent implements A, B {// 必须实现所有接口的方法}注意顺序extends 在前implements 在后。4. 接口多继承带来的类型转换影响当接口类型的引用进行强制类型转换时如果转换的目标是接口类型编译期总是通过因为接口之间可能有继承关系。但运行时是否成功取决于引用中实际存储的对象类型是否与目标类型兼容。· 如果实际对象类型就是目标类型或它的子类则转换成功。· 否则抛出 ClassCastException类型转换异常。javaA a new MyClass(); // MyClass实现了AB b (B) a; // 如果MyClass也实现了B则OK否则运行报错5. 接口的作用开发应用作用一扩充子类能力由于Java类是单继承子类从父类获得的功能有限。接口可以给子类“附加”额外的能力。通常把主要功能放在父类中次要的、扩展的功能放在接口中。作用二降低耦合度接口将“使用者”和“实现者”分离。使用者只依赖接口不关心具体实现实现者只需按接口规范编码。借助多态各模块之间可以独立演化维护更方便。6. 接口回调理解接口回调是指接口先定义好然后由接口的使用者比如框架调用而具体的实现代码由我们开发人员编写。这种模式在事件监听、回调函数中非常常见。简单来说就是“你定义规则我来实现你按规则调用我的实现”。开发时我们需要关注的是根据接口规范给出正确的实现类。---接口与抽象类的区别面试高频对比项 接口 (interface) 抽象类 (abstract class)关键字 interface abstract class属性 只能是 public static final 无限制实例变量、静态变量等方法 只能是 public abstractJava 8前 可以有抽象方法也可以有非抽象方法构造方法 没有 有用于子类构造时调用继承/实现关系 接口可以多继承类可以多实现 类只能单继承选择建议如果需要定义公共的、不变的行为规范用接口如果需要复用代码有共同的成员变量或已实现的方法用抽象类。---第二部分三个修饰符abstract、static、final修饰符用来控制类、方法、属性的行为和访问权限。这里重点讲解 abstract、static 和 final。一、abstract抽象的1. 抽象类· 使用 abstract 修饰类该类就是抽象类。· 抽象类不能实例化不能 new但可以声明引用用于多态。· 抽象类中可以有成员变量、成员方法也可以有构造方法供子类调用。· 抽象类的作用强制使用多态让子类必须实现某些方法。javaabstract class Animal {String name;public Animal(String name) { this.name name; }public abstract void sound(); // 抽象方法}2. 抽象方法· 使用 abstract 修饰方法该方法只有声明没有方法体连 {} 都没有。· 抽象方法只能定义在抽象类中。· 子类继承抽象类后必须实现所有抽象方法否则子类也必须声明为抽象类。javaclass Dog extends Animal {public Dog(String name) { super(name); }Overridepublic void sound() {System.out.println(汪汪);}}二、static静态的静态成员属于类级别不属于某个对象被所有对象共享。1. 静态属性类变量· 用 static 修饰的属性称为静态属性。· 所有对象共用一份推荐使用 类名.属性名 访问。· 静态属性在类加载时初始化。javaclass Counter {static int count 0; // 静态变量int id;public Counter() {count;id count;}}// 使用Counter.count2. 静态方法· 用 static 修饰的方法称为静态方法。· 通过 类名.方法名() 调用。· 注意· 静态方法中不能直接访问本类的非静态成员属性和方法因为非静态成员属于对象而静态方法调用时可能还没有对象。· 但非静态方法可以访问静态成员。· 静态方法中不能使用 this 和 super。· 静态方法可以被子类继承但只能被静态方法覆盖重写且没有多态效果调用时看引用类型而非实际对象。javaclass MyClass {int value 10;static int b 30;static void staticMethod() {// System.out.println(value); // 错误不能直接访问非静态System.out.println(b); // 正确}void instanceMethod() {System.out.println(value); // 正确System.out.println(b); // 正确可以访问静态}}3. 静态代码块static initialization block· 位置在类内、方法外用 static {} 包裹。· 在类加载时执行且只执行一次用于初始化静态属性。· 执行顺序先执行静态属性的初始化按定义顺序再执行静态代码块。类加载的时机· 第一次创建该类的对象· 第一次使用该类的静态成员· 子类加载会导致父类先加载。完整加载与创建对象的顺序以继承为例1. 加载父类静态属性初始化 → 静态代码块2. 加载子类静态属性初始化 → 静态代码块3. 创建父类对象实例属性初始化 → 动态代码块 → 构造方法4. 创建子类对象实例属性初始化 → 动态代码块 → 构造方法javaclass Parent {static int a 10;static { System.out.println(Parent static block); }{ System.out.println(Parent instance block); }Parent() { System.out.println(Parent constructor); }}class Child extends Parent {static int b 20;static { System.out.println(Child static block); }{ System.out.println(Child instance block); }Child() { System.out.println(Child constructor); }}// 当 new Child() 时输出顺序如上所述。4. 静态内部类略本文不展开三、final最终的final 表示不可改变。1. final 修饰变量常量· 局部变量、实例变量、静态变量都可以被 final 修饰一旦赋值就不能再修改。· 实例变量非静态不会默认赋值必须显式初始化时机· 声明时直接赋值· 在构造方法中赋值所有构造方法都必须赋值· 在动态代码块中赋值。· 静态变量必须在声明时或静态代码块中赋值。javaclass FinalDemo {final int a; // 必须在构造器或代码块中赋值final static int B; // 必须在静态代码块中赋值{a 10; // 可以}static {B 20;}}注意final 修饰引用类型变量时表示引用指向的地址不能变但对象内部的内容可以改变除非对象本身不可变。2. final 修饰方法· 方法可以被继承但不能被子类重写覆盖。这可以防止子类修改父类的重要方法。3. final 修饰类· 类不能被继承即没有子类。例如 String、System、Math 都是 final 类。---总结通过这次整理我对接口和三个修饰符有了更清晰的认识· 接口定义了行为规范支持多继承和多实现是降低耦合、实现多态的利器。· abstract用于定义抽象类和抽象方法强制子类实现是多态的基础。· static让成员属于类方便共享和调用但要注意静态上下文不能直接访问非静态。· final保证不可变性用于常量、防止方法重写或类继承。这些知识点是Java开发中的常客也是面试中的高频考点。大一阶段打好基础后面学框架、设计模式时会更加得心应手。希望我的笔记能对你有所帮助。如果发现错误或有更好的理解欢迎在评论区交流讨论