《java编程思想——第九章(接口)》
接口
接口与内部类为我们提供了一种将接口与实现分离的更加结构化的方法。
9.1 抽象类和抽象方法
抽象方法:仅有声明没有方法体。
抽象类:包含抽象方法的类叫抽象类。包含抽象方法的类必须是抽象的。
抽象类特性:不能为抽象类创建对象;继承抽象类必须覆盖基类所有抽象方法;抽象类可以没有抽象方法。
抽象方法:abstract void f()
包含抽象方法的类叫做抽象类。如果一个类包含一个或多个抽象方法,该类必须被限定为抽象的。
创建抽象类和抽象方法非常有用,因为它们可以使类的抽象性明确起来,并告诉用户和编译器打算怎样来使用它们。抽象类还是很有用的重构工具,因为它们使得我们可以很容易地将公共方法沿着继承层级结构向上移动
9.2 接口
interface关键字产生一个完全的抽象类。它允许创建者确定方法名、参数列表和返回类型,但是没有任何方法体。implements 实现接口。
接口可以包含域,默认是static和final的。
Java8 中接口新增了default和static方法,这两种方法在接口中都可以有具体实现。
普通的抽象方法和default方法会被子类继承,子类必现实现普通抽象方法,而default方法子类可以实现,也可以选择不实现。
default方法子类可以实现,也可以选择不实现。
static方法不能被继承,也不能被子类实现,只能被自身调用
9.3 完全解耦
只要一个方法操作的是类而不是接口,那么你只能使用类和其子类。如果你想要将这个方法应用于不在此继承结构中的某个类,那么就不行了。接口可以在很大程度上放宽这种限制。因此,它可以使得我们编写复用性更好的代码。
- 策略设计模式
能够根据传递的参数对象的不同而具有不同行为的方法。
/**
* 策略设计模式
* @author Administrator
*
*/
public class Apply {
public static void process(Processor p,Object o) {
System.out.println("Useing Processor" +p.name());
System.out.println(p.process(o));
}
public static String s = "Disagreement with beliefs is by definition incorrent";
public static void main(String[] args) {
process(new Upcase(), s);
process(new Downcase(), s);
process(new Splitter(), s);
}
}
class Processor{
public String name() {
return getClass().getSimpleName();
}
Object process(Object input){
return input;
}
}
class Upcase extends Processor{
String process(Object input){
return ((String)input).toUpperCase();
}
}
class Downcase extends Processor{
String process(Object input){
return ((String)input).toLowerCase();
}
}
class Splitter extends Processor{
String process(Object input){
return Arrays.toString(((String)input).split(" "));
}
}
- 适配器模式
适配器接收你拥有的接口,产生你所需要的接口。
/**
* 适配器模式
* @author Administrator
*
*/
public class FilterAdapter implements Processor{
Filter filter; //代理:选择性的返回需要的方法
public FilterAdapter(Filter filter) {
this.filter = filter;
}
@Override
public String name() {
return filter.name();
}
@Override
public Waveform process(Object input) {
return filter.process((Waveform) input);
}
}
将接口冲具体的实现解耦使得接口可以应用于多种不同具体实现。因此代码也就更具有可复用性。
9.4 多重继承
组合多个类的接口的行为称为多重继承。
使用接口的核心原因:为了向上转型为多个基类型;防止客户端创建该类的对象。
9.5 通过继承来扩展接口
接口可以继承多个接口。
interface Monster{
void menace();
}
interface DangerMonster extends Monster{
void destory();
}
interface Lethal{
void kill();
}
class DrangoZilla implements DangerMonster{
@Override
public void menace() {}
@Override
public void destory() {}
}
interface Vampire extends DangerMonster,Lethal{
void drinkBlood();
}
通过继承,可以很容易地在接口中添加新的/方法声明,还可以通过继承在新接口中组合数个接口。
组合接口时的名字冲突:可以重载方法,覆写方法写个@Override注解。尽量还是避免不同的接口中使用相同的方法名造成代码可读性的混乱。
9.6 适配接口
接口最吸引人的原因之一就是允许同一个接口具有多个不同的实现。
常见用法有策略模式和适配器模式。
9.7 接口中的域
放入接口中的任何域都自动是static和final的。既然域是static的,它们就可以在类第一次被加载时初始化,这发生在任何域首次被访问时。当然,这些域不是接口的一部分,它们的值被存储在该接口的静态存储区域内。
9.8 嵌套接口
接口可以嵌套在类和其他接口中。
嵌套在接口中的接口自动是public的。
9.9接口与工厂
接口是实现多重继承的途径,生成遵循某个接口的对象的典型方式就是工厂方法设计模式。
在工厂对象上调用的是创建方法,而该工厂对象将生成接口的某个实现对象。通过这种方式,可以将代码的实现与接口完全分离。
/**
* 工厂模式
* @author Administrator
*
*/
interface Game{ boolean move();}
interface GameFactory{ Game getGame();}
class Checkers implements Game{
private int moves = 0;
private static final int MOVES = 3;
public boolean move() {
System.out.println("Checkers move"+moves);
return ++moves !=MOVES;
}
}
class CheckersFactory implements GameFactory{
public Game getGame( ) {
return new Checkers();
}
}
class Chess implements Game{
private int moves = 0;
private static final int MOVES = 4;
public boolean move() {
System.out.println("Chess move"+moves);
return ++moves !=MOVES;
}
}
class ChessFactory implements GameFactory{
public Game getGame( ) {
return new Chess();
}
}
public class Games {
public static void playGame(GameFactory factory) {
Game g = factory.getGame();
while(g.move());
}
public static void main(String[] args) {
playGame(new CheckersFactory());
playGame(new ChessFactory());
}
}

浙公网安备 33010602011771号