美文网首页
第九章 接口

第九章 接口

作者: 浩林Leon | 来源:发表于2017-12-20 22:37 被阅读4次

9.1抽象类和抽象接口

创建抽象类是希望通过这个通用类操纵一系列类,所以如果直接创建一个抽象类是没有意义的.甚至还可以在所有的方法都产生错误.含有抽象方法的类必须定义为抽象类.
抽象类是很重要的重构工具,他可以使我们很容易的将共用方法沿继承结构向上移动.

9.2接口

接口是指”所有实现了该接口的类都有这样的行为”.接口用于建立类与类之间的协议.
接口定义

 public interface{}

如果是

interface{}

没有任何修饰,表示包内可以访问.接口内可以包含域(成员变量和常量)但是,这些域隐式的申明为 static final. 
接口内的所有域和方法 默认是public权限,即 不需要显示的设置,并且 不能设置除了public 之外其他的任何权限(private,protected);

ackage tinking_in_java.interfacetest;
import java.util.Random;
/**
 * Created by leon on 17-12-15.
 */
public interface Interface {
    int i = new Random().nextInt();
    int j = new Value().getValue();

    void test();
}

package tinking_in_java.interfacetest;
/**
 * Created by leon on 17-12-15.
 */
public class Value {
    public int getValue() {
        return 10;
    }
}

package tinking_in_java.interfacetest;
/**
 * Created by leon on 17-12-15.
 */
public class TestImp implements Interface {
    @Override
    public void test() {
//        i = 20;  不能修改,因为已经是final 类型
        System.out.println(i);
    }
    public static void main(String[] args) {
        TestImp testImp = new TestImp();
        testImp.test();
    }
}
//output----
10

在java 8中接口引入了关键字default 方法,可以在接口中实现,但是对于一个类实现了两个不同的接口,但是这两个接口都有相同的default 方法,实现类必须overriding default方法否则编译会报无法关联default.

public  interface A { 
  default  void  foo(){
        System.out.println("Calling A.foo()");
    }
} 
public  interface B {
    default  void  foo(){
        System.out.println("Calling B.foo()");
    }
} 
public class Clazz implements A, B {}

上面代码编译失败,报错如下:java: class Clazz inherits unrelated defaults for foo() from types A and B
为了修复错误,在Clazz中,我们手工地覆写掉冲突的方法来处理这个问题,如下所示:

public  class  Clazz  implements A, B {
    public  void foo(){}
}

可是,如果我们就想调用接口A中默认实现的方法foo(),而不用自己实现的,该怎么办?那就要像下面这样使用A#foo()才行。

public  class  Clazz  implements A, B {
    public  void foo(){
        A.super.foo();
    }
}

9.3完全解耦

复用代码的第一种方式是:客户端程序遵循接口来编写自己的类.但是有时你发现接口所需要的传递的数据类型,并不是你想传递的,或者说已经定义好的接口所接受的类型是过时的,为了保持还是使用之前的接口方法,需要对数据进行重新适配(建立中间类,实现旧的接口,在里面重新替换新的实现()).这种模式也叫适配器模式.具体
UML结构图:


image.png
public interface Target 
{
     public void request(); //示意方法,客户端请求处理的方法
}

/**
 * 适配器
 */
public class Adapter implements Target {
 
     private Adaptee adaptee; //持有需要被适配的接口对象
     public Adapter(Adaptee adaptee) { //构造方法,传人需要被适配的对象
          this.adaptee = adaptee;
     }

     public void request() {
      //可能转调已经实现了的方法,进行适配
      adaptee.specificRequest();
     }
}

public class Adaptee { //以及存在的接口
 /**
  * 示意方法,原本已经存在,已经实现的方法
  */
 public void specificRequest() {
  //具体的功能处理
 }
}

public class Client {
     public static void main(String[] args) {
      //创建需被适配的对象
      Adaptee adaptee = new Adaptee();
      //创建客户端需要调用的接口对象
      Target target = new Adapter(adaptee);
      //请求处理
          target.request();
 }
}

9.4多重继承

