接口隔离原则表示一个类对另一个类的依赖应该建立在最小的接口上。也就是说,一个接口应该尽可能的小,只包含它需要的方法,而不是包含一些不相关的方法。
接口隔离原则是面向接口编程的重要原则之一,它体现了接口的粒度和单一性。如果一个软件能够遵循接口隔离原则,那么它就具有以下两个优点:
举个例子,假设我们有一个动物类 Animal,它有一个方法 eat(),表示动物可以吃东西。然后我们定义了一个狗类 Dog 和一个鱼类 Fish 来继承 Animal 类,并实现 eat() 方法。但是,我们发现鱼类还有一个 swim() 方法,表示鱼可以游泳。这个方法和 eat() 方法没有什么关系,但是却被放在了同一个接口中。代码如下:
interface Animal {
public void eat();
public void swim();
}
class Dog implements Animal {
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public void swim() {
// 狗不一定会游泳,这个方法对狗来说没有意义
throw new UnsupportedOperationException();
}
}
class Fish implements Animal {
@Override
public void eat() {
System.out.println("鱼吃虾米");
}
@Override
public void swim() {
System.out.println("鱼在水里游");
}
}
这个类违反了接口隔离原则,因为它将两个不相关的方法放在了同一个接口中,导致接口臃肿和污染。这样的设计有以下几个缺点:
为了遵循接口隔离原则,我们应该将 Animal 接口拆分为两个接口:Eatable 和 Swimmable。Eatable 接口只包含 eat() 方法,Swimmable 接口只包含 swim() 方法。然后,根据不同的动物类型和行为,实现不同的接口。这样,在程序中可以根据需要选择实现哪些接口,而不强制实现不必要的接口。代码如下:
interface Eatable {
public void eat();
}
interface Swimmable {
public void swim();
}
class Dog implements Eatable {
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
class Fish implements Eatable, Swimmable {
@Override
public void eat() {
System.out.println("鱼吃虾米");
}
@Override
public void swim() {
System.out.println("鱼在水里游");
}
}
// 其他动物类型和行为的实现类省略