Go 语言接口:轻量实现,灵活扩展 —— 与 Java 接口的深度对比

126 阅读2分钟

前言

golang中的接口实现,和C++、java的不一样,并不需要显式指定接口的类型去实现。而是更加简洁、轻便,修改成本更低。

Java中的接口

在 Java 里,一个类通过 implements 关键字后跟多个接口名(用逗号分隔)来实现多个接口。这使得类能够融合多个接口所定义的行为,增强类的功能。例如:

但注意,Java必须显式指定接口,并且实现接口所有的方法

interface Swimmable {
    void swim();
}

interface Flyable {
    void fly();
}

class Duck implements Swimmable, Flyable {
    @Override
    public void swim() {
        System.out.println("Duck is swimming.");
    }

    @Override
    public void fly() {
        System.out.println("Duck is flying.");
    }
}

Golang 中的接口

Golang的接口不需要显式指定,而是编译器通过判断是否实现了某个接口对应的方法,来隐式实现对应接口的功能

package main

import "fmt"

type Animal interface {
    Speak() string
}

type Dog struct {
    Name string
}

func (d Dog) Speak() string {
    return "Woof!"
}

鸭子类型——组合关系

这种实现模式,其实遵循的是Go里的鸭子类型哲学:如果一个东西看上去像鸭子,走起路来也像鸭子,那么它就是鸭子。只要一个类型的行为符合接口定义,它就被认为是该接口类型。例如上述代码中,Dog 结构体因为实现了 Animal 接口定义的 Speak 方法,所以 Dog 就是 Animal 类型。而这种实现方式,而不像其他语言的继承关系,而是组合关系。

组合关系的好处,就是将抽象和具体实现之间做了解耦,更方便了他们两者之间的扩展。

扩展性优势

但不一样的点是,在业务迭代中,随着产品构建和架构设计的迭代,接口定义往往会频繁发生修改。这时实现接口的"类"不需要强制新增对应的方法,这种特性对业务迭代显得更加友好,相比于接口继承关系,更有利于业务的扩展开发。