golang interface浅谈

themoonstone · · 2876 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

golang 的接口设计是这门编程语言的两大亮点之一,本文仅浅谈golang接口和其它语言(以C++为例)的区别。

引用《Go语言编程》作者在书中的话,go语言中的接口是“非侵入式”的,而其它语言中的接口是“侵入式”的。因此,需要对非侵入式和侵入式分别理解才能理解清楚golang 接口的优点

首先 让我们看看C++中的接口:

在C++中,接口的实现必须要通过继承

 

```cpp

interface IFoo{

    void Bar();

}



class Foo: public IFoo

{}



IFoo *Foo=new IFoo;

 

在此类语言中 即使另外有一个接口IFoo2实现了与IFoo完全一样的接口方法,甚至名字相同只不过位于不同的名字空间下,编译器也会认为上面的类Foo只实现了IFoo的接口,而没有实现IFoo2的接口

此类接口称为侵入式接口。“侵入式”的主要表现是实现类必须明确表示自己实现了某个接口。在C++里面表示为需要继承。

举一个具体的实例:

#include <iostream>

using namespace std;



class Person

{

    public:

    Person():m_strName("###"){};

    virtual void SetName(const string name)=0;

    private:

    string m_strName;

};



class Person2

{

    public:

    Person2():m_strName("###"){};

    virtual void SetName(const string name)=0;

    private:

    string m_strName;

};



class Student:public Person

{

    public:

    Student():m_strName("***"){};

    void SetName(const string name);

    private:

    string m_strName;

};



void Student::SetName(const string name){

    std::cout << m_strName << std::endl;

    m_strName=name;

    std::cout << m_strName << std::endl;

}



int main() {

    Student s;

    Person *p;

    p=&s;

    Person2 *p2;

    p2=&s;

    return 0;

}

 

在这里 因为Student没有声明继承Person2 所以 针对 p2=$s;这段代码 会出现:“cannot convert Struden* to Person2 in assignment”这样的错误。

而在GO语言中,一个类只要实现了该接口所有的函数,就代表这个类实现了该接口

type file struct{}

func(f *File) Read(buf []byte)(n int, err error)

func(f *File) Write(buf []byte)(n int, err error)

func(f *File) Seek(off int64, err eror)(pos int, err error)

func(f *File) Close() err error



type IFile interface{

    Read(buf []byte)(n int, err error)

    Write(buf []byte)(n int, err error)

    Seek(off int64, err eror)(pos int, err error)

    Close() err error

}



type IReader interface

{

Read(buf []byte)(n int, err error)

}

type IWriter interface

{

 Write(buf []byte)(n int, err error)

}

type ICloser interface

{

 Close() err error

}

 

尽管file类并没有从这些接口继承,甚至可以不知道这些接口的存在,但是file实现了这些接口的所有方法,就可以说file类实现了这些接口,可以进行赋值

其实我们可以用一个通俗的例子来进行一下说明:

对于侵入式接口,假设你在参加高考,但不是全国统考,而是高校自主命题,此时有X大学和Y大学两所学校,他们的考试题目是完全相同的,录取分数也是完全相同的,但就算你参加了X大学的考试,达到了X大学的分数线,你也不能申请就读Y大学,要想申请Y大学,你必须再次参加Y大学的考试并达到Y大学的分数线,这里的参加考试并达到分数线就相当于C++中的继承,如果没有声明继承,就不能说明实现了某个接口

而对于非侵入式接口,同样是高考,但这次是全国统考,你考过了分数线,这个时候 你既能申请X大学,又能申请Y大学,因为你达到了这两所大学所要求的统一分数,相当于你实现了X和Y两个接口里的所有方法,所以既能调用X 又能调用Y

综上,侵入式接口和非侵入式接口区别的关键在于是否需要明确声明你的类实现了某个接口。

以上仅代表个人理解,对于不对的或者不恰当的地方,欢迎批评和指正。


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2876 次点击  ∙  2 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传