А вот в Go интерфейсы есть, а наследования интерфейсов нет. То есть никакого вообще нет. Ни множественного ни одинарного. Кода ручками в результате приходится писать сильно меньше.
За счет чего меньше?
За счет того, что нет комбинаторного взрыва интерфейсов. Допустим у нас есть функции a, b, c. Какие-то функции хотят от типа аргумента чтобы он умел только a, а кто-то хочет только b. А кто-то и a и b одновременно. Итого получаем следующие сочетания которые могут потребоваться: a, b, c, ab, ac, bc, abc.
Если мы попробуем это дело оформить в виде интерфейсов скажем в джаве, то у нас получится что-то вот такое:
interface A {void a();}
interface B {void b();}
interface C {void c();}
interface AB extends A, B {}
interface AC extends A, C {}
interface CB extends C, B {}
interface ABC extends AC, CB, AB {}
class MyType implements ABC {
void a() {}
void b() {}
void c() {}
}
И это всего лишь три функции. Также можно добавить сюда необходимость явного разрешение имен функций в некоторых ЯП (по моему, в том же C# это нужно будет сделать, но могу ошибаться).
Причем все эти интерфейсы будут болтаться где-то около объявления типа, а не там где он непосредственно нужен. То есть предусловие на функцию будет где-то за километр от самой функции, вообще в другой либе, другом пакете и так далее. И если, не дай бог, писатель этого типа забыл скажем написать интерфейс AB, то все. Придется резко извращаться. То есть в либе у нас так:
interface A {void a();}
interface B {void b();}
interface C {void c();}
interface AC extends A, C {}
interface CB extends C, B {}
interface ABC extends AC, CB {}
class MyType implements ABC {
void a() {}
void b() {}
void c() {}
}
А нам нужно такое:
void f1(ABC x) {x.a(); x.b(); x.c();}
void f2(AB xx) {x.a(); x.b();}
void run() {
MyType t = new MyType();
f1(t);
f2(t);
}
Предется лепить враппер:
interface AB extends A, B{}
class Wrapper extends MyType implements AB {}
Но это прокатит только если мы сами создаем объекты нужного типа, если же к нам уже приезжают готовые MyType объекты, то все хуже. Придется это дело агрегировать.
interface AB extends A, B{}
class Wrapper2 implements AB, ABC {
private MyType myobj;
Wrapper2 (MyType obj){myobj = obj;}
void a() {myobj.a();}
void b() {myobj.b();}
void c() {myobj.c();}
}
Ну, понятно что у меня тут в примерах код совсем игрушечный, отформатирован не по правилам (по правилам если оформить - строчек будет раза в три-четыре больше) и вообще наверняка я тут где-то зевнул и про всякие hashCode забыл и isEquals, clone и так далее. Так что можешь смело умножать на четыре объем кода. Кода которого в Go просто не будет. За не надобностью.