首页 > 代码库 > [think in java] 第9章 接口

[think in java] 第9章 接口

9.1抽象类和抽象方法

在应用继承时,基类的很多方法是子类的通用接口,其本身并无实际意义。创建基类对象没有意义,我们甚至需要组织用户这么做。但是,如果用户这么做了,我们将在运行时才会发现错误。为了使错误信息在编译时就可以被捕获,我们可以将基类定义为抽象类。

抽象的关键字为abstract,java提过了抽象方法机制,这种方法是不完整的;仅有声明没有方法体。如:

abstract void f();

包含抽象方法的类叫抽象类。如果一个类包含一个或多个抽象方法,该类必须被限定为抽象的。如果一个从抽象类继承,并想创建为该新类创建对象,那么就必须为基类中的所有抽象方法提供方法定义。否则该类依然是抽象的,编译器会强制你加上abstract关键字。


9.2接口

接口的关键字为interface,这个关键字产生一个完全抽象的类。接口只提供方法的声明,而未提供方法体。接口被用来建立类与类之间的协议。

关键接口就像创建类,只是需要用interface替换class关键字。可以在interface前添加public关键字(仅限与该接口在与其同名的文件中,这也与类类似)。如果不添加public关键字,则只有包访问权限。此外,接口也可以包含域,但是这些域是隐式的是static 和 final的,同时接口中的域自动是public的。

接口中定义的方法必须是public的,即使没有明确显示定义,他们默认也是public的。


9.4java中的多重继承

java中的继承是单继承的,但是如果需要从多个地方继承接口,可以选择用接口来实现。implement关键字可以继承多个接口。下面是一个例子。

interface CanFight{
	void fight(); //默认为public
}

interface CanSwim{
	void swim();
}

interface CanFly{
	void fly();
}

class ActionCharacter{
	public void fight(){}
}

class Hero extends ActionCharacter 
	implements CanFight, CanFly, CanSwim{
	//fight方法从ActionCharacter继承而来。
	public void swim(){}
	public void fly(){}
}

public class Adventure {
	public static void t(CanFight x) {x.fight();}
	public static void u(CanSwim x) {x.swim();}
	public static void v(CanFly x)  {x.fly();}
	public static void w(ActionCharacter x) {x.fight();}
	
	public static void main(String [] args){
		Hero x = new Hero();
		t(x);
		u(x);
		v(x);
		w(x);
	}
}

Hero组合具体类和接口时,具体类必须放在前面,后面跟着的才是接口。(否则编译器会报错)。

这里带来一个问题,我们应该使用接口还是抽象类?如果要创建不带任何方法定义和成员变量的基类,那么应该选择接口而不是抽象类。事实上,如果知道某食物应该成为一个基类,我们第一选择应该是使他成为一个接口。


9.5接口继承可以用来扩展接口

9.8嵌套接口

几口可以嵌套在类或其他接口中。特别要注意的是,当实现某个接口时,并不需要实现嵌套在其内部的任何接口。而且private接口不能在定义它的类之外被实现


在进行设计时,恰当的原则应该是优先选择类而不是接口。从类开始,如果接口的必需性变得非常明确,那么就进行重构。接口是一种重要的工具,但是容易被滥用。




[think in java] 第9章 接口