这段时间学习Java类库源码,发现自己对于Java的一些基本特性掌握的不是很好,例如接口与抽象类的一些特性,所以重新翻看《Core Java》,将两者的相关内容整理一下。
转载请注明出处。
————————————————————————————————————————————
————————————————————————————————————————————
Java中的接口和抽象类都是抽象机制的实现,两者有许多共同点,也有一些不同点,要注意区分。
抽象类
在继承结构中,上层的类比下层的类更具有通用性,更加抽象。有些时候,我们只想把上层类作为派生其他类的基类,而不作为特定的实例类,这时候抽象类就派上用场了。如果类中的一个方法用abstract 关键字修饰,则不需要实现这个方法,而是把实现留给继承它的类。例如:
public abstract class AbstractPerson {
public abstract String getDescription();
}
必须注意,出了抽象方法之外,抽象类还可以包含其他具体数据和具体方法(提供实现)。如下:
package cd.edu.hfut.comparable;
/**
* @author bingduanLin
*
*/
public abstract class AbstractPerson {
public abstract String getDescription();
/**
* @return
*/
public String getName() {
return this.name;
}
private String name;
}
如果一个类含有抽象方法,则类本身也必须声明为抽象的。抽象类不能被实例化,但是可以声明一个抽象类的对象变量,这个对象变量只能引用抽象子类的对象。例如,Employee类继承自Person,则可以如下声明:
Person person = new Employee()
在子类中,可以实现部分或者全部抽象方法。如果实现部分抽象方法,则子类仍然是抽象类。如果所有方法都被实现,则子类不再是抽象类。另外,即使不含抽象方法,也可以将某个类声明为抽象类。
现在如果有一个类继承了Person,如下:
class Employee extends AbstractPerson {
@Override
public String getDescription() {
return this.des;
}
String des;
}
现在,上面的person对象变量可以调用p.getDescription方法了,而且结果也将返回des。这里需要解释一下,由于抽象类不能被实例化,所以person引用的永远不可能是Person对象,也就是说,只能引用具体的子类,而这些子类中都实现了getDescription方法,当然就可以调用啦。
在java集合框架中,有许多抽象类,例如 AbstractCollection, AbstractSet, AbstractList等等。可以查看源码了解更多。
接口
Java中的接口,是对类的一组需求描述,遵循接口的统一格式。
在接口中,只能提供方法的声明,而不能实现方法的具体细节。所有方法自动声明为public,所以可以不提供关键字public,但是标准库中有些接口还是加上public,例如Comparable接口中的compareTo方法。在实现接口时,必须声明为public。
出了方法声明之外,接口中还可以定义常量。常量自动被声明为public static final,所以可以省略这一些,一样的,可以加上去使代码更加清晰。标准库中的SwingConstant接口中只包含诸如North之类的常量而没有方法声明,于是实现这一接口的类就可以直接引用这些常量。
需要特别注意的是,在接口中不能有实例域或者静态方法(静态一般都跟类相关,而跟接口无关),也不能有方法实现。
跟抽象类一样,不能实例化接口,但是可以声明接口的对象变量,然后将实现接口的类对象赋值给他。例如:
List<String> strings = new ArrayList<String>();
if (anObjecy instanceof Comparable)
接口跟抽象类最大的区别除了抽象类可以含有实例域和实例方法(而接口不行)以外,Java中只能使用单继承,但是却可以实现多个接口,这是很重要的一个特性。