GO programming paradigm
Go mostly follows the procedural language paradigm and supports coding following the OOP concept, utilizing types and methods, even though Go is not a pure OOP language. Go doesn't provide a type hierarchy like pure OOP languages to create objects. Since it supports multiple programming paradigms, it is often referred to as a post-OOP or concurrent programming language.Interfaces
Go doesn’t have the concept of classes and inheritance. Instead, it uses interface types to define method signatures for common types. The 'interface' keyword is utilized to create an interface.
type interface_name interface {
// method signatures
}
To implement an interface, all methods of the interface type must be implemented in the derived type. In Go, interfaces are implemented implicitly, unlike in languages such as C# and Java.
For example, let's continue the exercise from Part 2 of this series Mastering Go: Part 2 - Structuring Your Go Projects
For example, let's continue the exercise from Part 2 of this series Mastering Go: Part 2 - Structuring Your Go Projects
Step 1. Create a new file named
formatter.go
in the string_formatter
package and add the following code:package stringformater
// formater interface to format the strings
type Formater interface {
Format() string
}
Step 2. Update the main
function and add the following code:
package main
import (
"fmt"
dateformater "learngo/date_formater" // import data formater package
stringformater "learngo/string_formater" // import string formater package
)
func main() {
fmt.Println("Import date format package!")
dateformater := dateformater.Date{Year: "2021", Month: "07", Day: "01"}
fmt.Println(dateformater.Format())
//Create an instance of an interface 'Formater'
var istringFormater stringformater.Formater
fmt.Println("Use name format package to format name!")
// Create the instance if PersonName struct and assign to string formater interface
istringFormater = &stringformater.PersonName{FirstName: "Sharad", LastName: "Subedi"}
fmt.Println(istringFormater.Format())
fmt.Println("Use name format package to format billing address!")
//create the instance if Address struct and assign to string formater interface
istringFormater = &stringformater.Address{StreetNumber: "123", StreetName: "Main St", City: "San Francisco", State: "CA", Zip: "94101"}
fmt.Println(istringFormater.Format())
}
In the above code, both the PersonName and Address structs implement all the methods defined in the Formatter interface. Since the interface type (Formatter) and the types (PersonName and Address) implement the interface in the same package (string_formatter), the interface is implicitly implemented for these types.
Additionally, Go allows the use of multiple interfaces. One interface can implement another interface as well.
Polymorphism
In Go, there is no concept of classes and objects. Instead, we utilize Go interfaces to achieve polymorphism. When we create a variable of an interface type in Go, it can hold any other types that implement the interface. This feature allows us to achieve polymorphism effectively.Step 1. Modify the main method and add the function formatString with the parameter as the interface type.
Step 2. Call the function formatString for PersonName and Address struct types.
Update the main method with the code below and observe the function formatString and its uses.
package main
import (
"fmt"
dateformater "learngo/date_formater" // import data formater package
stringformater "learngo/string_formater" // import string formater package
)
func main() {
fmt.Println("Import date format package!")
dateformater := dateformater.Date{Year: "2021", Month: "07", Day: "01"}
fmt.Println(dateformater.Format())
fmt.Println("Use name format package to format name!")
// Create the instance of PersonName struct
personName := &stringformater.PersonName{FirstName: "Sharad", LastName: "Subedi"}
fmt.Println(formatString(personName))
fmt.Println("Use name format package to format billing address!")
//create the instance of Address struct
address := &stringformater.Address{StreetNumber: "123", StreetName: "Main St", City: "San Francisco", State: "CA", Zip: "94101"}
fmt.Println(formatString(address))
}
// function to format the strings. Takes the interface type as input.
// Example to implement polymorphism using interface
func formatString(formater stringformater.Formater) string {
return formater.Format()
}
Constructor
Declare a function to do some initialization or validity check for the type. the constructor will always execute if the method from the type is accessed.
Step 1. Modify the date_formater file and add a new constructor to the struct Date. Copy the code below:
package dateformater
type Date struct {
Year string
Month string
Day string
}
func NewDate(year string, month string, day string) *Date {
return &Date{
Year: year,
Month: month,
Day: day,
}
}
func (d *Date) Format() string {
return d.Month + "/" + d.Day + "/" + d.Year
}
In the above code, the constructor simply returns an instance of the Date struct type.
Step 2. Modify the main.go file and create a new instance of the Date struct using its constructor. Copy the code below:
package main
import (
"fmt"
dateformater "learngo/date_formater" // import data formater package
stringformater "learngo/string_formater" // import string formater package
)
func main() {
fmt.Println("Crete new date struct type instance using a constructor!")
dateConstructor := dateformater.NewDate("2021", "07", "01")
fmt.Println(dateConstructor.Format())
// fmt.Println("Create the instance of Date using!")
// dateformater := dateformater.Date{Year: dateConstructor.Year, Month: dateConstructor.Month, Day: dateConstructor.Day}
// fmt.Println(dateformater.Format())
fmt.Println("Use name format package to format name!")
// Create the instance of PersonName struct
personName := &stringformater.PersonName{FirstName: "Sharad", LastName: "Subedi"}
fmt.Println(formatString(personName))
fmt.Println("Use name format package to format billing address!")
//create the instance of Address struct
address := &stringformater.Address{StreetNumber: "123", StreetName: "Main St", City: "San Francisco", State: "CA", Zip: "94101"}
fmt.Println(formatString(address))
}
// function to format the strings. Takes the interface type as input.
// Example to implement polymorphism using interface
func formatString(formater stringformater.Formater) string {
return formater.Format()
}
Reference
https://go.dev/learn/
Nice rundown of Go's paradigm flexibility.
ReplyDelete