This post is a small example for Go interfaces. It is destined for beginners.
In this tutorial we will implement a ProofOfId
interface that will permit to define required methods that an object must implement to be considered as a proof of id (such as your ID card, your driving license or your passport...) and a second interface CountriesList
which defines the methods required to print a list of countries.
The goal of this tutorial is to learn about how interfaces works and how it "replaces" polymorphism/inheritance in other programming languages.
Project setup
$ mkdir proof-of-identity-checker && cd proof-of-identity-checker
$ go mod init <yourname>/proof-of-identity-checker
Then open your editor in this folder.
Defining our interfaces
Create a new interfaces.go
file:
package main
import "time"
type ProofOfId interface {
getExpDate() time.Time
getName() string
getObtentionDate() time.Time
}
type CountriesList interface {
getCountries() []string
}
So, for a ProofOfId
, we except that the object has the methods getExpDate()
, getName()
and getObtentionDate()
, and for CountriesList
, we except getCountries()
method.
Functions requiring our interfaces
Now we're gonna create a new file named main.go
:
package main
import "time"
// check if a proof of id is valid (it checks only dates here ;))
func IdentityVerification(proof ProofOfId) bool {
// checking if
// `proof.getObtentionDate() < time.Now() < proof.getExpDate()`
if proof.getExpDate().After(time.Now()) &&
proof.getObtentionDate().Before(time.Now()) {
return true
} else {
return false
}
}
// display in the console the list of the visited countries
func DisplayVisitedCountries(countriesList CountriesList) {
countries := countriesList.getCountries()
println("Visited countries:")
for i := 0; i < len(countries); i++ {
println(countries[i])
}
}
For more information about date comparison: https://www.geeksforgeeks.org/how-to-compare-times-in-golang/.
Proofs of identification implementation
Identification card
Create idcard.go
:
package main
import "time"
type IdCard struct {
Name string
ObtentionDate time.Time
ExpDate time.Time
}
So our object has the required data for our ProofOfId
interface. But actually this interface defines required method so we will implement them.
// ...
func (card IdCard) getName() string {
return card.Name
}
func (card IdCard) getExpDate() time.Time {
return card.ExpDate
}
func (card IdCard) getObtentionDate() time.Time {
return card.ObtentionDate
}
Driver's license
Create driver-license.go
:
package main
import "time"
type DriverLicense struct {
Name string
ObtentionDate time.Time
ExpDate time.Time
Enterprise string
}
Please note that we will store a field Enterprise
as well (for the driving school's enterprise name).
There's the methods for DriverLicense
:
func (license DriverLicense) getName() string {
return license.Name
}
func (license DriverLicense) getExpDate() time.Time {
return license.ExpDate
}
func (license DriverLicense) getObtentionDate() time.Time {
return license.ObtentionDate
}
// this function isn't required for `ProofOfId`, but it may be useful in another context
func (license DriverLicense) getEnterprise() string {
return license.Enterprise
}
Passport
Create passport.go
:
package main
import "time"
type Passport struct {
Name string
ObtentionDate time.Time
ExpDate time.Time
VisitedCountries []string
}
As you can see, for Passport
we're going to implement our two interfaces: ProofOfId
and CountriesList
.
func (passport Passport) getName() string {
return passport.Name
}
func (passport Passport) getExpDate() time.Time {
return passport.ExpDate
}
func (passport Passport) getObtentionDate() time.Time {
return passport.ObtentionDate
}
func (passport Passport) getCountries() []string {
return passport.VisitedCountries
}
Testing
Return in main.go
and implement a main()
function:
// ...
func main() {
// vars init. You can note that some fields aren't defined.
// They will contain the default value, "" for strings, etc...)
idCard := IdCard{
// = tomorrow
ObtentionDate: time.Now().Add(24 * time.Hour),
ExpDate: time.Now().Add(24 * time.Hour),
}
driverLicense := DriverLicense{
// = yesterday
ObtentionDate: time.Now().Add(-24 * time.Hour),
ExpDate: time.Now().Add(24 * time.Hour),
}
passport := Passport{
ObtentionDate: time.Now().Add(-24 * time.Hour),
// one hour ago
ExpDate: time.Now().Add(-1 * time.Hour),
VisitedCountries: []string{
"France",
"Spain",
"Belgium",
},
}
println(IdentityVerification(idCard))
println(IdentityVerification(driverLicense))
println(IdentityVerification((passport)))
DisplayVisitedCountries(passport)
}
Now you can run go run .
in your cmd:
$ go run .
false
true
false
Visited countries:
France
Spain
Belgium
Conclusion
We saw that interfaces permits to link objects between them by specifying common methods. This is really powerful.
But you can also use interfaces in other languages, like in Typescript or Java.
If you want to learn more about how to use interfaces or inheritance/polymorphism in other languages, you can watch this video from CodeAestethic: The Flaws of Inheritance.
Top comments (0)