20260723-笔记.md 30 KB

JavaSE 基础 — Day09 笔记

日期:2026-07-23
项目c260723
作者:WanJL


一、抽象类(Abstract Class)

1. 抽象类的引出

文件Demo01.java

在父子类继承时,提取子类的共性功能时,有些方法在父类中并没有具体的实现。

例如员工体系:

员工类
  |- 开发工程师
     |- Java开发工程师
     |- 前端开发工程师
  |- 测试工程师
     |- 后端测试工程师
     |- IOS测试工程师

每一个子类的工作内容都是不一样的,所以都需要重写父类的 work() 方法,导致父类的 work() 方法代码没有实际作用。

public class 员工 {
    public void work() {
        // 每一个子类的工作内容都不一样,此方法体没有意义
    }
}

在 Java 中,一个没有方法体的方法,应该定义为 抽象方法;如果类中包含抽象方法,那么这个类必须是 抽象类

2. 抽象类的定义

文件Demo01.java

使用 abstract 关键字来定义抽象类和抽象方法。

定义抽象类

public abstract class 类名 {
    // 成员
}

定义抽象方法

public abstract 返回值类型 方法名(参数列表);

注意:抽象方法没有方法体(没有 {},直接以分号结尾)。

3. 抽象类的特点

文件Demo01.java

特性 说明
关键字 抽象类和抽象方法必须使用 abstract 关键字修饰
抽象方法所在类 有抽象方法的类必须是抽象类
抽象类中的抽象方法 抽象类中不一定要有抽象方法,但抽象方法必须在抽象类中
实例化 抽象类不能实例化(不能创建对象)
构造方法 抽象类可以有构造方法(供子类通过 super() 调用)
子类选择 ① 重写父类所有的抽象方法;② 子类也是抽象类,直接继承父类的抽象方法
继承关系 抽象父类和具体子类之间是继承关系,子类仍然属于父类类型

二、抽象类代码示例

示例 1:动物体系(Animal → Cat / Dog)

抽象父类 Animal

文件Animal.java

package course;

public abstract class Animal {
    public Animal() {
        System.out.println("调用动物的构造方法....");
    }

    public abstract void eat();
    public abstract void sleep();
    public abstract void move();
    public abstract void play();
}
  • 定义了 4 个抽象方法:eat()sleep()move()play()
  • 包含一个构造方法,虽然抽象类不能直接创建对象,但构造方法可以通过子类 super() 调用

子类 Cat

文件Cat.java

package course;

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }

    @Override
    public void sleep() {
        // 空实现
    }

    @Override
    public void move() {
        // 空实现
    }

    @Override
    public void play() {
        // 空实现
    }
}
  • 使用 extends 继承抽象类 Animal
  • 使用 @Override 注解重写父类的所有抽象方法(必须全部重写,否则子类也要声明为抽象类)

子类 Dog

文件Dog.java

package course;

public class Dog extends Animal {
    public void eat() {
        System.out.println("狗吃肉");
    }

    @Override
    public void sleep() { }

    @Override
    public void move() { }

    @Override
    public void play() { }
}
  • 同样继承 Animal,重写所有抽象方法
  • eat() 方法没有写 @Override 注解,但仍然是对父类抽象方法的重写(注解只是编译检查,不写也能重写)

测试类 Test01

文件Test01.java

package course;

public class Test01 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();  // 输出:狗吃肉
    }
}
  • 创建 Dog 对象,调用重写后的 eat() 方法
  • 验证了抽象类的子类可以正常创建对象和使用成员方法

示例 2:员工体系(Emp → javaEmp)

抽象父类 Emp

文件Emp.java

package course;

// 有抽象方法的类必须是抽象类
public abstract class Emp {
    /**
     * 抽象方法——没有方法体
     */
    public abstract void work();
}
  • 只定义了一个抽象方法 work()
  • 类必须使用 abstract 修饰

子类 javaEmp

文件javaEmp.java

package course;

public class javaEmp extends Emp {
    @Override
    public void work() {
        System.out.println("Java开发工程师在开发Java项目");
    }
}
  • 重写父类的 work() 抽象方法,给出具体的实现
  • 不同子类可以提供不同的实现(例如还可以有 前端开发工程师后端测试工程师 等)

示例 3:服务层体系(BaseService → UserService)

抽象父类 BaseService

文件BaseService.java

package course;

