您的位置:首页 > 其它

抽象类与接口的应用以及区别

2011-10-30 17:46 447 查看
“要么读书,要么旅行,灵魂和身体,必须有一个在路上”。每每听人说生活如何无聊,如何找不到事做,我总会禁不住发自内心地**一下。为什么会感到无聊和空虚,会害怕孤独?不过是没有找到值得追求的东西罢了。平凡的人往往沉迷于一时的安稳而不思进取,纠缠于一时的琐事而禁锢在自己的小世界中,而如此,如何能有另人刮目相看的资本呢?这是最近的一些生活感想。

在面向对象的思想中,一切皆对象,所有的对象都是通过类来描绘的。但反过来,并非所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。抽象类往往用来表征我们在对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象。因为抽象的概念在问题领域没有对应的具体概念,所以用以表征抽象概念的抽象类是不能够实例化的。通过继承,造就了对象的多态性。这里有一个原则需要把握:不要试图去继承一个已经实现好的类,尽管这是被允许的。

abstract class 和 interface 是 Java 语言中对于抽象类定义进行支持的两种机制,这两种机制赋予了 Java 强大的面向对象能力。abstract class 和 interface 之间在对于抽象类定义的支持方面具有很大的相似性,也有很大的区别。对于它们的选择甚至反映出对于问题领域本质的理解。下面是他们之间关系的简单总结。

抽象类和接口之间的关系:

1 定义:抽象类为包含抽象方法(其实不是必须的)的类;而接口则是全局常量(static & final)和抽象方法的集合。

2 组成:抽象类可包括构造函数、抽象方法、普通方法(可有可无)、常量(可有可无)、变量(可有可无);而接口仅包括常量(可有可无)、抽象方法。

3 使用:子类通过关键字 extends 继承抽象类;子类通过关键字 implements 实现接口。

4 关系:抽象类可以实现接口;而接口也可以实现接口,但不允许继承抽象类。

5 对象:抽象类和接口都不能直接实例化,但可以通过对象的多态性产生实例化对象,即利用其之类的对象来进行实例化。

6 限制:抽象类的继承受到单继承的限制,即一个子类只能继承一个抽象类;接口无此限制,即一个子类可以同时实现多个接口。

7 思想:抽象类作为一个模板而存在,子类对抽象类的继承表达了该子类的本质,即“b is a”;而接口表示的是一种标准和能力,之类对接口的实现表示该之类具有某种能力。

8 选择:很多时候,我们面临着抽象类和接口的选择问题,这时不要随性而为,而应当根据 [ 6 限制、7 思想 ] 两条来做权衡,能否做出合理的选择反应了我们对问题本质的理解。

示例:

/**
* 人类
* 人类真是太抽象了!
* @author dancen
*
*/
abstract class Human
{
private String name;
private int age;

public Human(String name, int age)
{
this.setName(name);
this.setAge(age);
}

public void setName(String name)
{
this.name = name;
}

public String getName()
{
return this.name;
}

public void setAge(int age)
{
this.age=age;
}

public int getAge()
{
return this.age;
}

abstract void speak();
abstract void laugh();
}


/**
* 学习
* @author dancen
*
*/
interface Study
{
void readBooks ();
void makeNotes ();
}


/**
* 旅游
* @author dancen
*
*/
interface Travel
{
/**
* 各种旅行方式
*/
static final String TYPE_FOOT="on foot";
static final String TYPE_CAR="by car";
static final String TYPE_SHIP="by ship";
static final String TYPE_PLANE="by plane";

void toDestination(String desName,String type);
void returnHome();
}


/**
* 强大的中国人
* @author dancen
*
*/
class ChinesePeople extends Human implements Study,Travel
{
public static final String COUNTRY = "China";

private String chineseID;	//臭名昭著的身份证号

public ChinesePeople(String name , int age , String chineseID)
{
super(name , age);
this.setChineseID(chineseID);	//必须有身份证,否则就是黑人
}

public void setChineseID(String chineseID)
{
this.chineseID=chineseID;
}

public String getChineseID()
{
return this.chineseID;
}

public String getCountry()
{
return ChinesePeople.COUNTRY;
}

/**
* 实现父类 Human 中的抽象方法
*/
public void speak()
{
System.out.println(this.getName()+" is speaking ...");
}

/**
* 实现父类 Human 中的抽象方法
*/
public void laugh()
{
System.out.println(this.getName()+" is laughing ...");
}

/**
* 实现接口 Study 中的抽象方法
*/
public void readBooks()
{
System.out.println(this.getName()+" can study by reading books ...");
}

/**
* 实现接口 Study 中的抽象方法
*/
public void makeNotes()
{
System.out.println(this.getName()+" can study by making notes ...");
}

/**
* 实现接口 Travel 中的抽象方法
* @param desName
*/
public void toDestination(String desName , String type)
{
System.out.println(this.getName()+" will travel to "+desName+" "+type+" ...");
}

/**
* 实现接口 Travel 中的抽象方法
*/
public void returnHome()
{
System.out.println(this.getName()+" return home ...");
}
}


public class Test
{
public static void main(String[] args)
{
test();
}

public static void test()
{
ChinesePeople cp = new ChinesePeople("小明", 5 ,"530381199911110550");

System.out.println(cp.getName()+" 的国籍是 "+cp.getCountry());
System.out.println(cp.getName()+" 的身份证号是 "+cp.getChineseID());
cp.speak();
cp.laugh();
cp.readBooks();
cp.makeNotes();
cp.toDestination("昆明",Travel.TYPE_CAR);
cp.returnHome();
}
}


输出结果:

小明 的国籍是 China

小明 的身份证号是 530381199911110550

小明 is speaking ...

小明 is laughing ...

小明 can study by reading books ...

小明 can study by making notes ...

小明 will travel to 昆明 by car ...

小明 return home ...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: