第九章 接口

接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法。

1、抽象类和抽象方法

1.1 抽象类    abstract

  • 仅有声明,没有方法体,即无大括号以及其内容;
  • 如果一个类包含一个或多个抽象方法,该类必须限定为抽象的;
  • 如果不完整的抽象类试图创建该类的对象时,编译器会报错;
  • 并不需要所有的方法都是抽象的;

如果子类继承抽象父类,并不要求一定要重写父类的方法,否则必须重写实现; 

2、接口

  •  interface关键字产生一个完全的抽象类,它允许创建者确定方法名、参数列表和返回类型,但是没有任何方法体。implements实现接口;
  • 范围:public;
  • 接口可以包含域,默认是static和final的;

3、完全解耦

只要方法操作的是类而不是接口,那么你只能使用类和其子类。接口则可以提高代码的复用性。 

1、策略设计模式

能根据传递的参数对象的不同而具有不同的行为方法;

/**
 * 策略设计模式
 * @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(" "));
    }
}

2、适配器模式

适配器模式接受你拥有的接口,产生的所需要的接口;

分为对象适配器和类适配器:

  • 对象适配器模式是把“源”作为一个对象聚合到适配器类中;
  • 若此适配器只为某一个类提供一个具体服务,则称其为类适配器模式;

2.1 对象适配器模式

public interface Processor {
    String name();
    Object process(Object input);
}
/**
 * 对象适配器模式
 * @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);
    }

}

2.2 类适配器模式

源的代码
public class Person {
	
	private String name;
	private String sex;
	private int age;
	
	public void speakJapanese(){
		System.out.println("I can speak Japanese!");
	}
	
	public void speakEnglish(){
		System.out.println("I can speak English!");
	}
	...//以下省略成员变量的get和set方法
}
目标接口的代码
public interface Job {
	
	public abstract void speakJapanese();
	public abstract void speakEnglish();
	public abstract void speakFrench();
	
}
适配器的代码
public class Adapter extends Person implements Job{

	public void speakFrench() {
		
	}
	
}

为什么称其为类适配模式呢?很显然的,Adapter类继承了Person类,而在Java这种单继承的语言中也就意味着,他不可能再去继承其他的类了,这样也就是这个适配器只为Person这一个类服务。所以称其为类适配模式。

2.3 两种适配器模式分析

  • 类的适配模式用于单一源的适配,由于它的源的单一话,代码实现不用写选择逻辑,很清晰;而对象的适配模式则可用于多源的适配,弥补了类适配模式的不足,使得原本用类适配模式需要写很多适配器的情况不复存在,弱点是,由于源的数目可以较多,所以具体的实现条件选择分支比较多,不太清晰。
  • 适配器模式主要用于几种情况:(1)系统需要使用现有的类,但现有的类不完全符合需要。(2)讲彼此没有太大关联的类引进来一起完成某项工作(指对象适配)。

将接口冲具体的实现解耦使得接口可以应用于多种不同具体实现。因此代码也就更具有可复用性。

练习11:创建一个类,它有一个方法用于接受一个String类型的参数,生成的结果是将该参数中每一对字符进行互换。对该类进行适配,使得它可以用于interfaceprocessor.Apply.process()。

package nuc.test;
import static nuc.test.Print.*;

class Swap {
	static String swap(String s) {
		StringBuilder sb = new StringBuilder(s);
		for(int i = 0; i < sb.length() - 1; i += 2) {
			char c1 = sb.charAt(i);
			char c2 = sb.charAt(i + 1);
			sb.setCharAt(i, c2);
			sb.setCharAt(i+1, c1);
		}
		return sb.toString();
	}
}

class SwapperAdapter implements Processor{
	@Override
	public String name() {
		return getClass().getSimpleName();
	}
	@Override
	public String process(Object input) {
		return Swap.swap((String) input);
	}
}
public class adapter {
	public static void main(String[] args) {
		Apply.process(new SwapperAdapter(),"1234");
		Apply.process(new SwapperAdapter(),"abcde");
	}
}

4、java中多重继承

组合多个类的接口的行为称为多重继承。 
使用接口的核心原因:为了向上转型为多个基类型;防止客户端创建该类的对象,并确保这仅仅是一个接口。

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();
}

★  尽量避免不同接口使用相同的名称;

6、适配接口

接口最吸引人的原因之一就是允许同一个接口具有多个不同的实现。 
常见用法有策略模式和适配器模式。

7、接口中的域

  • 放入接口中的任何域都自动是static和final的;
  • 在接口中定义的域不能是“空final”,但可以是非常量表达式初始化;
  • 这些域不是接口中的一部分,他们的值被存储在该接口的静态存储区域内

8、嵌套接口

  • 接口可以嵌套在类和其他接口中,实现一个private接口,他可以强制该接口中的方法定义不要添加任何类型信息(也就是不允许向上转型);
  • private接口可以通过将返回值交给有权使用他的对象;
  • 嵌套在接口中的接口自动是public的;
  • 当实现某个接口时,并不需要实现嵌套在其内部的任何接口;

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());
    }
}

 

参考博客: https://blog.csdn.net/elegant_shadow/article/details/5006175 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值