public abstract class BaseService {
    public abstract void add();
    public abstract void remove();
    public abstract void update();
    public abstract void query();
}
  • 定义了标准的 CRUD(增删改查)四个抽象方法
  • 在实际项目中常用来定义业务层接口规范

子类 UserService

文件UserService.java

package course;

public class UserService extends BaseService {
    @Override
    public void add() { }

    @Override
    public void remove() { }

    @Override
    public void update() { }

    @Override
    public void query() { }
}
  • 重写父类的所有抽象方法
  • 方法体暂时为空,后续可添加具体的业务逻辑

三、final 关键字

1. final 的引出

文件Demo02.java

在实际开发中,有些类、方法或变量不希望被改变:

  • 某个工具类,只能被调用,不希望被继承
  • 某些核心方法,不希望被子类重写(篡改)
  • 某些固定值,希望成为常量,不允许修改

final 关键字就是用来解决这些问题的——用于限制类、方法或变量被修改

2. final 修饰类——禁止继承

文件Demo02.javaFinalClass.java

// 使用 final 修饰的类,不能被继承
public final class 类名 {
    // ...
}

应用场景

  • 工具类(如 MathArrays),只能被调用,不能被继承
  • 特殊功能的类,如 String 类就是用 final 修饰的,不能被继承

3. final 修饰方法——禁止重写

文件FinalClass.javaSubClass.java

// 父类中的 final 方法
public class FinalClass {
    final String SPRING = "春天";

    public final void showInfo() {
        System.out.printf(SPRING);
    }
}

// 子类无法重写父类的 final 方法
public class SubClass extends FinalClass {
    // ❌ 编译报错:不能重写父类的 final 方法
    // public final void showInfo() {
    //     System.out.printf(SPRING);
    // }
}
  • FinalClass 类本身没有用 final 修饰,所以 SubClass 可以继承它
  • FinalClass 中的 showInfo() 方法用 final 修饰,子类 不能重写 该方法
  • 注掉了 SubClass 中的重写代码,否则编译报错

4. final 修饰变量——变成常量

文件Demo02.javaTest02.java

// final 修饰基本类型变量——值不可修改
final int i = 10;
// i = 20;  // ❌ 编译报错:不能修改 final 变量的值

// final 修饰引用类型变量——引用地址不可变,但对象内容可以修改
final Person p = new Person("1001", "张三");
// p = new Person("1002", "李四");  // ❌ 编译报错:不能修改引用地址
p.setName("李四");  // ✅ 可以修改对象的属性
p.setId("1002");
System.out.printf(p.showInfo());  // 输出:Person{id='1002', name='李四'}

常量命名规范:Java 中一般使用 final 修饰的变量作为常量,常量名称通常 全部大写,单词之间用下划线 _ 分隔。例如:

final String SPRING = "春天";     // FinalClass.java
final int MAX_STUDENT_COUNT = 100;
final double PI = 3.1415926;

关键区别

变量类型 final 的作用 示例
基本类型(int、double 等) 数值本身不可修改 final int i = 10;i=20; 报错
引用类型(对象、数组等) 引用地址不可修改,但对象 属性 可修改 final Person p = new Person(...)p.setName(...) 可以

注意final 修饰引用类型变量时,只是保证这个变量不再指向其他对象,但该对象内部的 成员变量 仍然可以通过 setter 修改。

5. final 与 abstract 的对比

关键字 修饰类 修饰方法 修饰变量
abstract 类必须被继承 方法必须在子类中实现(无方法体) 不能修饰变量
final 类不能被继承 方法不能被重写 变量变成常量

⚠️ finalabstract 不能同时使用,二者语义完全冲突:

  • abstract 表示「需要被继承/重写」
  • final 表示「不能被继承/重写」

四、随堂练习代码示例——Shape 抽象类(计算周长 + 计算面积)

代码位于 exercise/exercise02 包中,对应课堂练习题第 2 题。

抽象父类 Shape

文件exercise/exercise02/Shape.java

package exercise.exercise02;

public abstract class Shape {
    private String color;

    public Shape(String color) {
        this.color = color;
    }

    /** 计算面积——抽象方法 */
    public abstract double getArea();

    /** 计算周长——抽象方法 */
    public abstract double getPerimeter();

