Abstract Class in Go

Abstract Class in Go

In this tutorial, we will discuss abstract class in Go language. Go language Interface doesn’t have fields, and also it doesn’t allow the definition of methods inside it.

Any type needs to implements all methods of interface to become of that interface type. There are use cases where it is useful to have a default implementation of a method and also default fields in GO. Before understanding how to do it, lets first understand the requirements of an abstract class.

  1. The abstract class should have default fields
  2. The abstract class should have the default method
  3. It should not be possible to create a direct instance of the abstract class
Abstract Class in Go

We will use a combination of an interface (abstract interface) and struct (abstract concrete type). Together they can provide the functionalities of an abstract class. See the below program.

package main

import "fmt"

//Abstract Interface
type iAlpha interface {
	work()
	common()
}

//Abstract Concrete Type
type alpha struct {
	name string
}

func (a *alpha) common() {
	fmt.Println("Common method called")
}

//Implementing Type
type beta struct {
	alpha
}

func (b *beta) work() {
	fmt.Println("Work method called")
	fmt.Printf("Name is %s\n", b.name)
	b.common()
}

func main() {
	a := alpha{
		name: "Abstract Class Test",
	}
	b := &beta{
		alpha: a,
	}
	b.work()
}

Output

Work method called
Name is Abstract Class Test
Common method called

Run in playground

In the above program:

  • We created an abstract interface iAlpha, an abstract concrete struct alpha, and an implementer struct beta
  • alpha struct is embedded in a beta struct
  • The beta struct can access the default field “name”
  • The beta struct can access the default method “common”
  • It cannot create a direct instance of iAlpha as the alpha struct only implements only one of the method of iAlpha.

So it fulfills all three requirements, but there is also one limitation of the above method. It is impossible to call the “work” method from the “common” alpha method. Basically, there is no way to call an undefined method of the abstract interface from the default methods of an abstract concrete type. There is one way to fix it, though. See below program

package main

import "fmt"

//Abstract Interface
type iAlpha interface {
	work()
	common()
}

//Abstract Concrete Type
type alpha struct {
	name string
	work func()
}

func (a *alpha) common() {
	fmt.Println("Common method called")
	a.work()
}

//Implementing Type
type beta struct {
	alpha
}

func (b *beta) work() {
	fmt.Println("Work method called")
	fmt.Println("Name is : ", b.name)
}

func main() {
	a := alpha{
		name: "Abstract Class Test",
	}
	b := &beta{
		alpha: a,
	}
	b.alpha.work = b.work
	b.common()
}

Output

Common method called
Work method called
Name is :  Abstract Class Test

Run in playground

In the above program:

  • We created a new field “work” of type func in alpha
  • We assigned alpha’s “work” method to the beta “work” method

The only problem with the above program is that it is possible to create a direct instantiation of alpha struct, and by providing the definition of work method, an instance of type iAlpha is created. This violates point 3 of the above Abstract class requirement as without creating our own new type, we can create a type of iAlpha. Let’s try to fix this problem. The below program also solves the problem where it was impossible to call the undefined methods from default methods.

package main

import "fmt"

//Abstract Interface
type iAlpha interface {
	work()
	common(iAlpha)
}

//Abstract Concrete Type
type alpha struct {
	name string
}

func (a *alpha) common(i iAlpha) {
	fmt.Println("Common method called")
	i.work()
}

//Implementing Type
type beta struct {
	alpha
}

func (b *beta) work() {
	fmt.Println("Work method called")
	fmt.Println("Name is : ", b.name)
}

func main() {
	a := alpha{
		name: "Abstract Class Test",
	}
	b := &beta{
		alpha: a,
	}
	b.common(b)
}

Output

Common method called
Work method called
Name is :  Abstract Class Test

Run in playground

In the above program, all the default methods will accept the first argument of interface type iAlpha. All the undefined methods of the alpha struct will be called using this argument from default methods.

Abstract Class in Go
Scroll to top