接口(Interface)在编程中是一种规范或者契约,它定义了一组方法(在某些编程语言中还包括属性、事件等),但不提供这些方法的具体实现。接口只规定了类必须做什么,而不规定如何去做。实现接口的类必须实现接口中定义的所有方法。
1.定义要点
接口声明
接口使用特定的关键字进行声明,例如在Java中使用interface
关键字,在C#和TypeScript中也使用interface
。
方法声明
接口中定义的方法默认是抽象的(在Java中,即使不显式地写出abstract
关键字,方法也是抽象的)。这意味着接口中的方法不包含实现体,即没有大括号{}
和其中的代码。
访问修饰符
在Java中,接口中的方法默认是public
的,因此不需要(也不允许)显式地指定访问修饰符。在其他语言中,接口的访问级别可能有所不同,但通常也是公开的。
属性、事件等(取决于语言)
除了方法外,一些编程语言还允许接口定义属性(如C#中的只读或只写属性)、事件等成员。这些成员也必须是抽象的,并且在实现接口的类中必须有相应的实现。
实现
一个类通过使用特定的关键字(如Java中的implements
,C#中的:
)来声明它实现了某个接口。实现接口的类必须提供接口中所有方法的具体实现(除非该类也是抽象的)。
接口继承
接口可以继承自其他接口,这允许接口之间形成层次结构。在Java中,使用extends
关键字来表示接口之间的继承关系。
多态
接口是实现多态性的基础之一。通过接口引用,可以指向实现了该接口的任何类的实例,并在运行时调用该实例的方法。
2.接口的用途
定义规范
接口可以定义一组方法的规范,让不同的类按照相同的规范去实现这些方法。
实现多态
接口是实现多态性的关键。不同的类可以实现相同的接口,并且可以通过接口引用调用实现了该接口的类的实例。
解耦合
接口可以降低类之间的耦合度,使得代码更加灵活和易于维护。
3.接口的功能
- 定义一个可以被多个类共享的公共接口。
- 提供一个抽象层,将实现细节与接口分离。
- 允许不同的类实现相同的接口,并提供统一的方法调用方式。
4.接口的特点
- 接口中的方法都是抽象的,不能有具体的实现。
- 接口中的方法默认是
public
的,即使不写public
修饰符。 - 接口中的变量默认是
public static final
的,即它们是公开的、静态的、最终的。 - 一个类可以实现多个接口,但只能继承一个类。
5.接口的实现
在Java中,接口(Interface)的实现是通过让类使用implements
关键字来完成的。当一个类声明它实现了某个接口时,它必须提供该接口中所有方法的具体实现(除非该类本身被声明为抽象类)。
接口是一种引用类型,它是对一组方法声明的集合,但它不包含方法的实现。接口是一种形式上的契约,它规定了实现接口的类必须遵循的规则。
步骤
-
定义接口:首先,你需要定义一个接口,使用
interface
关键字,并在其中声明你想要的方法(以及其他可能的成员,如常量、默认方法、静态方法等,但这些不是必需的)。 -
实现接口:然后,你可以通过让类使用
implements
关键字来声明它实现了该接口。实现接口的类必须提供接口中所有抽象方法的具体实现。 -
编写实现代码:在实现了接口的类中,你需要为接口中声明的每个方法提供具体的实现代码。
示例
// 定义一个接口
interface Animal {
void eat();
void sleep();
}
// 实现接口的类
class Dog implements Animal {
// 实现接口中的方法
@Override
public void eat() {
System.out.println("Dog is eating");
}
@Override
public void sleep() {
System.out.println("Dog is sleeping");
}
}
// 测试类
public class Test {
public static void main(String[] args) {
// 创建Dog类的实例,并通过Animal接口引用来引用它
Animal myDog = new Dog();
// 调用接口中的方法(实际上是调用Dog类中的实现)
myDog.eat(); // 输出: Dog is eating
myDog.sleep(); // 输出: Dog is sleeping
}
}
在这个例子中,Animal
是一个接口,它声明了两个方法eat()
和sleep()
。Dog
类通过implements
关键字声明它实现了Animal
接口,并提供了这两个方法的具体实现。然后,在Test
类的main
方法中,我们创建了Dog
类的一个实例,并通过Animal
类型的引用来引用它。这展示了多态性的使用,即我们可以通过接口引用来调用实现了该接口的类的实例的方法。
注意
- 如果一个类实现了某个接口,但它没有提供接口中所有方法的具体实现,那么这个类也必须被声明为抽象类。
- 从Java 8开始,接口中可以包含默认方法和静态方法,这些方法可以有实现体。但是,实现接口的类仍然需要为接口中所有的抽象方法提供实现(除非该类也是抽象的)。
6.接口和抽象类
相同点
-
不能被实例化:接口和抽象类都不能直接实例化(创建对象),它们都是用来被其他类实现或继承的。
-
要求实现或继承的类必须实现/覆盖所有抽象方法:接口的实现类或抽象类的子类,都必须实现或覆盖接口/抽象类中的所有抽象方法,否则该类仍然为抽象类,不能被实例化。
-
支持多态:通过接口或抽象类的引用,可以指向实现了接口或继承了抽象类的子类对象,实现多态性。
不同点
- 关键字和声明方式:
- 接口使用
interface
关键字声明,实现接口的类使用implements
关键字。 - 抽象类使用
abstract class
声明,继承抽象类的子类使用extends
关键字。
- 接口使用
- 方法实现:
- 接口中的方法默认是
public abstract
的,且不能有具体的实现(在Java 8及以后版本中,接口可以包含默认方法和静态方法,但这些方法并不是接口的主要组成部分)。 - 抽象类中可以包含抽象方法(没有方法体的方法)和普通方法(有具体实现的方法)。
- 接口中的方法默认是
- 成员变量:
- 接口中的成员变量默认是
public static final
的,即它们是公开的、静态的、最终的常量,且必须被初始化。 - 抽象类中的成员变量可以是任意修饰符,且不一定是常量,也可以是变量。
- 接口中的成员变量默认是
- 继承关系:
- 一个类可以实现多个接口(Java支持多重实现),但只能直接继承一个类(包括抽象类),即Java不支持多重继承,但可以通过接口间接实现。
- 抽象类可以继承另一个抽象类。
- 设计理念:
- 接口强调的是一种规范或契约,它定义了一组方法,但不提供实现,由实现接口的类来具体实现这些方法。接口的设计理念是“has-a”(拥有)关系,即实现接口的类“拥有”接口所定义的方法。
- 抽象类则更侧重于表示一种类型或类别,它提供了一种模板或框架,让子类可以在这个基础上进行扩展和细化。抽象类的设计理念是“is-a”(是)关系,即继承抽象类的子类“是”抽象类的一种具体实现。
- 速度:
- 一般来说,抽象类在调用方法时速度会比接口稍快,因为接口在调用方法时可能需要花费额外的时间去查找具体实现。然而,这种差异在大多数情况下是可以忽略不计的,并且随着编译器的优化,这种差异可能会进一步缩小。
- 用途:
- 接口更多地被用于定义一组规范或契约,确保实现接口的类都遵循这组规范。接口是实现多态性的重要手段之一。
- 抽象类则更多地被用于定义一组紧密相关的类之间的共同特征和行为,同时提供一些默认的实现,以减少子类的工作量。抽象类也可以作为模板或框架,供子类进行扩展和定制。
结束