    /** 输出信息——普通方法(调用抽象方法) */
    public void showInfo() {
        System.out.print("颜色:" + this.color);
        System.out.printf(",面积:%.2f", getArea());
        System.out.printf(",周长:%.2f", getPerimeter());
        System.out.println();
    }
}
  • 定义了两个抽象方法:getArea()getPerimeter()
  • 定义了一个普通方法 showInfo(),内部调用抽象方法输出结果
  • 体现了 模板方法 的思想——父类定义输出框架,子类提供具体的面积和周长计算

子类 Circle

文件exercise/exercise02/Circle.java

package exercise.exercise02;

public class Circle extends Shape {
    private double radius;
    private double pi = 3.1415926;

    public Circle(String color, double radius) {
        super(color);           // 调用父类构造方法
        this.radius = radius;   // 初始化子类属性
    }

    @Override
    public double getArea() {
        return pi * radius * radius;
    }

    @Override
    public double getPerimeter() {
        return 2 * pi * radius;
    }
}

测试类 Test

文件exercise/exercise02/Test.java

package exercise.exercise02;

public class Test {
    public static void main(String[] args) {
        Circle circle = new Circle("红色", 5);
        circle.showInfo();
        // 输出:颜色:红色,面积:78.54,周长:31.42
    }
}

五、模板方法设计模式(Template Method Pattern)

1. 模板方法的引出

文件Demo03.java

模板方法模式是抽象类的经典应用场景。核心思想:父类定义算法的「骨架」(通用结构),子类实现特定的「步骤」(定制化需求)

Java中的设计模式:模板模式
是把抽象类整体看成是一个模版,模板中不能决定的东西,抽象成方法
让使用模板的类(也就是抽象类的子类)去重写抽象方法,实现定制化的需求。
模板模式的优势:
    模板已经定义了通用的结构,使用者只需要关心自己需要实现的功能就可以了

2. 模板类的组成

文件MyOneDayTemplate.java

一般模板类分为两部分:

组成部分 关键字 说明
模板方法 final 定义执行步骤的骨架,子类不能修改(不能重写)
抽象方法 abstract 需要被子类重写的方法,具体行为由子类决定
package course;

public abstract class MyOneDayTemplate {

    /**
     * 模板方法——使用 final 修饰,只能使用,不能修改
     */
    public final void myOneDay() {
        System.out.print("《我的一天》");
        System.out.print("今天我吃了");
        this.eat();         // 步骤 1:吃(抽象方法,子类实现)
        System.out.print("然后我又");
        this.sleep();       // 步骤 2:睡(抽象方法,子类实现)
        System.out.print("最后我又玩了");
        this.play();        // 步骤 3:玩(抽象方法,子类实现)
        System.out.print("好开心哟~");
        System.out.println();
    }

    // 抽象方法——由子类提供具体的实现
    public abstract void eat();
    public abstract void sleep();
    public abstract void play();
}

关键点myOneDay()final 修饰,确保子类不能篡改这个方法的结构。子类只需关注 eat()sleep()play() 三个抽象方法的具体实现。

3. 子类实现

文件ZhSanOneDay.javaLiSiOneDay.java

// 张三的一天
public class ZhSanOneDay extends MyOneDayTemplate {
    @Override
    public void eat() {
        System.out.println("饭");
    }

    @Override
    public void sleep() {
        System.out.println("菜");
    }

    @Override
    public void play() {
        System.out.println("小狗");
    }
}

// 李四的一天
public class LiSiOneDay extends MyOneDayTemplate {
    @Override
    public void eat() {
        System.out.println("饭");
    }

    @Override
    public void sleep() {
        System.out.println("菜");
    }

    @Override
    public void play() {
        System.out.println("小狗");
    }
}

4. 测试类

文件Test03.java

public class Test03 {
    public static void main(String[] args) {
        ZhSanOneDay zhSanOneDay = new ZhSanOneDay();
        zhSanOneDay.myOneDay();

        LiSiOneDay li = new LiSiOneDay();
        li.myOneDay();
    }
}

预期输出

《我的一天》今天我吃了饭然后我又菜最后我又玩了好开心哟~
《我的一天》今天我吃了饭然后我又菜最后我又玩了好开心哟~

5. 模板方法模式的优势

优势 说明
复用性 公共的流程代码写在父类的模板方法中,所有子类共用
扩展性 新增一种「一天」只需新建子类,重写抽象方法即可
规范性 父类通过模板方法强制规定了执行顺序和结构,子类无法改变
关注分离 使用者只需关心自己的定制逻辑(吃什么/睡什么/玩什么),不用关注整体流程

