Композиция вместо наследования: встраивание структур и интерфейсов
Наследования в Go нет вовсе, вместо него — встраивание: поле без имени, чей тип становится источником продвинутых методов и полей. type Server struct { *log.Logger } даёт Server все методы логгера так, будто они его собственные, но это не наследование, а синтаксический сахар над делегированием. Разница принципиальна и проявляется в двух местах. Во-первых, нет полиморфизма по встроенному типу: если внешний тип переопределит метод, вызовы изнутри встроенного типа продолжат вызывать его собственную реализацию — привычного из ООП переопределения не происходит. Во-вторых, продвижение методов подчиняется правилу глубины: метод с меньшей глубиной встраивания перекрывает более глубокий, а два одинаковых на одном уровне создают неоднозначность, которая проявится только при обращении. Встраивать можно и интерфейсы — это стандартный приём для частичной реализации и для расширения интерфейсов вроде io.ReadWriter.