接口、普通类和抽象类有什么区别和共同点
普通类用于描述具体的对象,抽象类用于定义具有共性的基类,而接口则用于定义行为规范。
区别
- 接口(Interface):
- 完全抽象,仅定义方法签名(JDK 8+ 可有默认/静态方法),无状态。
- 普通类(Concrete Class):
- 可实例化,包含完整实现,兼有属性和方法。
- 抽象类(Abstract Class):
- 部分抽象,可有抽象方法和实现,带状态但不可实例化。
共同点
- 都是类层次结构的一部分。
- 可定义方法和属性。
- 支持继承或实现关系。
1. 区别详解
(1) 定义与用途
- 接口:
- 定义规范,强制实现类遵守(如
Runnable
)。 - JDK 8+:支持
default
和static
方法。 - 普通类:
- 完整功能实现,直接使用(如
String
)。 - 抽象类:
- 提供模板,部分方法待子类实现(如
AbstractList
)。
(2) 方法实现
- 接口:
- 方法默认抽象(无实现)。
- JDK 8+:
default
方法有实现,static
方法静态调用。 - 普通类:
- 所有方法需实现(除非留空)。
- 抽象类:
- 可混有抽象方法(
abstract
)和实现方法。
(3) 实例化
- 接口:不可实例化,只能实现。
- 普通类:可直接
new
。 - 抽象类:不可实例化,需子类继承。
(4) 继承与实现
- 接口:
- 类可多实现(
implements
)。 - 接口可多继承(
extends
)。 - 普通类:
- 单继承(
extends
)。 - 抽象类:
- 单继承(
extends
)。
(5) 属性
- 接口:
- 只能有静态常量(
public static final
)。 - 普通类:
- 可有任意属性(实例/静态)。
- 抽象类:
- 可有任意属性。
(6) 构造器
- 接口:无构造器。
- 普通类:有构造器。
- 抽象类:有构造器(子类调用)。
示例
// 接口
interface Animal {
void eat(); // 抽象方法
default void sleep() { System.out.println("Sleeping"); }
}
// 抽象类
abstract class Bird {
int age; // 属性
Bird(int age) { this.age = age; } // 构造器
abstract void fly(); // 抽象方法
void sing() { System.out.println("Singing"); } // 实现
}
// 普通类
class Sparrow extends Bird implements Animal {
Sparrow(int age) { super(age); }
public void eat() { System.out.println("Eating"); }
public void fly() { System.out.println("Flying"); }
}
2. 共同点
- 封装性:
- 都可定义方法和属性(接口属性限静态)。
- 继承关系:
- 普通类和抽象类可继承,接口可被实现。
- 多态性:
- 可作为引用类型,支持向上转型。
- 如
Animal a = new Sparrow(1);
。
- 如
- 访问控制:
- 支持
public
、protected
等修饰符。 - Java 体系:
- 都属于面向对象设计。
3. 对比表格
特性 | 接口 | 普通类 | 抽象类 |
---|---|---|---|
实例化 | 不可 | 可 | 不可 |
方法 | 抽象 + 默认/静态 | 全实现 | 抽象 + 实现 |
属性 | 静态常量 | 任意 | 任意 |
继承 | 多实现/多继承 | 单继承 | 单继承 |
构造器 | 无 | 有 | 有 |
用途 | 规范 | 实现 | 模板 |
4. 延伸与面试角度
- 设计选择:
- 接口:定义行为(如
Comparable
)。 - 抽象类:共享代码(如
AbstractCollection
)。 - 普通类:具体对象(如
ArrayList
)。 - JDK 8+ 影响:
- 接口
default
方法模糊与抽象类界限。 - 实际应用:
- 接口:插件化(如
List
)。 - 抽象类:框架基类(如
HttpServlet
)。 - 面试点:
- 问“区别”时,提方法和继承。
- 问“场景”时,提规范 vs 模板。
总结
接口注重规范(全抽象),普通类提供实现(可实例化),抽象类兼顾模板(部分抽象)。共同点在于支持面向对象特性。面试时,可举代码或提设计意图,展示理解深度。