6. 模板方法 vs 普通继承 + 方法重写

对比维度 普通继承 + 方法重写 模板方法模式
父类方法 普通方法,子类可选择重写或不重写 模板方法用 final 修饰,禁止重写
执行流程 由调用方决定调用顺序 父类模板方法定义固定执行顺序
强制约束 弱——子类可以不重写 强——子类必须重写抽象方法
设计意图 复用代码 定义算法骨架 + 强制子类实现特定步骤

六、代码块(Code Block)

1. 代码块的概念

文件Demo04.java

在 Java 中,使用 {} 括起来的代码称为 代码块

{
    // 代码....
}

Java 中分为三种代码块:

代码块类型 位置 执行时机
局部代码块 方法或构造方法内部 调用到该方法时执行
构造代码块 方法外部、类内部 每次创建对象时执行(在构造方法之前)
静态代码块 类内部,使用 static 修饰 类加载时执行(仅一次)

2. 三种代码块示例

文件Demo04.java

package course;

public class Demo04 {

    public Demo04() {
        // 局部代码块——存在于方法或构造方法里面
        {
            System.out.println("我是局部代码块,我存在于方法或构造方法里面");
        }
        System.out.println("我是构造方法");
    }

    // 构造代码块——在方法外面类里面
    {
        System.out.println("我是构造代码块....我是在构造方法前面执行....");
    }

    // 静态代码块——使用 static 修饰
    static {
        System.out.println("我是静态代码块....我最先执行");
    }

    public static void main(String[] args) {
        Demo04 d = new Demo04();
    }
}

3. 执行顺序验证

执行 main 方法中的 new Demo04(),输出结果:

我是静态代码块....我最先执行
我是构造代码块....我是在构造方法前面执行....
我是局部代码块,我存在于方法或构造方法里面
我是构造方法

执行流程说明

步骤 执行的代码 说明
static { ... } 类加载时执行静态代码块(仅执行一次)
{ ... }(构造代码块) 每次创建对象时,在构造方法之前执行
{ ... }(局部代码块) 构造方法内部按顺序执行到局部代码块
构造方法体 构造方法的其他代码最后执行

注意:如果 main 方法中只声明变量 Demo04 d; 而不创建对象,则只有静态代码块执行,构造代码块和构造方法都不会执行。

4. 三种代码块的特点总结

代码块类型 执行次数 执行时机 典型用途
静态代码块 1 次(类加载时) 最早执行 加载配置文件、初始化静态资源
构造代码块 每次创建对象 在构造方法之前 提取多个构造方法的共同代码
局部代码块 调用到该位置时 方法执行过程中 限制局部变量的作用域

5. 构造代码块的作用

构造代码块的一个重要特性:把里面的代码在运行的时候,整合到被调用的构造方法中。这意味着:

  • 如果一个类有多个重载的构造方法,每个构造方法中都需要执行的相同代码,可以提取到构造代码块中
  • 构造代码块在 所有构造方法之前 执行
  • 避免多个构造方法中的代码重复

    public class Example {
    // 构造代码块——所有构造方法都会执行
    {
        System.out.println("初始化公共资源...");
    }
    
    public Example() {
        System.out.println("无参构造");
    }
    
    public Example(String name) {
        System.out.println("有参构造:" + name);
    }
    }
    

七、接口(Interface)

1. 接口的引出——解决单继承的局限性

文件Demo05.java

Java 中的继承是 单继承,一个子类只能直接继承一个父类。这种方式逻辑清晰,但扩展性较低。

学生类 extends 人类

鹦鹉   extends 鸟类

鸟人   extends   ?    ← 既有人类的特征,又有鸟类的飞行能力,单继承无法解决

为了解决单继承带来的局限性,Java 提出了 接口 的概念。

接口(Interface) 是一种公共规范标准,只要符合这个规范标准,大家都可以通用。

鸟人 extends 人类 实现 飞行接口    ← 继承父类 + 实现接口,两者互补

接口存在的意义

  • 定义规范 — 规定实现类必须遵循的行为标准
  • 功能拓展 — 在继承父类的基础上,额外扩展其他能力

俗话说的好:「单继承 + 多实现」——一个类只能继承一个父类,但可以同时实现多个接口。

2. 接口的定义

文件Demo05.javaMyInterface.java

接口的关键字是 interface。接口也是一种引用数据类型(或者说接口也是一种类)。

public interface 接口名 {
    // 成员
}

