Go is not a fully featured object-oriented language. Instead, it offers a subset of OOP concepts. For example, you can attach a method to any type or encapsulate data through the use of internal or public (exported) identifier.
In the following exemple, Person
has both a public and private fields and a method attached.
type Person struct {
ID string // public as it starts uppercase
name string // private
}
func (p Person) sayHello(){
fmt.Printf("Hello %s", p.name)
}
func main(){
p := Person{ID: "0", name: "John"}
p.sayHello()
}
So we’ve got both encapsulation and methods covered. One often used feature of OOP, well someone could even say it defined object for a lot of people, is the capacity to extend a class through inheritance.
What if you want to do something akin inheritance in Go ?
The main motivation to use inheritance boils down to 2 use cases:
Let’s say it quickly: reusing code is generally not a good motivation for using inheritance.
Reusability is better served with composition. In general,** you should favor composition over inheritance, **especially if it’s only for sharing code.
Let’s take a very basic example written in Java. We want to make a hash map that encrypts objects added to it. As we surely want to reuse the hashSet code of the standard library, we write the following:
class EncryptedHashSet extends HashSet {
private Object encrypt(Object o){
// do some fancy encryption
return o;
}
public boolean add(Object o) {
return super.add(encrypt(o));
}
}
It’s of course working but there are numerous drawbacks:
This example is better written using composition. Like this:
class ComposedEncryptedHashSet {
private HashSet hashSet;
private Encrypter encrypter;
public ComposedEncryptedHashSet(HashSet hs, Encrypter encrypter) {
this.hashSet = hs;
this.encrypter = encrypter;
}
private Object encrypt(Object o){
return encrypter.encrypt(o);
}
public boolean add(Object o){
return hashSet.add(o);
}
}
In this example, we:
#oop #go #golang