采用接口的核心原因
1.表示可以向上转型多个基类型(有多种不同的行为,从此带来的灵活性)
2.和抽象类相同,防止客户端创建该类的对象,确保仅仅是建立一个接口.(接口和抽象类的选择 : 事实上如果知道某事物应该成为一个基类,第一反应应该使它成为一个接口)

9.6适配接口

接口一种常见用法就是策略模式.这使得方法更加灵活,通用,并具有复用性.

9.7接口中的域

在java 5以后enum很好的解决了定义一些常量的功能,所以在interface中定义常量的做法已经没有太大意义了.

在接口中可以定义域,但是不能定义空白final域.因为接口域隐式的是final staic ,而final 域必须在构造方法完成前初始化,然而接口是没有构造方法的,所以没有初始化的域将是一个没有意义的值.
域可以初始化 成表达式或者值,可以通过 new 对象获取值.

9.8嵌套接口

类中可以嵌套接口,接口中也可以嵌套接口.类中的嵌套接口是可以支持 public,protected,默认缺省(包内可见),private 权限.但是在接口中嵌套的接口只能是public/(缺省权限也是public)

在Class类中,如果出现一个方法 ”返回一个private接口的引用的public方法” 例如:

package tinking_in_java.interfacetest;
/**
 * Created by leon on 17-12-15.
 */
public class Innerclass {
private interface D {
    void f();
}
public class DImpl2 implements D {
    @Override
    public void f() {
        System.out.println("DImpl2");
    }
}
public D getD() {
        return new DImpl2();
    }
    private D dRef;
    public void setD(D d) {
        dRef = d;
        dRef.f();
    }
}

package tinking_in_java.interfacetest;
/**
 * Created by leon on 17-12-15.
 */
public class InnerTest {
 
    public static void main(String[] args) {
        Innerclass innerclass = new Innerclass();
        // 除了在Innerclass 内部,其他地方无法获取到D引用,因为这个接口是private
        //D d = innerclass.getD();
        innerclass.setD(innerclass.getD());
    }
}
//output-----
DImpl2

9.9接口与工厂

接口实现多重继承的途径的典型例子就是工厂方法.
总结:任何抽象性都应该是应真正的需求而产生的.恰当的原因是,优先选择类而不是接口,如果接口的必须性变得很明确了,那么就进行重构.

相关文章

  • 数据结构思维 第九章 `Map`接口

    第九章 Map接口 原文:Chapter 9 The Map interface 译者:飞龙 协议:CC BY-...

  • 第九章:接口

    接口和内部类为我们提供了一种将接口和实现分离的更加结构化的方法。 1. 抽象类 包含抽象方法的类叫作抽象类。使用抽...

  • 第九章 接口

    9.1抽象类和抽象接口 创建抽象类是希望通过这个通用类操纵一系列类,所以如果直接创建一个抽象类是没有意义的.甚至还...

  • Thinking in Java 第九章接口读书笔记

    1.第九章一上来就说了接口的作用:接口与内部类为我们提供一种将接口与实现分离的更加结构化的方法。所以这一句的重点我...

  • Java多线程笔记

    第九章-线程笔记: 1.线程的创建有两种方式:(1)继承Thread类;(2)重写Runnerbale接口(必须重...

  • 2017-09-10学习记录

    今天重新学习了接口和内部类的部分知识;下面是所有的内容: 第九章:接口 在第八章多态中,通过把子类对象的基类引用作...

  • 《JavaScript高级程序设计》之笔记七

    第九章 DOM DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口)。DOM描绘了一个...

  • Think in Java 第九章(接口)

    接口和内部类为我们提供了一种将接口与现实分离的更加结构化的方法。 9.1抽象类和抽象方法 创建抽象类是希望通过接口...

  • 第九章 DMA控制接口

    9.1 DMA控制器8237A 每个8237A芯片有四个独立的DMA通道,每个通道具有不同的优先权,每个通道有4种...

  • Java编程思想——第九章:接口

    接口和内部类为我们提供一种将接口与实现分离的更加结构化的方法。抽象类似普通类和接口之间的一种中庸之道。 1.抽象类...

网友评论

      本文标题:第九章 接口

      本文链接:https://www.haomeiwen.com/subject/ergnwxtx.html