抽象类
1. 抽象类 vs 普通类
| 特性 | 抽象类 | 普通类 |
|---|---|---|
| 方法类型 | 可包含抽象方法和普通方法 | 只能包含普通方法 |
| 实例化 | 不能被实例化 | 可直接实例化 |
| 继承要求 | 子类必须实现所有抽象方法 | 无特殊要求 |
示例:
// 抽象类定义
abstract class Animal {
// 抽象方法(无实现)
public abstract void makeSound();
// 普通方法(有实现)
public void sleep() {
System.out.println("Animal is sleeping");
}
}
// 子类实现
class Dog extends Animal {
@Override
public void makeSound() { // 必须实现抽象方法
System.out.println("Woof!");
}
}
// 使用
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.makeSound(); // 输出: Woof!
dog.sleep(); // 输出: Animal is sleeping
// Animal a = new Animal(); // 错误!抽象类不能实例化
}
}
2. 抽象类的限制
| 限制项 | 说明 | 示例 |
|---|---|---|
| 实例化 | 不能直接创建对象 | new Animal() → 编译错误 |
| 多态支持 | 可通过子类实现多态 | Animal a = new Dog() |
| 构造方法 | 可以有构造器(供子类初始化) | 见下方示例 |
构造方法示例:
abstract class Vehicle {
private String type;
// 抽象类的构造方法
public Vehicle(String type) {
this.type = type;
}
public abstract void move();
public void showType() {
System.out.println("Vehicle type: " + type);
}
}
class Car extends Vehicle {
public Car() {
super("Land"); // 调用父类构造器
}
@Override
public void move() {
System.out.println("Car is driving");
}
}
// 使用
Vehicle v = new Car();
v.showType(); // 输出: Vehicle type: Land
3. 修饰符冲突规则
| 组合 | 是否允许 | 原因 |
|---|---|---|
abstract + final | ❌ | final禁止继承,abstract要求继承 |
abstract + private | ❌ | private方法不可见,无法被重写 |
abstract + static | ❌ | static方法属于类,abstract方法需要实例实现 |
错误示例:
abstract class Test {
// 以下声明均会编译失败
public abstract final void method1(); // final+abstract冲突
private abstract void method2(); // private+abstract冲突
static abstract void method3(); // static+abstract冲突
}
4. 子类继承规则
-
规则:子类必须实现所有抽象方法,否则自身需声明为
abstract -
应用场景:构建多层继承体系时部分实现功能
多级继承示例:
abstract class Shape {
public abstract double area();
}
abstract class Polygon extends Shape { // 未实现area(),需保持抽象
public abstract int getSides();
}
class Rectangle extends Polygon {
private double width, height;
public Rectangle(double w, double h) {
this.width = w;
this.height = h;
}
@Override
public double area() { // 实现顶层抽象方法
return width * height;
}
@Override
public int getSides() { // 实现父层抽象方法
return 4;
}
}
接口
1. 核心特性
| 特性 | 说明 | 默认修饰符 |
|---|---|---|
| 成员变量 | 自动为public static final | 常量(必须初始化) |
| 方法 | 自动为public abstract | Java 8+支持默认/静态方法 |
| 构造函数 | 不允许 | 无构造器 |
示例:
interface USB {
// 常量(自动public static final)
int MAX_VOLTAGE = 5;
// 抽象方法(自动public abstract)
void transferData();
// 默认方法(Java 8+)
default void powerOn() {
System.out.println("USB device powered on");
}
}
class FlashDrive implements USB {
@Override
public void transferData() {
System.out.println("Transferring data at 100MB/s");
}
}
// 使用
USB drive = new FlashDrive();
drive.powerOn(); // 调用默认方法
System.out.println(USB.MAX_VOLTAGE); // 访问常量
2. 接口的限制
| 限制项 | 说明 | 示例 |
|---|---|---|
| 实例化 | 不能直接实例化 | new USB() → 编译错误 |
| 方法实现 | 实现类需实现所有抽象方法 | 除非实现类是抽象类 |
| 多实现 | 类可实现多个接口 | class A implements B, C |
多接口实现示例:
interface Flyable {
void fly();
}
interface Swimmable {
void swim();
}
class Duck implements Flyable, Swimmable {
@Override
public void fly() {
System.out.println("Duck flying low");
}
@Override
public void swim() {
System.out.println("Duck paddling in water");
}
}
// 使用
Duck donald = new Duck();
donald.fly(); // 输出: Duck flying low
donald.swim(); // 输出: Duck paddling in water
3. 接口继承
-
单继承:接口只能继承一个父接口
-
多级继承:支持接口链式继承
-
多继承变通:通过继承多个父接口实现功能组合
接口继承示例:
interface Animal {
void eat();
}
interface Bird extends Animal { // 接口单继承
void chirp();
}
interface FlyingCreature {
void takeOff();
}
// 通过实现多接口模拟多继承
class Sparrow implements Bird, FlyingCreature {
@Override
public void eat() {
System.out.println("Eating seeds");
}
@Override
public void chirp() {
System.out.println("Chirp chirp!");
}
@Override
public void takeOff() {
System.out.println("Flapping wings to fly");
}
}
接口应用:排序
1. Comparable 接口(自然排序)
class Student implements Comparable<Student> {
String name;
int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Student other) {
// 按年龄升序排序
return this.age - other.age;
}
@Override
public String toString() {
return name + "(" + age + ")";
}
}
// 使用
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 20));
students.add(new Student("Bob", 18));
students.add(new Student("Charlie", 22));
Collections.sort(students); // 使用Comparable排序
// 输出: [Bob(18), Alice(20), Charlie(22)]
System.out.println(students);
}
}
2. Comparator 接口(灵活排序)
// 姓名比较器
class NameComparator implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
return s1.name.compareTo(s2.name);
}
}
// 使用
public class Main {
public static void main(String[] args) {
List<Student> students = ... // 同上
// 使用自定义比较器按姓名排序
Collections.sort(students, new NameComparator());
// 输出: [Alice(20), Bob(18), Charlie(22)]
System.out.println(students);
// Java 8+ Lambda简化:按年龄降序
Collections.sort(students, (s1, s2) -> s2.age - s1.age);
}
}
关键对比总结
| 特性 | 抽象类 | 接口 |
|---|---|---|
| 方法实现 | 可包含实现方法 | Java 8前只能有抽象方法 |
| 多继承 | 单继承(extends) | 多实现(implements) |
| 构造函数 | 有 | 无 |
| 成员变量 | 无限制 | 自动为public static final |
| 设计目的 | 代码复用(is-a关系) | 行为规范(has-a能力) |
使用场景建议:
-
使用抽象类:需要共享代码、定义公共状态、控制子类构造
-
使用接口:定义行为契约、实现多态、支持多重行为继承

被折叠的 条评论
为什么被折叠?



