TJI读书笔记12-接口

Posted 吾码2016

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TJI读书笔记12-接口相关的知识,希望对你有一定的参考价值。

 

 

接口和抽象类为我们提供了更强又有力的接口和实现分离的方法.

抽象类和抽象方法

抽象类的目的是为了给子类提供一个通用接口,通过这样一个通用的接口,可以操纵一系列的子类. 也就是说,只需要通过相同的接口调用就可以操作不用的实现. 这也就是所谓的接口和实现的分离.

抽象类简单来说就是包含抽象方法的类. 那么,要了解抽象类就得先了解抽象方法. abstract void f();像这样的由abstract修饰的方法叫做抽象方法. 抽象方法只有返回值类型和方法签名,没有方法体. 抽象类同样适用abstract修饰,并且抽象类不能实例化.

1.abstract class Instrument{
2.
3. abstract public void paly(Note m);
4. private void test1(){
5. System.out.println("Instrument");
6. }
7.}
8.class Wind extends Instrument{
9. public void paly(Note m){
10. System.out.println("Wind play()");
11. }
12.
13. public void test1(){
14. System.out.println("111");
15. }
16.}
17.
18.public class Music {
19. public static void tune(Instrument i){
20. i.paly(Note.C_SHARP);
21. }
22. public static void main(String[] args) {
23. Wind flute = new Wind();
24. tune(flute);
25. }
26.}

抽象类作为基类,对子类中需要改变的方法仅提供abstract方法,对于其他方法,可以正常提供方法体,算是一种介于接口和正常类之间的一种中庸的方案. 抽象类使类的抽象性明确起来了. 抽象类是很重要的重构工具,因为它可以容易的将公共方法沿着继承层次结构向上移动.(埃大爷说的好学院范儿…)

接口

如果一个抽象类中的方法都是抽象方法,那么它的作用就更抽象了. 这么一种纯粹的抽象类,它只提供一个类型的接口定义,没有任何实现. 那么这么一种抽象的令人发指的抽象类如果不给它定义成一个新的概念简直天理难容. 于是这种玩意儿就叫做接口. 它只提供一个类的接口定义于是就被粗暴的叫成了接口… 注意这个接口是java的一种类型机制,平时所说的类的接口是指类中暴露出的可以使用的方法. 可以说接口是用用来被建立类和类之间的协议. (有些语言会直接使用protocol完成这一功能)

interface不仅仅是一个纯粹的抽象类,它允许人们通过创建一个能够被向上转型的多种基类的类型. 除了这个,interface还有一个功能就是可以实现类似多继承的功能. 需要注意的几个点:

  • 接口中定义的方法,隐式添加 public static final
  • 接口中可以定义成员变量,默认都是static final的
  • 要让一个类实现一个接口需要使用implements关键字
  • 实现一个接口的类必须要实现这个接口中定义的所有方法.
  • 实现一个接口的类,可以定义自己的public方法. 也就是说实现一个interface的类对外提供的接口是所实现interface的子集.
1.interface Instrument2{
2. int Value = 5;
3. void paly(Note n);
4. void adjust();
5.}
6.
7.public class Wind2 implements Instrument2{
8. public void paly(Note n ){
9. System.out.println(this+".play() "+n);
10. }
11. public void adjust(){
12. System.out.println(this+".adjust()");
13. }
14. public String toString(){
15. return "Wind";
16. }
17. public void foo1(){
18. System.out.println("hoho");
19. }
20.
21. public static void main(String[] args) {
22. Wind2 wind = new Wind2();
23. wind.adjust();
24. wind.paly(Note.B_FLAT);
25. wind.foo1();
26. System.out.println(Instrument2.Value);
27. }
28.}

完全解耦和策略模式

1.import java.util.Arrays;
2.
3.class Processor{
4. public String name(){
5. return getClass().getSimpleName();
6. }
7. Object process(Object input){
8. return input;
9. }
10.}
11.
12.class UpCase extends Processor{
13. String process(Object input){
14. return ((String)input).toUpperCase();
15. }
16.}
17.
18.class LowerCase extends Processor{
19. String process(Object input){
20. return ((String)input).toLowerCase();
21. }
22.}
23.
24.class Splitter extends Processor{
25. String process(Object input){
26. return Arrays.toString(((String)input).split(" "));
27. }
28.}
29.
30.public class Apply {
31. public static void process(Processor p,Object s){
32. System.out.println("using Processor "+p.name());
33. System.out.println(p.process(s));
34. }
35. public static String s = "hello world";
36. public static void main(String[] args) {
37. Apply.process(new UpCase(), s);
38. Apply.process(new LowerCase(), s);
39. Apply.process(new Splitter(), s);
40. }
41.}

上面是一个经典的策略模式,同一个方法,根据入参不同会有不同的行为. 所谓见人说人话,见鬼说鬼话. 注意实现方式,本质其实就是多态. 策略就是传入的参数的对象.它包含所要执行的代码.

但是看下面这个例子

1.public class Waveform {
2. private static long counter;
3. private final long id = counter++;
4. public String toString(){
5. return "Waveform "+id;
6. }
7.}
8.//=========================================================
9.public class Filter {
10. public String name(){
11. return getClass().getSimpleName();
12. }
13. public Waveform process(Waveform input){
14. return input;
15. }
16.}
17.//=========================================================
18.public class LowPass extends Filter{
19. double cutoff;
20.
21. public LowPass(double cutoff){
22. this.cutoff=cutoff;
23. }
24. public Waveform process(Waveform input){
25. return input;
26. }
27.}
28.//=========================================================
29.public class HighPass extends Filter{
30. double cutoff;
31.
32. public HighPass(double cutoff) {
33. this.cutoff = cutoff;
34. }
35. public Waveform process(Waveform input) {
36. return input;
37. }
38.}
39.//=========================================================
40.public class BandPass extends Filter{
41. double lowCutoff,HighCutoff;
42.
43. public BandPass(double lowCutoff,double HighCutoff){
44. this.HighCutoff=HighCutoff;
45. this.lowCutoff=lowCutoff;
46. }
47. public Waveform process(Waveform input){
48. return input;
49. }
50.}
51.

Alt text

.1473781578401

上面这段代码就会有个问题,Filter和Processor虽然有相同的接口元素,但是他并非继承自Processor. 因为Filter的创建者可能并不知道你想将其用作processor. 这样就不能通过Apply.process()来调用了. 虽然也有办法可以正常运行,但是processor和Apply.process()之间的耦合太紧. 想复用Apply.process()的时候就出现问题. 所以有个办法就是把processor抽象为一个接口,然后处理不同问题的时候,再去实现这个接口.

1.public interface Processor{
2. public String name();
3. public Object process(Object input);
4.}
5.//=========================================================
6.import java.util.Arrays;
7.public abstract class StringProcessor implements Processor {
8. public String name() {
9. return getClass().getSimpleName();
10. }
11.
12. public abstract String process(Object input);
13.
14. public static String s = "hello world";
15.
16. public static void main(String[] args) {
17. Apply.process(new UpCase(), s);
18. Apply.process(new LowerCase(), s);
19. Apply.process(new Splitter(), s);
20. }
21.}
22.
23.class UpCase extends StringProcessor {
24.
25. public String process(Object input) {
26. return ((String) input).toUpperCase();
27. }
TJI读书笔记14-闭包与回调

TJI读书笔记11-多态

TJI读书笔记15-持有对象

TJI读书笔记10-复用类

TJI读书笔记16-异常处理

TJI读书笔记07-初始化