抽象基类:

通常在如下两种情况下,会使用抽象基类:

1、当多数类都拥有多个相同类型的属性时,通常会选择使用抽象基类,并将这些类中相同类型的属性都放在抽象基类中来声明,当这些类内部需要使用这些属性时,可以通过抽象基类针对这些属性开放的方法类读取。

比如:

public abstract class AbstractAnimal {

private String name;

public Stirng getName(){

return this.name;

}

}
public class Elephant extends AbstractAnimal {
}

public class Snake extends AbstractAnimal {
}

2、当多数类都拥有多个相似的处理流程时,通常也会选择抽象基类,并将这些类中相似的操作都放在抽象基类中,然后在流程中使用到的属性数据,都通过抽象方法,从具体子类中提取。

public abstract class AbstractAnimal {

public void feed(){

this.drink(getName());

}

protected abstract String getName();

private void drink(String name){

... ...

}

}

public class Elephant extends AbstractAnimal {

@Override
protected String getName(){

return "elephant";

}

}

public class Snake extends AbstractAnimal {

@Override
protected String getName(){

return "snake";

}

}

3、接口通常用于对具体的类进行区分,当某类实现了某些口,该类就拥有该接口开放的所有执行方法,同样通过判断某类是否实现了某些口,可以将该类转换成目标接口,并将该类当作该接口代表的类型,进行处理。

例如:

//野兽
public interface Wild{
}

//冷血的
public interface Coldblooded{
}

public interface Animal {
}

public class Elephant implements Animal,Wild{
}

public class Snake implements Animal,Wild,Coldblooded {
}

public class Tiger implements Animal,Wild{
}

这样,当判断某类是否为某接口,即可为该类进行分类操作。

比如:

List<Animal> animals = new ArrayList<Animal>();

animals.add(new Elephant());

animals.add(new Snake());

animals.add(new Tiger());

for(Animal animal : animals){

if(animal instanceof Wild){

... ...

}

if(animal instanceof Coldblooded){

... ...

}

}