个人理解
当所有的类都有的相同的行为,可以提取为Base类或抽象类,因为如果采用接口的方式,所有的子类都需要重复的实现这个行为,而抽象类的某些行为能有default的实现,但当不同的类对相同的行为有不同的动作时,应采用Interface。抽象类的演化比接口的演变要容易得多,但Java只允许单继承,抽象类作为类型定义收到了极大的限制。所以使用接口优于抽象类。但当演变的容易性比灵活性和功能更为重要的时候。应使用抽象类来定义类型。
使用接口现有的类可以很容易被更新,以实现新的接口,如果需要增加新的方法,只需要在类的声明中增加一个implements方法。
skeletal implementation1.
骨架实现(skeletal implementation),能将接口和抽象类的优点结合起来。Collections就为集合接口都提供了一个骨架实现。
下例中AbstractFoo是一个骨架类,它实现了IFoo接口,并实现了其中的我认为以后大家会公用的基础方法foo(),又增了自己独有的方法,setVal()和getVal()方法。而另一个接口叫IBar,我想让它具有IFoo的属性,又有一些自己的个性,这时让它继承IFoo接口,然后增加自己独有的方法bar()。最后,我定义一个实例,让它继承AbstractFoo,并实现IBar,这样,它就不用重新一一定义IFoo接口中的方法,因为骨架类(AbstractFoo)已经有基础的方法了,它只需要实现不共用的方法即可。
另外,公开的接口,如IFoo是不能修改的,以后我发现还有些公共的东西能加进来,怎么办呢?我可以在骨架类(AbstractFoo)中设置新的方法,让子类继承就ok了,如例子中的setVal()和getVal()方法,这样,在Test中,我完全可以定义一个FooBar实例,然后调用新增加的setVal()和getVal()方法.这就很好的达到了复用的目的。这里也呈现出抽象类的一个好处。
骨架类(AbstractFoo)是个抽象类,它实现了IFoo接口,但是可以选择地实现它的方法,并不需要全部实现,因为接口本质上也是抽象类。另外,抽象类可以定义已经实现的方法,所以就可以增加一些“基础方法”,供子类调用。
骨架实现类是为了继承的目的而设计的,必须认真研究接口,并确定哪些方法是最为基本的(primitive),其他的方法则可以根据他们来实现。这些基本方法将成为骨架实现类中的抽象方法,然后为接口中所有其他的方法提供具体的实现。
public interface IFoo {
void foo();
void add();
void del();
}
public interface IBar extends IFoo {
void bar();
}
public abstract class AbstractFoo implements IFoo {
private String val;
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
public void foo() {
System.out.println("AbstarctFoo");
}
}
public class FooBar extends AbstractFoo implements IBar{
@Override
public void bar() {
//Auto-generated method stub
}
@Override
public void add() {
//Auto-generated method stub
}
@Override
public void del() {
//Auto-generated method stub
}
}
抽象类实现接口2.
抽象类可以不用实现接口的全部方法,有的时候需要将接口和抽象类配合起来使用,这样可以为开发者提供相当的便利性,开发者觉得哪个方便就选用哪个。这样的抽象类称为便利类。此时,便利类并不需要实现接口的所有方法,可以留给继承它的子类去实现它们。
这么做并非是没有意义的,当你自己写的类想用接口中个别方法的时候(注意不是所有的方法),那么你就可以用一个抽象类先实现这个接口(方法体中为空),然后再用你的类继承这个抽象类,这样就可以达到你的目的了,如果你直接用类实现接口,那是所有方法都必须实现的。