Golang / GoLang Interfaces and Object Oriented Interview Questions
How do you implement an abstract type pattern in Go using interfaces and constructors?
Go has no abstract class. The idiomatic equivalent is: define an interface for the contract, provide a factory function that returns the interface, and keep the concrete implementation unexported. Callers depend only on the interface β the implementation is hidden.
// database/db.go Γ’ΒΒ abstract the database driver // Exported interface Γ’ΒΒ the 'abstract type' type DB interface { Query(sql string, args ...any) (Rows, error) Exec(sql string, args ...any) (Result, error) Close() error } // Unexported concrete implementation Γ’ΒΒ callers never see this type postgresDB struct { conn *pg.Conn } func (p *postgresDB) Query(sql string, args ...any) (Rows, error) { return p.conn.Query(sql, args...) } func (p *postgresDB) Exec(sql string, args ...any) (Result, error) { return p.conn.Exec(sql, args...) } func (p *postgresDB) Close() error { return p.conn.Close() } // Exported factory Γ’ΒΒ returns the interface, hides the concrete type func NewPostgresDB(dsn string) (DB, error) { conn, err := pg.Connect(dsn) if err != nil { return nil, fmt.Errorf("NewPostgresDB: %w", err) } return &postgresDB{conn: conn}, nil } // In main/service code: db, err := database.NewPostgresDB("postgres://localhost/mydb") if err != nil { log.Fatal(err) } defer db.Close() // Caller has no knowledge of postgresDB Γ’ΒΒ depends only on DB interface // Swap the factory call to use a different DB implementation // db, _ = database.NewSQLiteDB(":memory:")
This pattern achieves the same goals as abstract class in Java: the implementation is hidden, the interface is the contract, and the factory controls creation. The advantage: the concrete type can be swapped by changing only the factory call β zero impact on the rest of the codebase.
More Related questions...