抽象类和接口是面向对象编程中常用的概念,它们都用于定义类的行为和约束,但在一些方面有明显的差异。下面是抽象类和接口的共同点和不同点的详细介绍:
共同点:
-
都是用于实现多态性:抽象类和接口都支持多态性,可以在不同的类中实现相同的抽象方法或接口方法,从而实现不同类的对象具有相同的行为。
-
都不能被实例化:抽象类和接口都不能直接实例化,只能通过子类来实现抽象类的具体方法或接口的方法。
-
都可以被继承或实现:抽象类可以被子类继承,而接口可以被类实现。
-
都可以包含抽象方法:抽象类可以包含抽象方法,这些方法只有声明而没有具体实现;接口中的方法也没有具体的实现,都只有方法签名。
不同点:
-
关键字不同:在Java中,抽象类使用abstract关键字进行声明,而接口使用interface关键字进行声明。
-
实现方式不同:一个类只能继承一个抽象类,而可以实现多个接口。通过继承抽象类,子类可以获得抽象类中的属性和方法的实现;而通过实现接口,类需要提供接口中所有方法的具体实现。
-
方法类型不同:抽象类可以包含抽象方法和非抽象方法,非抽象方法可以有具体的实现;接口中只能包含抽象方法和默认方法(Java 8及以后的版本),默认方法有默认的实现。
-
语义不同:抽象类用于表示一种"是什么"的关系,用于对类的共性进行抽象;而接口用于表示一种"具有什么能力"的关系,用于对行为的抽象。
-
关联关系不同:抽象类可以拥有实例变量,可以在构造函数中进行初始化;接口只能包含静态常量,不能拥有实例变量。
总体而言,抽象类更适合于表示一种层次结构和共性,而接口更适合于定义一组相关的操作和行为能力。使用抽象类还是接口取决于具体的设计需求和设计目标。
另外,在这里记录两个点(关于接口中方法和字段的修饰符省略):
- 在Java中,使用interface可以声明一个接口:
interface Person {
void run();
String getName();
}
所谓interface,就是比抽象类还要抽象的纯抽象接口,因为它连字段都不能有。因为接口定义的所有方法默认都是public abstract的,所以这两个修饰符不需要写出来(写不写效果都一样)。
2. 因为interface是一个纯抽象类,所以它不能定义实例字段。但是,interface是可以有静态字段的,并且静态字段必须为final类型:
public interface Person {
public static final int MALE = 1;
public static final int FEMALE = 2;
}
实际上,因为interface的字段只能是public static final类型,所以我们可以把这些修饰符都去掉,上述代码可以简写为:
public interface Person {
// 编译器会自动加上public statc final:
int MALE = 1;
int FEMALE = 2;
}
编译器会自动把该字段变为public static final类型。