Java学习提要——'接口'的基础示例

1.接口的基本定义

尽量详细,日后翻阅方便,干货。

1)基础概念

如果一个类之后只有由抽象方法全局常量组成的,那么在这种情况下不会将其定义为一个抽象类,而只会将其定义为接口,所谓接口严格来说就属于一个特殊的类,而且这个类里面,只有抽象方法和全局常量,连构造方法都没有

interface  A { //定义了接口
  public static final String MSG = "Hello";//全局常量
  public abstract void print();      //抽象方法
}

由于接口里面存在有抽象方法,所以接口对象不可能直接使用关键字new进行实例化的操作,所以接口使用原则有:
  1.接口必须要有子类,但是此时一个子类可以使用implements关键字实现多个接口;
  2.接口的子类(如果不是抽象类),那么必须要覆写接口中的全部抽象方法
  3.接口的对象可以利用子类对象的向上转型进行实例化操作

接口实例:

interface A{
  public static final String MSG = "hello" ;
  public abstract void print() ;
}
interface B {
  public abstract void get();
}
class X implements A,B{
  public void print(){
    System.out.println("A");
  }
  public void get(){
    System.out.println("B");
  }
}
public class Demo{
  public static void main(String args[]){
    X x = new X() ;//实例化
    A a = x ;//向上转型
    B b = x ;//向上转型
    a.print();
    b.get();
  }
}

上面的实例化代码,改成:

A a = new X();
B b = (B) a ;
b.get();
//System.out.println(a instanceof A);
//System.out.println(a instanceof B);

结果是正确的,后面也返回的true,定义结构上AB没有任何直接联系,但是这两个接口都有同一个子类,千万不要被类型与名称迷惑,new的是X子类,而这个子类也属于B类的对象,只是从代码编写上讲,有点难理解。

2)同时继承接口与抽象类

对于子类而言,除了接口以外,还可能会继承抽象类,那么两个当同时进行时,我们要先使用extends继承,再使用implements实现。

已经定义好了接口A、B,抽象类C;
格式: class X extends C implements A,B { }

3)多个接口定义

一个抽象类可以去继承一个接口,但注意,一个接口可以使用extends关键字同时继承多个接口(但是接口不能继承抽象类).
接口实例:

interface A{
  public void funA();
}
interface B{
  public void funB();
}
interface C extends A,B {
  public void funC();
}
class X implements C {
  public void funA ( ) { }
  public void funB ( ) { }
  public void funC ( ) { }
}
……

从继承关系上讲抽象类的限制比接口多了太多:
  1.一个抽象类只能够继承一个抽象的父类,而接口没有这个限制
  2.一个子类只能够继承一个抽象类,而却可以实现多个接口

4)内部接口

接口虽然本身概念来说,只能够由抽象方法全局变量组成,但是所有的内部结构是不受这些限制的,也就是说接口里面可以定义普通内部类抽象内部类内部接口
接口实例:

interface A{
  public void funA();
  abstract class B {
    public abstract void funB() ;
  }
}
class X implements A{ //实现了A接口
  public void funA(){
    System.out.println("hello");
  }
  class Y extends B{ //内部抽象类的子类
    public void funB() {};
  }
}

一般不会这样,举个例子而已。。。

在一个接口内部,如果使用了static去定义一个内部接口,那么表示是一个外部接口:

interface A{
  public void funA();
  static interface B {  //外部接口
    public void funB() ;
  }
}
class X implements A.B { //实现了A接口
  public void funB() ;
}

2.标准定义

定义实例:USB设备标准举例

interface USB {
  public void start() ;
  public void stop() ;
}
class Computer{
  public void plugin(USB usb){//插入USB
    usb.start();
    usb.stop();
  }
}
class Flash implements USB{
  public void start() {
    System.out.println("U盘开始使用");
  }
  public void stop() {
    System.out.println("U盘停止使用");
  }
}
class Scan implements USB{
  public void start() {
    System.out.println("扫描仪开始工作");
  }
  public void stop(){
    System.out.println("扫描仪停止工作");
  } 
}
public class Test{
  public static void main (String args []) { 
    Computer com = new Computer() ;
    com.plugin(new Flash());
    com.plugin(new Scan());
  }
}

3.工厂设计模式

先来一段普通接口代码:

interface Fruit {
  public void eat() ;
}
class Apple implements Fruit {
  public void eat() {
    System.out.println("eat apple");
  }
}
class orange implements Fruit {
  public void eat() {
    System.out.println("eat orange");
  }
}
public class Test{
  public static void main(String args[]){
    Fruit f = new Apple() ; 
    f.eat() ;
  }
}

这个代码从代码角度看,是没有问题的,但是,从客户端角度看的话,吃apple或者orange 就要 new 不一样的,换来换去麻烦,也可以理解为耦合度太高,直接问题是代码不方便维护

确认一个代码真的好,有这么几个标准:
  1.客户端调用简单,不需要关注具体的细节
  2.客户端之外的代码修改,不影响用户的用户,即用户不用担心代码是否变更
  
那么看下下面这个例子:

interface Fruit {
  public void eat() ;
}
class Apple implements Fruit {
  public void eat() {
    System.out.println("eat apple");
  }
}
class Orange implements Fruit {
  public void eat() {
    System.out.println("eat orange");
  }
}
class Factory {
  public static Fruit getInstance(String className){
    if("apple".equals(className)) {
      return new Apple() ;
    }else if ("orange".equals(className)) {
      return new Orange();
    }else {
      return null ;
    }
  }
}
public class Test{
  public static void main(String args[]){
    Fruit f =  Factory.getInstance("apple"); 
    f.eat() ;
  }
}

现在客户端不会看到具体的子类,因为所有的接口对象都是通过factory类取得的,如果日后要扩充新的Fruit子类对象,只需要修改Factory就可以了,但是客户端不会发生变化

4.代理设计模式

interface Subject{  //整个操作的核心主题
  public void make() ; //核心功能
}
class  RealSubject implements Subject {
  public void make() {
    System.out.println("做什么什么");
  }
}
class ProxySubject implements Subject{
  private Subject subject ;
  //接收一个真实主题的操作对象
  public ProxySubject(Subject subject) {
    this.subject = subject ;
  }
  public void prepare() {
    System.out.println("准备");
  }
  public void make() {
    this.prepare();
    this.subject.make();
    this.destroy();
  }
  public void destroy() {
    System.out.println("销毁");
  }
}
public class Test {
  public static void main(String args[]) {
    Subject sub = new ProxySubject(new RealSubject());
    sub.make() ; //调用的是代理主题操作
  }
}

代理设计模式核心精髓在于有一个主题操作接口(可能有多种方法),核心业务主题只完成核心功能,而代理主题负责完成所有与核心主题有关的辅助性操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值