在面向对象编程中,接口是一个重要概念,它是一种契约,它定义了对象应该具备的方法。一个接口可以有多重实现,它的所有实现都必须满足接口所有约定的方法。并不是所有编程语言都有接口,例如在CPythonRuby中是没有内置的接口机制,但在大多数编程语言中都有接口的概念,一般用interface来标记。

JavaGo都是有内置的接口的机制,但在接口实现上却不尽相同。这些区别主要是接口定义、接口实现、约束机制和应用场景等方面,下面就这些不同进行逐一比较。

接口定义

两者在接口定义上区别不大,都是通过interface实现的。

Java中接口的定义:

public interface Shape {
    double perimeter();
    double area();
}

Go语言中接口的定义:

type Shape interface {
    Perimeter() float64
    Area() float64
}

接口实现

Java中,接口实现类必须通过implements关键字明确实现的接口,这是一种显式的声明,将实现接口绑定,也就是说要实现一个接口就必须依赖这个接口。

class Circle implements Shape { // 显式声明实现Shape接口
    @Override
    public double perimeter() {
        // TODO Auto-generated method stub
    }

    @Override
    public double area() {
        // TODO Auto-generated method stub
    }
} 

而在Go中,并不需要将接口实现显式的绑定,只要一个类型包含了接口所定义的方法,并且输入和输出参数一致,那么这个类型则自动满足这个接口,即表示它实现了这个接口,也就是隐式实现。

type Circle struct{} { // 自动满足Shape接口

func (c Circle) Perimeter() float64 {
}

func (c Circle) Area() float64 {
}

约束机制

Java中,一切皆对象,所以也只有类(class)可以实现接口,基本的数据类型(如:int、long)等均不支持实现接口。

但在Go中就不一样了,可以说任何类型均可实现接口,包括基本类型(intbool等)、mapslice,甚至函数都可以实现接口

必要时,使用函数来实现接口,便可快速满足业务场景,代码简洁灵活。这是一个函数实现接口的例子:

type ShapeFunc func() (float64, float64)

func (f ShapeFunc) Perimeter() float64 {
    p, _ := f()
    return p
}

func (f ShapeFunc) Area() float64 {
    _, a := f()
    return a
}

另外,在多接口扩展上,两种编程语言的的实现也有所不同。

Java中,一个类可以同时实现多个接口,多个接口以,分隔,并且接口之间还可以继承:

public interface Drawable {
    void draw();
}

// 实现多个接口
class Circle implements Shape, Drawable { 
    @Override
    public double perimeter() {
        // TODO Auto-generated method stub
    }

    @Override
    public double area() {
        // TODO Auto-generated method stub
    }

    @Override
    public void draw() {
       // TODO ...
    }
}

// 接口继承
public interface Drawable extends Shape {
}

而在Go语言中,一个类型实现多个接口,只需要实现多个接口的所有方法即可,多个接口可以组合成一个新接口:

type Drawable interface {
    Draw()
}

type Circle struct{} { // 自动满足Shape接口

func (c Circle) Perimeter() float64 {
}

func (c Circle) Area() float64 {
}

func (c Circle) Draw() { // 自动满足Drawable接口
}

// 组合
type ShapeAndDrawable interface {
    Shape
    Drawable
}

最后

接口在编程中的主要作用就是降低耦合、约束行为、提供可扩展性和可维护性。在Java显式的定义接口,增强约束性,提供清晰的接口实现结构。在Go语言中,则是通过隐式的方式实现接口,更强调行为的一致而非类型,接口和实现没有依赖关系,较为灵活。