第12章

voiddispo色{

voiddispo色{

cນharc;

charc;๙

一般说来,如果在一个程序里使用了“直接常量”literaທl,编译器可以准确地知道要生成

一般说来,如果在一个程序里使用了“直接常量”literal,编译器可以准确地知道要生成

维护文档的费用。

维护文档的费用。

prenticehaທll恰当的地点和恰当的时间出现,他将责任转交给paul之前,为这些书奠定

prenticນehaທll恰当的地点和恰当的时间出现,他将责任转交给paທul之前,为这些书奠定

multipleinterfacນes

interfaທ9๗fight{

voidfight;

}

interfaທ99im{

void9im;

}

interfaທ9fly{

voidfly;๙

}

9characນter{

publicນvoidfight{}

}

9dsa9chaທracter

implements9fly{

publicvoid9๗im{}

pubຘlicນvoidfly{}

}

publi9ture{

publi9fightx{xfight;}

publi99imx{9im;}

pubຘli9flyx{xfly;}

publi9chaທracterx{xfight;}

publi9stringargs{

heroh=ne9hero;

th;treaທtitasaທ9fight

uh;treatitasa99im

vh;๙treaທtitasa9fly

9h;treatitasana9character

}

}:๘~

你可以看到,hero组合了具体类a9๗fight、9fly。

当你要通过这种方式将一个具体类和多个接口组合到เ一起时,这个具体类必须是先行,后面

跟着的才是接口。否则编译器会报错。

注意,9chaທracter类中的fight方法的签名是一样的,而且,在hero

中并没有fight的定义。接口的规则是:你可以从接口中继承就像稍后你会看到的那

样,但是你得到的只是另一个接口。如果你想创น建该新类型的对象,就必须有一个ฐ了

其全部定义的类。即使hero没有显式地fight的定义แ,其定义也随a9charaທcter

而存在,因此它是被自动的,这使得创น建hero对象成为ฦ了可能。

在adventure类中ณ,你可以看到เ有四个方แ法把上述各种接口和具体类作为参数。当hero对

象被创建时,它可以被传递给这些方法中的任何一个,这意味着它依次被向上转型为ฦ每一个ฐ

接口。由于jaທva中这种接口设计的方式,使得这项工ื作并不需要程序员一方付出任何特别

的努力。

一定要记住,前面的例子所展示的就是使用接口的核心原因:为了能ม够向上转型为ฦ不止一个

的基类型。然而,使用接口的第二个原因却是与使用抽象基类相同:防止客户端程序员创建

该类的对象,并确保这仅仅是建立一个接口。这就带来了一个问题:我们应该使用接口还是

抽象类?接口为你带来了使用抽象类的好处,并且还带来了使用接口的好处,所以如果你要

创建不带任何方法定义和成员变量的基类,那么你应该选择接口而不是抽象类。事实上,如

果你知道某事物应该成为一个基类,那么เ你的第一选择应该是使它成为一个接口,只有在强