一、抽象类(Abstract Class)
1. 核心概念
- 抽象类是用 abstract关键字修饰的类,不能被实例化,只能被继承。
- 可以包含抽象方法(没有方法体的方法)和具体方法。
- 作用:定义模板,强制子类实现抽象方法,实现代码复用。
2. 特点
- 若类包含至少一个抽象方法,则类必须声明为抽象类。
- 抽象类可以有构造方法(用于初始化子类对象)。
- 子类必须实现抽象类中的所有抽象方法(除非子类也是抽象类)。
3. 示例
java
复制
// 抽象类:动物
public abstract class Animal {
    private String name;
    // 抽象方法:子类必须实现
    public abstract void makeSound();
    // 具体方法:子类可直接使用或重写
    public void sleep() {
        System.out.println(name + "在睡觉");
    }
    public Animal(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}
// 子类继承抽象类
public class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }
    @Override
    public void makeSound() {
        System.out.println(getName() + ":汪汪!");
    }
}
// 使用抽象类
public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog("旺财");
        dog.makeSound(); // 输出:旺财:汪汪!
        dog.sleep();     // 输出:旺财在睡觉
    }
}
二、接口(Interface)
1. 核心概念
- 接口是使用 interface关键字定义的纯抽象类型,不能包含具体方法(Java 8+ 支持默认方法)。
- 类通过 implements关键字实现接口,一个类可以实现多个接口(支持多继承)。
- 作用:定义行为规范,实现解耦和多态。
2. 特点
- 接口中的方法默认是 public abstract,变量默认是public static final。
- Java 8 开始支持默认方法(default方法)和静态方法。
- Java 9 开始支持私有方法。
3. 示例
java
复制
// 接口:飞行能力
 public interface Flyable {
     // 抽象方法
     void fly();
 
     // 默认方法(Java 8+)
     default void land() {
         System.out.println("降落");
     }
 
     // 静态方法(Java 8+)
     static void showInfo() {
         System.out.println("这是飞行能力接口");
     }
 }
 
 // 实现接口的类
 public class Bird implements Flyable {
     @Override
     public void fly() {
         System.out.println("鸟在飞翔");
     }
 }
 
 // 使用接口
 public class Main {
     public static void main(String[] args) {
         Bird bird = new Bird();
         bird.fly();    // 输出:鸟在飞翔
         bird.land();   // 输出:降落(来自接口默认方法)
         Flyable.showInfo(); // 输出:这是飞行能力接口
     }
 }
三、内部类(Inner Class)
1. 核心概念
- 内部类是定义在另一个类内部的类,可以访问外部类的所有成员(包括私有成员)。
- 分类: 
  - 静态内部类:用 static修饰,不依赖外部类实例。
- 非静态内部类:默认类型,依赖外部类实例。
- 匿名内部类:没有类名的内部类,通常用于实现接口或继承抽象类。
 
- 静态内部类:用 
2. 静态内部类(Static Inner Class)
- 通过外部类名访问,只能访问外部类的静态成员。
- 示例:
java
复制
public class Outer {
    private static String staticMsg = "外部类静态成员";
    // 静态内部类
    public static class StaticInner {
        public void print() {
            System.out.println(staticMsg); // 访问外部类静态成员
        }
    }
}
// 使用静态内部类
public class Main {
    public static void main(String[] args) {
        Outer.StaticInner inner = new Outer.StaticInner();
        inner.print(); // 输出:外部类静态成员
    }
}
3. 匿名内部类(Anonymous Inner Class)
- 没有类名的内部类,直接在代码中实现接口或继承抽象类。
- 适用场景:快速实现一次性使用的类。
- 示例:
java
复制
public interface Greeting {
    void sayHello();
}
public class Main {
    public static void main(String[] args) {
        // 匿名内部类实现接口
        Greeting greeting = new Greeting() {
            @Override
            public void sayHello() {
                System.out.println("你好,世界!");
            }
        };
        greeting.sayHello(); // 输出:你好,世界!
    }
}
四、抽象类 vs 接口
| 特性 | 抽象类 | 接口 | 
|---|---|---|
| 定义 | 用 abstract修饰的类 | 用 interface修饰的类型 | 
| 方法实现 | 可以包含具体方法和抽象方法 | Java 8+ 支持默认方法和静态方法 | 
| 多继承 | 单继承(一个类只能继承一个抽象类) | 多实现(一个类可实现多个接口) | 
| 设计目的 | 提取类的共性(is-a关系) | 定义行为规范(can-do关系) | 
| 构造方法 | 可以有构造方法 | 不能有构造方法 | 
五、内部类总结
| 类型 | 特点 | 示例场景 | 
|---|---|---|
| 静态内部类 | 不依赖外部类实例,只能访问外部类静态成员 | 工具类、Builder模式 | 
| 非静态内部类 | 依赖外部类实例,可访问外部类所有成员 | 事件监听、数据封装 | 
| 匿名内部类 | 没有类名,直接实现接口或继承抽象类 | 快速实现回调、临时逻辑 | 
六、综合示例
java
复制
// 抽象类与接口结合使用
public abstract class Shape {
    public abstract double area();
}
public interface Drawable {
    void draw();
}
// 静态内部类实现接口
public class Circle extends Shape {
    private double radius;
    public Circle(double radius) {
        this.radius = radius;
    }
    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
    // 静态内部类实现Drawable接口
    public static class Drawer implements Drawable {
        private Circle circle;
        public Drawer(Circle circle) {
            this.circle = circle;
        }
        @Override
        public void draw() {
            System.out.println("绘制半径为" + circle.radius + "的圆");
        }
    }
}
// 匿名内部类实现接口
public class Main {
    public static void main(String[] args) {
        Circle circle = new Circle(5);
        Drawable drawer = new Circle.Drawer(circle); // 静态内部类
        drawer.draw(); // 输出:绘制半径为5的圆
        // 匿名内部类直接实现Drawable
        Drawable anonymousDrawer = new Drawable() {
            @Override
            public void draw() {
                System.out.println("匿名内部类绘制操作");
            }
        };
        anonymousDrawer.draw();
    }
}
总结
- 抽象类:适合定义共性模板,强制子类实现特定行为。
- 接口:适合定义行为规范,支持多继承和解耦。
- 内部类:用于逻辑封装,静态内部类独立于外部类,匿名内部类简化代码。