I really like Golang's choice to not offer inheritance, but instead an alternative: embedding. Which is really just composition, but where 1. the child is named implicitly after its type, and 2. its methods and members are automatically promoted to visibility in the "namespace" of the parent (but still "live in" the child.)
So, if you've got Go code like this:
type B struct {
int c
}
type A struct {
B
}
...then if you type `anA.c`, it's basically the same as if you had written `anA.B.c`. It's just sugar.
And, as with inheritance, members+methods defined explicitly on the parent (A) shadow the ones from the child (B), when you're accessing them on the parent. So you can do something that looks a lot like "subclass method overriding" on the child. (Though it isn't, quite, because the embedded child's methods, once reached, will only call each-other, oblivious to the parent. In C++ terms, there are no "virtual" methods.)
This is more often used for decoration or aggregation (e.g. Go's bufio.ReadWriter, which is just a struct embedding a bufio.Reader and a bufio.Writer), but it can be used to simulate inheritance pretty well, with almost none of the disadvantages that come from having inheritance built into your type system.
(For example, there's no need for the Liskov Substitution Principle in Golang, since you can't pass an embedding "subclass" (A) instance into a method parameter that wants the "base class" type (B). If you want that behavior, you opt into it explicitly by defining the method parameter as being of an interface type, where the interface is one that B implements; then, anything that embeds B will—unless it shadowed B's methods with methods of different signatures—also meet that interface.)