抽象类与接口
前几天项目里用到接口,虽然学过可是没去实际使用过,感觉还是很模糊。
今天周末难得休息,自己总结下:
1. 测试了发现对于接口来说,他里面的方法与属性的定义是固定的,否则会报编译时错误:
只能写成形如以下形式:
public abstract interface Goul
{
public abstract void f();
public static final int i = 1;
}
黑体字如更改就会包编译期错误,但是可省略不写。
2 测试了下抽象类,一般只包括抽象方法,但是同时你也可以实现部分方法
public abstract class Goul
{
public|protected abstract void f();
public|protected void g()
{
}
public|protected int i;
}
3.抽象类与接口目前认为好处有2:
(1)方便扩展代码以及代码的复用:将大家有可能公用的东西提出来,然后大家都去实现统一的接口。
(2)代码的统一,多人开发使用同一接口,可以使大家的代码保持一致。
4.搜索了下,发现虽然接口像是一个特殊的抽象类,但是区别实际还是蛮大的,详细参考:http://dev.yesky.com/436/7581936.shtml
(1)在面向对象领域,抽象类主要用来进行类型隐藏。 我们可以构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。
(2)在abstract class的定义中,我们可以赋予方法的默认行为。但是在interface的定义中,方法却不能拥有默认行为,为了绕过这个限制,必须使用委托,但是这会增加一些复杂性,有时会造成很大的麻烦。在 抽象类中不能定义默认行为还存在另一个比较严重的问题,那就是可能会造成维护上的麻烦。因 为如果后来想修改类的界面(一般通过 abstract class 或者interface来表示)以适应新的情况(比如,添加新的方法或者给已用的方法中添 加新的参数)时,就会非常的麻烦,可能要花费很多的时间(对于派生类很多的情况,尤为如此)。但是如果界面是通过abstract class来实现的,那 么可能就只需要修改定义在abstract class中的默认行为就可以了。
同样,如果不能在抽象类中定义默认行为,就会导致同样的方法实现出现在该抽象类的每一个派生类中,违反了 "one rule,one place" 原则,造成代码重复,同样不利于以后的维护。因此,在abstract class和interface间进行选择时要非常的小心。
(3)其 实abstract class表示的是"is-a"关系,interface表示的是"like-a"关系,大家在选择时可以作为一个依据,当然这是建立在对问题领域的理解上的,比如:如果我们认为AlarmDoor在概念本质上是报警器,同时又具有Door的功能,那么上述的定义方式就要反过来了。