接口的成员特点

成员类型 默认修饰符 说明
变量 public static final 接口中定义的变量都是 公开的静态常量
方法 public abstract 接口中定义的方法都是 公开的抽象方法
public interface MyInterface {
    // 变量——默认使用 public static final
    public static final String name = "张三";

    // 方法——默认使用 public abstract
    public abstract void method();
}

注意:接口和抽象类一样 不能实例化(不能创建对象),且接口 没有构造方法

3. 接口的实现

文件Demo05.java

子类继承接口称为「实现 接口」,使用关键字 implements

public class 实现类 implements 接口 {
    // 必须重写(实现)接口中所有的抽象方法
}

// 类可以同时继承父类 + 实现接口
public class 子类 extends 父类 implements 接口1, 接口2, ... {
    // 必须重写所有接口中的抽象方法
}

接口的子类(实现类)规则

  • 要么重写(实现)接口中 所有 的抽象方法
  • 要么子类也是一个 抽象类

接口与抽象类的对比

对比维度 抽象类 接口
关键字 abstract class interface
构造方法 可以有 不能有
成员变量 可以是任意类型 只能是 public static final 常量
成员方法 可以有抽象/非抽象方法 只能是 public abstract 抽象方法
子类方式 extends(继承) implements(实现)
单/多 单继承 可同时实现多个接口

4. USB 接口标准示例

4.1 定义 USB 接口标准

文件Usb.java

package course;

public interface Usb {
    void startUsb();   // 默认 public abstract
    void useUsb();     // 默认 public abstract
    void stopUsb();    // 默认 public abstract
}

USB 接口定义了一个规范标准:任何 USB 设备都必须具备「启动 → 使用 → 关闭」三个行为。

4.2 父类 Mouse

文件Mouse.java

public class Mouse {
    private String brand;
    private double price;

    public Mouse(String brand, double price) {
        this.brand = brand;
        this.price = price;
    }
    // getter/setter 省略...
    public void showInfo() {
        System.out.println("品牌:" + brand + ",价格:" + price);
    }
}

4.3 实现类 LogiMouse(罗技鼠标)

文件LogiMouse.java

// 继承父类 Mouse + 实现 Usb 接口
public class LogiMouse extends Mouse implements Usb {

    public LogiMouse(String brand, double price) {
        super(brand, price);
    }

    @Override
    public void startUsb() {
        System.out.println("罗技鼠标启动");
    }

    @Override
    public void useUsb() {
        System.out.println("罗技鼠标使用");
    }

    @Override
    public void stopUsb() {
        System.out.println("罗技鼠标关闭");
    }
}

4.4 实现类 ROGMouse(ROG 鼠标)

文件ROGMouse.java

public class ROGMouse extends Mouse implements Usb {
    public ROGMouse(String brand, double price) {
        super(brand, price);
    }

    @Override
    public void startUsb() {
        System.out.println("ROG鼠标启动");
    }

    @Override
    public void useUsb() {
        System.out.println("ROG鼠标使用");
    }

    @Override
    public void stopUsb() {
        System.out.println("ROG鼠标关闭");
    }
}

4.5 测试类 Test04

文件Test04.java

public class Test04 {
    public static void main(String[] args) {
        LogiMouse lm = new LogiMouse("罗技", 13.6);
        lm.showInfo();   // 调用父类 Mouse 的方法
        lm.startUsb();   // 实现 Usb 接口的抽象方法
        lm.useUsb();     // 实现 Usb 接口的抽象方法
        lm.stopUsb();    // 实现 Usb 接口的抽象方法
    }
}

预期输出

品牌:罗技,价格:13.6
罗技鼠标启动
罗技鼠标使用
罗技鼠标关闭

5. 继承与接口的实现关系图

        ┌──────────┐          ┌──────────┐
        │  Mouse   │          │   Usb    │
        │ (父类)   │          │ (接口)   │
        └────┬─────┘          └────┬─────┘
             │ extends             │ implements
    ┌────────┴──────────┐          │
    │                   │          │
┌───┴────────┐   ┌──────┴─────┐    │
│ LogiMouse  │   │  ROGMouse  ├────┘
│ extends    │   │  extends   │
│ Mouse      │   │  Mouse     │
│ implements │   │  implements│
│ Usb        │   │  Usb       │
└────────────┘   └────────────┘

6. 接口的补充特性

文件Demo05.java

  • 类与接口:一个类虽然只能继承一个父类,但是可以同时 实现多个接口
  • 接口与接口:接口之间可以 多继承(一个子接口可以继承多个父接口)

    // 类实现多个接口
    public class MyClass implements InterfaceA, InterfaceB, InterfaceC {
    // 必须重写所有接口中的抽象方法
    }
    
    // 接口继承多个接口
    public interface SubInterface extends InterfaceA, InterfaceB {
    // 子接口继承多个父接口的方法
    }
    

八、随堂练习要点

练习目标:理解抽象类、接口、代码块的基本使用

  1. 定义抽象父类:使用 public abstract class 声明,定义抽象方法时不要写方法体
  2. 实现具体子类:使用 extends 继承抽象类,使用 @Override 重写所有抽象方法
  3. 测试类验证:创建子类对象,调用重写后的方法验证正确性

九、面试常见问题

Q1:抽象类能不能被实例化?

不能。抽象类不能直接 new 创建对象。

Q2:抽象类中一定要有抽象方法吗?

不一定。抽象类中可以没有抽象方法,但有抽象方法的类必须是抽象类。

Q3:抽象类的子类必须重写所有抽象方法吗?

不一定。子类有两个选择:① 重写父类所有抽象方法变为具体子类;② 子类也声明为抽象类,继承父类的抽象方法。

Q4:抽象类可以有构造方法吗?

可以。虽然抽象类不能直接创建对象,但其构造方法可以在子类实例化时通过 super() 调用,用于初始化父类成员。

Q5:abstractfinal 能否同时修饰一个类或方法?

不能。abstract 表示需要被继承/重写,final 表示不能被继承/重写,二者语义冲突。

Q6:final 修饰引用类型变量时,对象内容还能修改吗?

可以。final 修饰引用类型变量时,只是保证引用地址不变(不能重新指向其他对象),但该对象内部的成员变量仍然可以通过 setter 修改。

Q7:final 修饰的类有哪些常见例子?

String 类、Math 类、Integer 等包装类都是用 final 修饰的,它们不能被继承。

Q8:什么是模板方法设计模式?它的核心思想是什么?

模板方法模式(Template Method Pattern)是抽象类的经典应用场景。核心思想是:父类定义算法的「骨架」(通用结构),子类实现特定的「步骤」(定制化需求)。父类中的模板方法用 final 修饰禁止重写,抽象方法用 abstract 修饰强制子类实现。

Q9:模板方法模式中,模板方法为什么用 final 修饰?

为了防止子类篡改算法的执行流程。如果模板方法不被 final 修饰,子类可以重写它,破坏父类定义好的步骤结构,失去了「模板」的意义。

Q10:Java 中的代码块有哪几种?它们的执行顺序是什么?

有三种:① 静态代码块(static {})② 构造代码块({})③ 局部代码块(方法内的 {})。执行顺序:静态代码块(类加载时执行一次)→ 构造代码块(每次创建对象时执行,在构造方法之前)→ 构造方法(含内部的局部代码块)。

Q11:构造代码块有什么作用?

构造代码块可以把多个构造方法中共同的代码提取出来,避免重复。每次创建对象时,构造代码块会在构造方法之前自动执行,无论调用的是哪个重载的构造方法。

Q12:接口和抽象类有什么区别?

① 关键字不同:抽象类是 abstract class,接口是 interface;② 构造方法:抽象类可以有,接口不能有;③ 成员变量:抽象类可以是任意类型,接口只能是 public static final 常量;④ 成员方法:抽象类可以有抽象/非抽象方法,接口只能是 public abstract 抽象方法;⑤ 子类方式:抽象类用 extends 继承,接口用 implements 实现;⑥ 单/多:抽象类是单继承,接口可以同时实现多个。

Q13:一个类可以同时继承一个父类并实现多个接口吗?

可以。Java 中的类虽然只能单继承(一个父类),但可以同时实现多个接口。格式:public class 子类 extends 父类 implements 接口1, 接口2 { ... }

Q14:接口中的变量默认使用什么修饰符?方法呢?

接口中的变量默认使用 public static final 修饰(公开的静态常量),方法默认使用 public abstract 修饰(公开的抽象方法)。

Q15:接口为什么不能实例化?接口有构造方法吗?

接口没有构造方法,因此不能实例化(不能创建对象)。接口是一种规范标准,需要通过实现类来提供具体的功能实现。


十、拓展阅读