抽象基类:
通常在如下两种情况下,会使用抽象基类:
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){
... ...
}
}