1、当一个接口中有很多抽象方法,并且其有很多实现类,但是有些类不需要接口中某些方法。这样就会造成大量冗余的实现接口的方法。
比如:
改进前:
接口
public interface TestInterface{
void method1();
int method2();
boolean method3();
}
实现类1:
public class TestClass1 implements TestInterface{
public void method1(){
}
public int method2(){
return 1;
}
public int method3(){
return true;
}
}
实现类2:
public class TestClass2 implements TestInterface{
public void method1(){
}
public int method2(){
return 1;
}
public int method3(){
return true;
}
}
可以发现:两个实现类必须都要实现接口中的所有方法,如果实现类2只需要拥有method1方法的功能,这样就会造成代码冗余。如果接口的方法很多,实现类的也很多,那么就会造成大量不必要的方法重写。
改进后:
增加一个抽象类:
public abstract class TestAbstract implements TestInterface{
//找出接口中必要的方法,也就是子类必须实现的方法,定义成抽象方法,交由子类实现
public abstract void method1();
public abstract int method2();
//一些独特的方法可以在抽象类中默认实现
public boolean method3(){
return true;
}
}
实现类1:
public class TestClass1 extends TestAbstract {
public void method1(){
}
public int method2(){
return 1;
}
//重写抽象类中的方法
public int method3(){
return false;
}
}
实现类2:
public class TestClass2 extends TestAbstract {
public void method1(){
}
public int method2(){
return 1;
}
}
可以发现:实现类2中只需要实现接口中的必要的方法就ok。
通过接口和抽象类的结合,避免了在实现接口的子类中出现大量的“无意义”实现,这个“无意义”实现,被缓冲到了抽象类中,完美展现了代码复用(可以把抽象类理解成接口和实现类之间的缓冲)。
这样做的好处不仅仅是这一点,细细品味,假如我们向接口中增加了一个方法。。。
向接口中新增的方法,可以在实现接口的抽象类中缓冲一下,提供一个默认的实现,这样一来,就不必强制所有的子类(通过继承抽象类间接实现接口的类)都进行修改,可以形象的理解为“没有惊动子类”。而需要使用这个方法的子类,直接重写即可。
接口和抽象类结合,产生了优雅的缺省适配模式。