第9章:接口

抽象类与抽象方法

抽象类(abstract)

  • 抽象方法:只给出方法定义而没有具体实现的方法被称为抽象方法,抽象方法是没有方法体的,在代码的表达上就是没有“{}”。使用 abstract 修饰符来表示抽象方法和抽象类。
  • 抽象类:包含抽象方法的类叫做抽象类(如果在类的方法声明中使用abstract修饰符,表明该方法是一个抽象方法,它需要在子类实现。如果一个类包含抽象方法,则这个类也是抽象类,必须使用abstract修饰符,并且不能实例化。 )
  • 注意,抽象类除了包含抽象方法外,还可以包含具体的变量和具体的方法。类即使不包含抽象方法,也可以被声明为抽象类,防止被实例化。如果从一个抽象类继承,并想创建该新类的对象,那么就必须实现所有的基类中的抽象方法,否则自己也会变成抽象类.

接口(interface)

  • 接口作用:定义规范,解耦合
    只要一个方法操作的是类而非接口,那么你就只能使用这个类及其子类.如果你想要将这个方法应用于不在此继承结构中的某个类,那么你就会触霉头了.接口可以在很大程度上放宽这种限制,因此,它使得我们可以编写复用性更好的代码.
package package9;

public class Processor {
    public String name(){
        return getClass().getSimpleName();
    }
    Object process(Object input){
        return input;
    }
}

public class Upcase extends Processor{
    Object process(Object input){
        return ((String)input).toUpperCase();
    }
}

public class Downcase extends Processor {
    Object process(Object input){
        return ((String)input).toLowerCase();
    }
}

public class Splitter extends Processor {
    Object process(Object input){
        return Arrays.toString(((String)input).split(" "));
    }
}

public class Apply {

    public static void process(Processor p,Object s){
        System.out.println("Using Processor "+p.name());
        System.out.println(p.process(s));
    }

    public static String s ="Disagreement with beliefs is by definition incorrect";

    public static void main(String[] args) {
        process(new Upcase(),s);
        process(new Downcase(),s);
        process(new Splitter(),s);

    }
}
//结果
Using Processor Upcase
DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRECT
Using Processor Downcase
disagreement with beliefs is by definition incorrect
Using Processor Splitter
[Disagreement, with, beliefs, is, by, definition, incorrect]

Apply.process()方法可以接受任何类型的Processor,并将其应用到一个Object对象上,然后打印结果.像本例这样,创建一个能够根据所传参数对象的不同而具有不同行为的方法,被称为策略设计模式.这类方法包含所要执行的算法中固定不变的部分,而”策略”包含变化的部分.策略就是传递进去的参数对象,它包含要执行的代码.这里Processor 对象就是一个策略,在main()中可以看到有三种不同类型的策略应用到了String类型的s对象上

  • 适配器设计模式:适配器中的代码将接受你所拥有的接口,并产生你所需要的接口
package package3;

public interface Processor {
    String name();
    Object process(Object input);
}

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

public class Filter {
    public String name(){
        return getClass().getSimpleName();
    }

    public Waveform process(Waveform input){
        return input;
    }
}

public class LowPass extends Filter {
    double cutoff;

    public LowPass(double cutoff) {
        this.cutoff = cutoff;
    }
    public Waveform process(Waveform input){
        return input;
    }
}

public class HighPass extends Filter {
    double cutoff;

    public HighPass(double cutoff) {
        this.cutoff = cutoff;
    }
    public Waveform process(Waveform input){
        return input;
    }
}

public class BandPass extends Filter {
    double lowCutoff,highCutoff;
    public BandPass(double lowCutoff, double highCutoff) {
        this.lowCutoff = lowCutoff;
        this.highCutoff = highCutoff;
    }

    public Waveform process(Waveform input){
        return input;
    }
}

public class Waveform {
    private static  long counter;
    private final long id=counter++;
    public String toString(){
        return "Waveform "+id;
    }
}

public class Apply {
    public static void process(Processor p,Object s){
        System.out.println("Using Processor "+p.name());
        System.out.println(p.process(s));
    }
}
//结果
Using Processor LowPass
Waveform 0
Using Processor HighPass
Waveform 0
Using Processor BandPass
Waveform 0

这种使用适配器的方式中,FilterAdapter 的构造器接受你所拥有的接口Filter,然后生成具有你所需要的Processor接口对象.你可能还注意到FilterAdapter 类中用到了代理.接口从具体实现中解耦使得接口可以应用于多种不同的实现,因此代码更具可复用性.

java中多继承

  • 类是单继承,接口是多继承
  • 当一个具体类和多个接口组合到一起时,具体类必须放在前面,后面跟着的才是接口(否则编译器会报错).
  • 该如何选择接口和抽象类?
    如果要创建不带任何方法定义和成员变量的基类,那么就应该选择接口而不是抽象类.事实上,如果知道某事物应该成为一个基类,那么第一选择应该是使它成为一个接口.

通过继承来扩展接口

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值